版本更新需要注意的点
- 兼容Android7.0
最近我们发现Android7.0的手机更新App的时候会出android.os.FileUriExposedException这个异常,出现这个异常是因为7.0的系统更改了文件系统访问权限。这无疑对我们开发者增加了麻烦~~~,若要在应用间共享文件,需要发送content://格式的URI,并授予 URI 临时访问权限。而进行此授权的最简单方式是使用 FileProvider类。下面就这个问题我们对Android更新apk进行一下整理。
- 兼容Android8.0
因为8.0添加了新的安全措施,不允许应用内安装未经过Google play验证的应用,所以添加下面这个权限即可解决问题。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
一、权限申请
首先我们在AndroidManifest.xml文件中注册我们的基本的权限。
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在这里我使用的大神封装好的一套权限申请方案(https://github.com/yanzhenjie/AndPermission),这里就不多做权限申请的说明了,权限申请成功我们判断应用版本。
int currentVerCode = Utils.getCurrentVerCode();
if (2 > currentVerCode) {
Intent intent = new Intent(this, UpdateService.class);
intent.putExtra("apkUrl", "http://app.mi.com/download/63785");//调用下载apk的服务,传入下载地址
startService(intent);
}
二、Android7.0更新Apk注意事项
- 1.AndroidManifest.xml中注册
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="你的包名.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!-- 元数据 -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
- 2.在res目录下新建一个名为xml的文件夹,并且新建一个名为file_paths.xml的文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path path="Android/data/你的包名/" name="files_root" />
<external-path path="." name="external_storage_root" />
</paths>
</resources>
- 3.安装app进行版本判断
//拿到apk文件
File apkFile = new File(getDownloadPathName());
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 24) { //判读版本是否在7.0以上
//参数1 上下文, 参数2 Provider主机地址 和配置文件中保持一致 参数3 共享的文件
Uri apkUri = FileProvider.getUriForFile(UpdateService.this, PACKAGE_NAME + ".fileprovider", apkFile);
//添加这一句表示对目标应用临时授权该Uri所代表的文件
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
}
startActivity(intent);