安卓7.0 ,8.0手机上遇到的app升级问题终极解决方案
兼容Android 7.0 及8.0 App升级
Android7.0变化点:
出于安全机制的考虑,从安卓7.0开始获取uri的方式改为
Uri apkUri = FileProvider.getUriForFile(mContext, getPackageName() + ".fileprovider", appFile);
Android7.0之前的版本获取uri还是之前的方式
Uri apkUri = Uri.fromFile(appFile)
Android8.0变化点:
安卓8.0设置页面新增了 允许安装未知来源app 按钮,app在进行升级安装的时候需要先判断此开关是否已经打开了,如果没打开,需要跳转到设置页面进行打开,之后返回继续进行app升级安装。
一、在AndroidManifest.xml清单文件中注册Provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.cuileikun.androidbase.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/cui_file_paths"
tools:replace="android:resource"/>
</provider>
authorities: 常用命名为包名+fileprovider
exported要求必须为false,为true会报安全异常
grantUriPermissions表示URI临时访问权限,true为需要临时访问权限
resource指当前组件引用res文件夹中qk_file_paths文件,这个文件名可以随便写,只要在res文件夹中有这个文件即可。
在res文件夹中新建xml文件夹,再新建cui_file_paths.xml文件,内容如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="files_root"
path="Android/data/com.cuileikun.androidbase/" />
<external-path
name="external_storage_root"
path="." />
<!-- yan notice: do not edit -->
<root-path path="" name="camera_photos" />
</paths>
</resources>
path填上Android/data/包名
二、安装Apk时注意兼容高低版本
/**
* 安装新版本应用
*/
private void installApp() {
File appFile = new File(FILE_NAME);
if (!appFile.exists()) {
return;
}
// 跳转到新版本应用安装页面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 24) { //判断是否是AndroidN (安卓7.0)以及更高的版本
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致 参数3 共享的文件
Uri apkUri = FileProvider.getUriForFile(mContext, getPackageName() + ".fileprovider", appFile);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
//兼容8.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = mContext.getPackageManager().canRequestPackageInstalls();
if (!hasInstallPermission) {
startInstallPermissionSettingActivity();
return;
}
}
} else {
intent.setDataAndType(Uri.fromFile(appFile), "application/vnd.android.package-archive");
}
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
/**
* 跳转到设置-允许安装未知来源-页面
*/
@RequiresApi(api = Build.VERSION_CODES.O)
private void startInstallPermissionSettingActivity() {
Uri packageUri = Uri.parse("package:" + getPackageName());
//注意这个是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageUri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivityForResult(intent, 10086);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 10086) {
installApp();
}
}
主要是注意getUriForFile方法中的参数,第二个参数为BuildConfig.APPLICATION_ID + “.fileprovider”
即包名+.fileprovider,这个和AndroidManifest中的Provider中的属性authorities一致
参考链接:
http://www.2cto/kf/201704/622561.html
安卓7.0 ,8.0手机上遇到的app升级问题终极解决方案
兼容Android 7.0 及8.0 App升级
Android7.0变化点:
出于安全机制的考虑,从安卓7.0开始获取uri的方式改为
Uri apkUri = FileProvider.getUriForFile(mContext, getPackageName() + ".fileprovider", appFile);
Android7.0之前的版本获取uri还是之前的方式
Uri apkUri = Uri.fromFile(appFile)
Android8.0变化点:
安卓8.0设置页面新增了 允许安装未知来源app 按钮,app在进行升级安装的时候需要先判断此开关是否已经打开了,如果没打开,需要跳转到设置页面进行打开,之后返回继续进行app升级安装。
一、在AndroidManifest.xml清单文件中注册Provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.cuileikun.androidbase.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/cui_file_paths"
tools:replace="android:resource"/>
</provider>
authorities: 常用命名为包名+fileprovider
exported要求必须为false,为true会报安全异常
grantUriPermissions表示URI临时访问权限,true为需要临时访问权限
resource指当前组件引用res文件夹中qk_file_paths文件,这个文件名可以随便写,只要在res文件夹中有这个文件即可。
在res文件夹中新建xml文件夹,再新建cui_file_paths.xml文件,内容如下
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="files_root"
path="Android/data/com.cuileikun.androidbase/" />
<external-path
name="external_storage_root"
path="." />
<!-- yan notice: do not edit -->
<root-path path="" name="camera_photos" />
</paths>
</resources>
path填上Android/data/包名
二、安装Apk时注意兼容高低版本
/**
* 安装新版本应用
*/
private void installApp() {
File appFile = new File(FILE_NAME);
if (!appFile.exists()) {
return;
}
// 跳转到新版本应用安装页面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 24) { //判断是否是AndroidN (安卓7.0)以及更高的版本
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致 参数3 共享的文件
Uri apkUri = FileProvider.getUriForFile(mContext, getPackageName() + ".fileprovider", appFile);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
//兼容8.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean hasInstallPermission = mContext.getPackageManager().canRequestPackageInstalls();
if (!hasInstallPermission) {
startInstallPermissionSettingActivity();
return;
}
}
} else {
intent.setDataAndType(Uri.fromFile(appFile), "application/vnd.android.package-archive");
}
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
/**
* 跳转到设置-允许安装未知来源-页面
*/
@RequiresApi(api = Build.VERSION_CODES.O)
private void startInstallPermissionSettingActivity() {
Uri packageUri = Uri.parse("package:" + getPackageName());
//注意这个是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageUri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivityForResult(intent, 10086);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 10086) {
installApp();
}
}
主要是注意getUriForFile方法中的参数,第二个参数为BuildConfig.APPLICATION_ID + “.fileprovider”
即包名+.fileprovider,这个和AndroidManifest中的Provider中的属性authorities一致
参考链接:
http://www.2cto/kf/201704/622561.html