Android App内部更新(最新) 各安卓版本适配
Android 内部更新 各安卓版本适配
一:前言
在国内,app在线更新是一个必须要求。新版本发布时。用户进入我们的app,就会弹出更新提示框;
二:开发
在线更新分为以下几个步骤:
1:通过接口获取线上版本号 versionCode;
2: 比较线上的versionCode 和当前的versionCode ,弹出更新窗口;
3:下载apk文件(其实就是文件下载);
4:安装apk文件;
end
1、2 步骤很简单 ;
3、4因为 Andriod各个版本权限和隐私的保护和收缩,因此3和4会有各种适配问题,那么今天就总结下app在线更新的适配处理。
二: apk下载
apk下载其实就是我们正常的文件下载。而文件下载有很多方式:
1:借助框架(okhttp等)
2:可以通过Android sdk 提供的下载类 DownloadManager。配置下配置就好;
备注:我自己项目用的是okhttp3;
下载apk:
下载过程中如果需要提示通知就记录进度;
下载好之后拷贝到沙盒存储里;
重头戏来了就是安装:(需要适配)
我这里主要以7.0 为中间界限 (用谷歌DownloadManager的要区分6.0以上和一下,获取到的uri会不一致 ,具体可参考:
https://www.cnblogs.com/gooder2-android/p/8966045.html)
安装的一些重要api:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(intent);
我们看到 uri。此uri地址根据不同Android 版本进行不同处理拿到;
适配Android7.0 :访问文件做出了修改
在 Android 7.0 手机(访问文件做出了修改)
主要是:不能在使用file://格式的Uri 访问文件。Android 7.0对应提供了FileProvider 来获取apk地址,然后安装apk.
代码处理:
(1) 在res 目录下,新建一个xml
文件夹,在xml
下面创建一个文件provider_paths
文件:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="" />
<external-files-path
name="Download"
path="" />
</paths>
或:
我自己代码处理是:
<resources>
<paths>
<root-path
path=""
name="camera_photos" />
</paths>
</resources>
<!--
1、代表的根目录:Context.getFilesDir()
2、代表的根目录:Context.getExternalFilesDir()
3、代表的根目录:getCacheDir()
4、上述代码中path="",是有特殊意义的,它代码根目录,也就是说你可以向其它的应用
共享根目录及其子目录下任何一个文件了,如果你将path设为path=“pictures”,那么它
代表着根目录下的pictures目录(eg:/storage/emulated/0/pictures),如果你向其它应用
分享pictures目录范围之外的文件是不行的。
-->
(2) 在AndroidManifest.xml清单文件中申明Provider:
<provider
//Androidx是: android:name="androidx.core.content.FileProvider"
//support库是android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!--
1.android:exported:要求必须为false,为true则会报安全异常;
2.android:grantUriPermissions:true,表示授予 URI 临时访问权限;
3.android:authorities这个属性的值,建议写包名+fileprovider,当然也可以起别的字符串,
但是在设备中不能出现2个及以上的APP使用到同一个authorities属性值,因为无法共存。
-->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
(3) Android 7.0上的文件地址获取:
//apkFile 是已经生成的文件
uri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".fileprovider", apkFile);
适配Android 8.0:未知来源的应用权限
如果不适配有什么体验问题:
具体表现就是:apk下载完成,一闪而过,没有跳转到apk安装界面。经过排查,确定了是Android 8.0权限问题。
谷歌理由:Android8.0以上,未知来源的应用是不可以通过代码来执行安装的(在sd卡中找找到apk,手动安装是可以的),未知应用安装权限的开关被除掉,取而代之的是未知来源应用的管理列表,需要列表里面开启你的应用的未知来源的安装权限。Google这么做是为了防止一开始正经的应用后来开始通过升级来做一些不合法的事情,侵犯用户权益。
知道问题:开始适配:
1) 在清单文件中申明权限:REQUEST_INSTALL_PACKAGES
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
2)加flag:
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
亲测可以,搞定 搞定;
整体安装代码:
private void installApk(File apkFile) {
if (!apkFile.exists())
return;
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//7.0
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
uri = FileProvider.getUriForFile(getApplicationContext(), BuildConfig.APPLICATION_ID + ".fileprovider", apkFile);
} else {
uri = Uri.fromFile(apkFile);
}
intent.setDataAndType(uri, "application/vnd.android.package-archive");
startActivity(intent);
}
本文地址:https://blog.csdn.net/qq_34970020/article/details/110238750