最近在做app的自動更新功能,在網上找了別人做好的demo【感謝crazyfzw的分享】,在測試機[4.4,5.0,6.0]上能正常使用,本來就打算這么放過了。結果在別人的手機上出現了無法自動安裝的情況:下載完文件后不能發起調用。 發現他們使用的系統是7.0或8.0,百度后才知道高版本的系統對共享目錄和未知來源的安裝文件做了限制。
一般的自動更新功能,是通過解析服務器上記錄的版本信息【如json文件】,獲取版本號和本地進行對比,再進行下載 和調用文件、完成安裝。
在7.0中,需要使用FileProvider。
1. 在AndroidManifest.xml中,申請權限:
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="com.name.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
2. 在xml目錄下新建file_paths,指定路徑:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="apkname"/>
</paths>
3.在下載文件的線程中:
//指定目錄
String mSavePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "apkname" +File.separator;
File dir = new File(mSavePath);
String apkName = urlStr.substring(urlStr.lastIndexOf("/") + 1, urlStr.length());//根據json,取得apK文件名
File apkFile = new File(dir, apkName);
4. 下載完成后調用installApk(apkFile),對版本號進行判斷.
通過日志輸出發現,7.0及以上獲取的地址是file開頭的,而7.0以下版本獲取的地址是context開頭的路徑。 最開始修改后更新,出現”解析包錯誤“的提示,連接電腦看logcat發現,原來是apkUri和msavepath不一致。修改后就可以了。
if(Build.VERSION.SDK_INT>=24){
Log.e(TAG,"Version>=24");
Uri apkUri = FileProvider.getUriForFile(this, "與AndroidManifest中的android:authorities一致", apkFile);
Log.e(TAG,apkUri.toString());
Log.e(TAG,apkFile.getAbsolutePath());
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{
//如果沒有設置SDCard寫權限,或者沒有sdcard,apk文件保存在內存中,需要授予權限才能安裝
Log.e(TAG,"Version<=24");
try {
String[] command = {"chmod", "777", apkFile.toString()}; //777代表權限 rwxrwxrwx
ProcessBuilder builder = new ProcessBuilder(command);
builder.start();
} catch (IOException ignored) {
}
intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
5. 對於安卓8.0,增加了對”未知來源應用“的安裝限制,每次都需要申請權限。 不知道是不是因為我有對應用進行簽名的關系,8.0沒有申請權限,也能完成安裝