今天在開發過程中遇到了一個問題,在apk更新下載後執行安裝時,程序沒有反應,如下:
/*
* 下載到本地後執行安裝
*/
protected void installAPK() {
File apkFile = new File(mUpgradePath, "abc.apk");
if (!apkFile.exists()) {
return;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uridata;
// 判斷版本大於等於7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// "xxxx.fileProvider"即是在清單文件中配置的authorities
uridata = FileProvider.getUriForFile(getApplicationContext(), "xxxx.fileProvider", apkFile);
// 給目標應用一個臨時授權
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uridata = Uri.fromFile(apkFile);
}
intent.setDataAndType(uridata, "application/vnd.android.package-archive");
this.startActivity(intent);
}
但是執行以上代碼後卻沒有出現安裝界面,後來發現我的手機是8.0的系統 api26,
找到原因:Android8.0的諸多新特性中有一個非常重要的特性:未知來源應用權限。
以前安裝未知來源應用的時候一般會彈出一個彈窗讓用戶去設置允許還是拒絕,並且設置爲允許之後,所有的未知來源的應用都可以被安裝。Android8.0的變化是,未知應用安裝權限的開關被除掉,取而代之的是未知來源應用的管理列表,需要在裏面打開每個應用的未知來源的安裝權限。Google這麼做是爲了防止一開始正經的應用後來開始通過升級來做一些不合法的事情,侵犯用戶權益。 當你的應用直接適配到Android8之後,內部啓動應用安裝是會被阻塞的,如果不處理好這個未知來源的權限,會導致應用根本無法更新,只能去應用市場重新下載。
解決方法:
先加個權限:<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
注意這個不是運行時權限,不能代碼申請啊。
然後安裝前檢查一下
//安裝前檢測權限,安裝android8.0 需要權限
public void installBefore() {
boolean haveInstallPermission;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//先獲取是否有安裝未知來源應用的權限
haveInstallPermission = MySettingsActivity.this.getPackageManager().canRequestPackageInstalls();
if (!haveInstallPermission) {//沒有權限
new AlertDialog.Builder(MySettingsActivity.this)
.setTitle("提示")
.setMessage("安裝應用需要打開未知來源權限,請去設置中開啓權限")
.setNegativeButton("退出", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
ToastUtils.showCommanToast(MySettingsActivity.this, "沒有安裝權限,安裝失敗。");
System.exit(0);
}
})
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Uri packageURI = Uri.parse("package:" + JarvisApp.getContext().getPackageName());
//注意這個是8.0新API
Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
MySettingsActivity.this.startActivityForResult(intent, 2);
dialog.cancel();
}
}
}).show()
.setCanceledOnTouchOutside(false);
}
}
installAPK();
}
權限申請完之後在 onActivityResult 裏面判斷下就好,resultCode == RESULT_OK那就是給權限了,直接安裝吧。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_OK) {
installAPK();
}
}
以上問題解決~