最近接收一個(gè)老項(xiàng)目马澈,發(fā)現(xiàn)在Android Q版本上自動(dòng)更新的時(shí)候出錯(cuò)崩泡,表現(xiàn)為下載完app后直接崩潰迈螟。進(jìn)入文件管理器后發(fā)現(xiàn)安裝包已經(jīng)下載成功了叉抡,點(diǎn)擊安裝后能正常安裝,但這是文件管理器調(diào)用系統(tǒng)的安裝答毫,項(xiàng)目中調(diào)用系統(tǒng)安裝肯定是有問題的褥民。
查看gradle文件
android {
compileSdkVersion 23
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.*****.*****"
minSdkVersion 14
targetSdkVersion 23
versionCode 2
versionName "2.4.2"
multiDexEnabled true
ndk {
//選擇要添加的對(duì)應(yīng)cpu類型的.so庫
abiFilters "armeabi", "armeabi-v7a"
// 'armeabi-v8a', 'x86', 'x86_64', 'mips', 'mips64'
}
}
}
編譯版本和目標(biāo)版本都是23,項(xiàng)目中提示要更新到29洗搂。因?yàn)閷?duì)29新特性不是特別了解消返,不敢貿(mào)然升級(jí)。
再看看Manifest文件耘拇,權(quán)限有很多撵颊,這里就不貼了。查了下網(wǎng)上對(duì)安裝apk的權(quán)限惫叛,更新app以及安裝app需要的權(quán)限如下
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REPLACE_EXISTING_PACKAGE"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/><!-- 8.0必要權(quán)限 -->
項(xiàng)目中的權(quán)限列表中沒發(fā)現(xiàn)REPLACE_EXISTING_PACKAGE和REQUEST_INSTALL_PACKAGES這兩項(xiàng)權(quán)限倡勇,猜想是再其他的引用中加入了這些權(quán)限。因?yàn)樵贏ndroidQ以下的手機(jī)能安裝成功嘉涌。
再往下看發(fā)現(xiàn)一個(gè)問題妻熊,manifest中缺少provider的節(jié)點(diǎn)。網(wǎng)上查了下關(guān)于安裝apk所需的provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.fileprovider" <!--定義provider后面取值需要用到仑最,名字要一致-->
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" /> <!--在xml文件夾內(nèi)新建文件配置路徑-->
</provider>
@xml/file_paths文件:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="移動(dòng)辦公" path="/" />
</paths>
查了下關(guān)于該xml的定義:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!--Context.getFilesDir() 位于/data/data/安裝目錄-->
<files-path name="internalPath" path="file" />
<!--Context.getCacheDir()-->
<cache-path name="cachePath" path="file" />
<!--Environment.getExternalStorageDirectory()-->
<external-path name="externalPath" path="file" />
<!--Context.getExternalFilesDir(null)-->
<external-files-path name="externalFPath" path="file" />
</paths>
項(xiàng)目中用 <external-path 定義了外置路徑扔役,最后在代碼中調(diào)用安裝
public static boolean installApk(Context context, String apkPath) {
if (context == null || apkPath.isEmpty()) {
return false;
}
File apkfile = new File(apkPath);
if (!apkfile.exists()) {
return false;
}
PackageInfo pi = AppPackageUtil.getAPKFilePackageInfo(context, apkPath);
if (pi == null) {
apkfile.delete();
return false;
}
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT >= 24) { //7.p0以上
Uri apkUri = FileProvider.getUriForFile(context, "com.你的包名.fileprovider", apkfile);//注意這里的fileprovider要和manifest一致
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else { //7.0以下
//intent.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");
intent.setDataAndType(Uri.fromFile(apkfile), "application/vnd.android.package-archive");
}
context.startActivity(intent);
return true;
}
項(xiàng)目中沒有對(duì)版本進(jìn)行適配,缺少24以上的適配警医,加入以上代碼適配后亿胸,在Android 10的紅米手機(jī)上測(cè)試了更新后問題解決。