android - 使用 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 到底在做什么。
解决方案
推荐阅读
- list - 为什么我不能将一个列表插入到我的另一个列表中?
- javascript - VueJS 递归 API 调用良好实践
- angular - 使用 TS 的 Angular 禁用 href
- python - 规则定义中“线程”通配符的算术
- javascript - 为什么 Axios get call 使用基本设置返回 404 错误?
- mybatis - 在 mybatis 中遍历字符串
- android - 通过意图调用后如何清理和关闭应用程序
- mysql - 声明变量并连接选择的所有值
- python - Tkinter:列表框的更新频率
- compiler-construction - 自动机在编译器构造中的作用