主体实现步骤如下:
1.接口检测是否有更新,如果有更新,则dialog提示。
2.当用户点击确认更新时,先判断是否开启WRITE_EXTERNAL_STORAGE权限。(适配Android 6.0)
3.如果读权限开启,则请求下载并弹窗显示下载进度。
4.在下载成功完成的回调中检测用户系统版本是否为android 8.0及以上,不是的话直接执行安装方法。
5.如果是android 8.0及以上则检测未知来源应用安装权限是否开启,如果开启则直接执行安装方法。
6.没有开启的话,则请求未知来源应用安装权限,然后用户就会被动跳转到权限授权开启页面并开启。
7.然后在onActivityResult()方法中判断如果用户没开启则提示安装失败,安装权限为授权。如果开启授权,则执行安装方法。
注意适配7.0的FileProvider:
<!-- 适配7.0之后安装apk问题-->
<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/file_paths" />
</provider>
代码如下:
//1.接口检测是否有更新
private void checkUpdate() {
//自己实现网络请求是否有更新
}
//2.有更新时,则弹窗提示用户是否更新
private void showUpdateDialog(){
//自己实现弹窗提示
}
//3.检测6.0及以上时写入权限是否开启
private void checkAndroidM(){
//检测是否为6.0及以上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int i = ContextCompat.checkSelfPermission(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE});
if (i != PackageManager.PERMISSION_GRANTED) {
// 提示用户该请求权限的弹出框
showDialogTipUserRequestPermission();
return;
}
}
}
//4.写入权限开启后,显示下载进度
prvate void showProgressDialog(){
//自己实现下载进度提示框
}
//5.并开始下载apk文件
private void downloadApk(){
//自己实现下载文件请求
}
//6.在下载成功回调时,检测8.0及以上
/**
* 检测是否为Android 8
* Build.VERSION_CODES.O
*/
private void checkIsAndroidO() {
if (Build.VERSION.SDK_INT >= 26) {
boolean b = getPackageManager().canRequestPackageInstalls();
if (b) {
installApk(apkfile);
} else {
//请求安装未知应用来源的权限
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 456);
}
} else {
installApk(apkfile);
}
}
//7.在请求安装未知应用来源的权限后
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 456) {
Uri packageURI = Uri.parse("package:" + getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
startActivityForResult(intent,457);
}
}
//8.在 startActivityForResult(intent,457);执行后
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==457){
if (Build.VERSION.SDK_INT >= 26) {
if(getPackageManager().canRequestPackageInstalls()){
installApk(apkfile);
}else{
Utils.showFailureToast("安装权限未开通,安装失败!");
}
}
}
}
//9.安装apk,适配android 7.0
private void installApk(File file) {
if (Build.VERSION.SDK_INT >= 24) {//判读版本是否在7.0以上
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
boolean haveInstallPermission = getPackageManager().canRequestPackageInstalls();
if (!haveInstallPermission) {
Uri packageURI = Uri.parse("package:" + getPackageName());
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
startActivityForResult(intent, 457);
} else {
Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", file);
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(install);
}
} else {
Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".fileprovider", file);
Intent install = new Intent(Intent.ACTION_VIEW);
install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
install.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(install);
}
} else {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(install);
}
}
网友评论