Android安装带有Intent.VIEW_ACTION的APK不适用于文件提供程序 [英] Android install apk with Intent.VIEW_ACTION not working with File provider

查看:142
本文介绍了Android安装带有Intent.VIEW_ACTION的APK不适用于文件提供程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序具有自动更新功能,可以下载APK,下载完成后会显示一个Intent.VIEW_ACTION,可以打开应用程序并让用户安装下载的APK.

My app has an auto-update feature that download an APK and when the download is finished that a Intent.VIEW_ACTION to open the app and let the user install the downloaded apk

         Uri uri = Uri.parse("file://" + destination);
         Intent install = new Intent(Intent.ACTION_VIEW);
        install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        install.setDataAndType(uri,
            manager.getMimeTypeForDownloadedFile(downloadId));
        activity.startActivity(install);

这适用于所有设备< 24

This works great for all the device < 24

现在,在Android 24上,显然我们不再被允许使用file:///来启动意图.在进行了一次谷歌搜索之后,建议使用A File Provider

Now with Android 24 apparently we are not allowed any more to start intents with file:/// and after some googling it was advised to use A File Provider

新代码:

Intent install = new Intent(Intent.ACTION_VIEW);
    install.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Uri apkUri = FileProvider.getUriForFile(AutoUpdate.this,
        BuildConfig.APPLICATION_ID + ".provider", file);
    install.setDataAndType(apkUri,
        manager.getMimeTypeForDownloadedFile(downloadId));
    activity.startActivity(install);

现在activity.startActivity(install);引发错误

Now activity.startActivity(install); throws an error

未找到用于处理Intent的活动{act = android.intent.action.VIEW dat = content://com.xxxx.xx.provider/MyFolder/Download/MyApkFile.apk typ = application/vnd.android.package-archive flg = 0x4000000}

No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://com.xxxx.xx.provider/MyFolder/Download/MyApkFile.apk typ=application/vnd.android.package-archive flg=0x4000000 }

有什么方法可以在Android 7(24)中打开APK查看器吗?

Is there any way I can open the APK viewer in Android 7 (24) ?

推荐答案

经过大量尝试,我能够通过为低于Nougat的任何内容创建不同的Intent来解决此问题,例如使用FileProvider在Android版本中创建安装Intent.在牛轧糖导致错误之前:

After a lot of trying I have been able to solve this by creating different Intents for anything lower than Nougat as using the FileProvider to create an install intent with Android Versions before Nougat causes the error:

ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSTALL_PACKAGE dat=content://XXX.apk flg=0x1 }

在Android Nougat上使用普通Uri时,会产生以下错误:

While using a normal Uri on Android Nougat creates the following error:

FileUriExposedException: file:///XXX.apk exposed beyond app through Intent.getData()

适用于我的解决方案,可以在模拟器上使用Android N并运行Android M的手机.

My solution which is working for me with Android N on the emulator and a phone running Android M.

File toInstall = new File(appDirectory, appName + ".apk");
Intent intent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    Uri apkUri = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".fileprovider", toInstall);
    intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
    intent.setData(apkUri);
    intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
    Uri apkUri = Uri.fromFile(toInstall);
    intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
activity.startActivity(intent);

Android Nougat 7.1的更新:

您还需要在清单中添加权限REQUEST_INSTALL_PACKAGES.它可以从Api级别23(Android 6.0棉花糖)获取,而从级别25(Android 7.1牛轧糖)需要.

You also need to add the permission REQUEST_INSTALL_PACKAGES in your manifest. Its available from Api Level 23 (Android 6.0 Marshmallow) and required from Level 25 (Android 7.1 Nougat).

更新:

请记住,如果您尝试安装的文件在外部存储器上,请请求读取和写入外部存储器的权限.并为Android Nougat及更高版本设置正确的FileProvider.

Remember to request the permissions for read and write to external storage if the file you try to install is on the external storage. And also to set up a correct FileProvider for Android Nougat and above.

首先通过下面的canReadWriteExternal()来检查您是否具有写权限,如果之前没有调用requestPermission(),则:

First check if you have write permission by calling canReadWriteExternal() below, if not call requestPermission() before:

private static final int REQUEST_WRITE_PERMISSION = 786;

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == REQUEST_WRITE_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED)
        Toast.makeText(this, "Permission granted", Toast.LENGTH_LONG).show();
}

private void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
        requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}

private boolean canReadWriteExternal() {
    return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED;
}

以下是外部存储器上下载"文件夹的文件提供程序示例. AndroidManifest.xml :

Here is an example of a file provider for the Download folder on the external storage. AndroidManifest.xml:

<application ... >
    ...

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/filepaths" />
    </provider>
</application>

resources/xml/filepaths.xml :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_download" path="Download"/>
</paths>

如果在安装.apk时出错,则显示类似解析软件包时出现问题"之类的信息.可能是您没有要求读/写权限,或者您尝试安装的文件不存在或已损坏.

If you get an error while installing the .apk saying something like "There is a problem parsing the package." it could be that you haven't asked for the read/write permission or the file you try to install doesn't exist or is corrupt.

这篇关于Android安装带有Intent.VIEW_ACTION的APK不适用于文件提供程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆