如果你的应用包含自动更新版本的功能,那么这篇文章可能对你有些参考价值。大多数情况下,应用内自动升级实现方式通常为:
- 下载apk文件
- wifi下自动下载或用户手动下载
- 引导用户安装更新包
- 弹出自动升级弹窗
- 弹出自动升级notification
- 在其他位置预留版本升级入口
近期安卓系统升级针对安装应用接口变动较大,如Android N 禁止通过file:// URI安装应用,Android O 增加应用安装权限申请。下述方法经测试可较好适配Android 4/5/6/7/8/9/Q 系统。
准备工作
- AndroidManifest文件中配置:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="packageName.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
- res/xml路径下增加文件filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<paths>
<external-path
name="external_path"
path="." />
</paths>
<paths>
<external-files-path
name="external_files_path"
path="." />
</paths>
</resources>
手动安装
public static void installApk(File apkFile) {
try {
Uri apkUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
apkUri = FileProvider.getUriForFile(context, packageName + ".fileprovider", apkFile);
Intent installIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
installIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
installIntent.setData(apkUri);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
boolean hasInstallPermission = context.getPackageManager().canRequestPackageInstalls();
if (!hasInstallPermission) {
ToastUtil.shortShow("请开启应用安装权限");
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
context.startActivity(installIntent);
}
} else {
context.startActivity(installIntent);
}
} else {
apkUri = Uri.fromFile(apkFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
context.startActivity(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
通知点击安装
/**
* 自动升级安装时弹出notification
*/
public static void showInstallNotification(File apkFile) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri fileUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
fileUri = FileProvider.getUriForFile(context, packageName + ".fileprovider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
fileUri = Uri.fromFile(apkFile);
}
intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
showNotification(INSTALL_NOTIFICATION_ID, "点击安装新版本", parsePendingIntent(intent));
} catch (Exception e) {
e.printStackTrace();
}
}