首页 > 解决方案 > 使用 Download Manager + FileProvider 打开 APK 以更新应用

问题描述

我们有一个通过我们分发的 APK 安装的企业应用程序(不是 Play 商店)。在那个应用程序中是一个自动更新程序,在 SDK 29 之前运行良好。我一直在尝试更新我们的代码以使用新的方法来下载并使用下载的 APK 启动新意图,但它是一个令人沮丧的重击-a -痣经验。

我目前的状态是我可以下载该文件并且可以看到它存在,但是如果我尝试使用它启动一个意图,我会收到有关该文件不可访问的错误,因为它是一个外部文件。后来进行了很多谷歌搜索,我需要实现文件提供程序,我已经完成了,但是文件下载位置和我传递给意图的路径不匹配。

基本上,我真的很困惑 FileProvider 以及我应该如何使用它来获取下载的文件路径并让 Android 打开 APK 进行安装。提示用户安装很好,这就是它一直为我们工作的方式,我们并不是试图进行“静默”安装。我只是想让它工作。

精简相关代码:

private void downloadUpdate(Uri uri) {
final String filename = File.separator + uri.getLastPathSegment();

DownloadManager downloadmanager = (DownloadManager) parent.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.setDescription("Downloading");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalFilesDir(getContext(), Environment.DIRECTORY_DOWNLOADS, filename);

try {
    onDownloadComplete = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            if (downloadId == id) {
                Toast.makeText(parent, "Download Completed", Toast.LENGTH_SHORT).show();
                try {
                    Intent installIntent = new Intent(Intent.ACTION_VIEW);
                    String filepath = getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + filename;
                    File update = new File(filepath);

                    Uri updateUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", update);

                    installIntent.setDataAndType(updateUri, "application/vnd.android.package-archive");
                    installIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    startActivity(installIntent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    };
    parent.registerReceiver(onDownloadComplete,new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    downloadId = downloadmanager.enqueue(request);

} catch (Exception ex) {
    Log.e("UpdateDownload", "Update Error: " + ex.getMessage());
    new ErrorLog(new Date(), "Error downloading update: " + ex.getMessage());
}
}

我在清单中的提供者定义:

<provider
android:name="androidx.core.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>

我的文件路径 xml:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="pictures" path="Pictures" />
    <external-files-path name="Download" path="Download/" />
</paths>

一切都下载得很好,我一直到 startActivity 行,但随后我收到一个错误,android 无法解析包 - 因为它实际上并没有查看正确的文件路径。在调试模式下,如果我执行 update.exists(),我得到一个 true,因此文件正在下载,但更新文件路径不等于为 updateUri 找到的路径。

如何让 fileprovider 为意图提供正确的文件路径?我假设我的 XML 配置错误,但我不明白 FileProvider 到底在做什么。

标签: androidandroid-fileprovider

解决方案


推荐阅读