气抖冷!气抖冷! 都2050年了,还在这上面折腾一天,羞愧致死....
一、问题表现
应用内更新,apk下载完成后未自动弹出安装界面(或弹出去后闪退);我们之前下载Apk用的是DownloadManager,这次之后就完全不用了,因为应用退到后台后(在Receiver里面)启动Activity现在是不被允许的
二、填坑
- 7.0后文件分享需要加FileProvider,这里不展开讲了,主要是要注意下Flag问题: FileProvider需要添加Intent.FLAG_GRANT_READ_URI_PERMISSION,从非Activity启动需要Intent.FLAG_ACTIVITY_NEW_TASK,直接
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK)
- 申请 REQUEST_INSTALL_PACKAGES 权限,搜资料的时候有老外说需要动态申请权限,即用ActivityCompat.requestPermissions。我用我的小米手机(MIUI12)测试发现不可以,表现为没有权限弹窗直接被系统拒绝。所以目前只有用以下的方式申请权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = activity.getPackageManager().canRequestPackageInstalls();
if (!hasInstallPermission) {
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + activity.getPackageName()));
activity.startActivityForResult(intent, CODE_REQUEST);
}
}
注意:需要对应的Activity onActivityResult里面处理是否已授权
- App退到后台后,Receiver收到下载完成广播后无法唤起安装。完全理解,所以DownloadManger+Receiver的形式处理应用升级,在这种情况下容易出问题,不建议使用
三、最终代码(片段)
1.AndroidManifest增加权限申请
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
2.下载Apk前,先判断权限,若无需要申请 REQUEST_INSTALL_PACKAGES
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = activity.getPackageManager().canRequestPackageInstalls();
if (!hasInstallPermission) {
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, Uri.parse("package:" + activity.getPackageName()));
activity.startActivityForResult(intent, CODE_REQUEST);
}
}
- 下载完成后唤起安装
private void install(Context context, File file) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//兼容7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
//这里牵涉到7.0系统中URI读取的变更
Uri contentUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", file);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
}
if (context.getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
//如果是Activity,可以startActivityForResult
context.startActivity(intent);
}
} catch (Throwable e) {
e.printStackTrace();
}
}








网友评论