Android7.0版本更新無法安裝apk
許可權
在適配7.0手機的時候,發現部分手機下載到最新版本以後,無法自動安裝問題.
通過查詢才發現, 在AndroidAPI23以後, 部分許可權要動態獲取. 也就是說在下載前需要動態獲取檔案的讀寫許可權,在小米5適配出現這樣問題
從前幾屆谷歌大會,我們可以知道, 隨著android版本越高 , android對於移動裝置隱私的保護力度越來越大, 從Android6.0引入動態許可權控制到Android7.0的"私有目錄被限制訪問", 這些改變為使用者帶來更加安全的使用者體驗, 同時也給開發帶來了一些新的要求.
目錄限制訪問
在目錄及檔案的訪問和保護方面,Android比IOS要做的不夠好. 我們知道在android應用中可以可以隨意讀寫手機儲存中任意檔案, 但是這些帶來了很多的安全問題,比如:由於私有檔案許可權放權給所有的應用程式, 我們在使用和
適配7.0
1.在AndroidManifest.xml檔案中新增如下程式碼
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="{應用程式的包名}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
注意:
name: provider可以使用V4包提供FileProvider, 或者自己定義
authorities: app的包名.fileprovider
exported: 必須是false 表示provider不需要對外開放
grantUriPermissions: 必須設定為true, 表示授予URL臨時訪問許可權
2. 在res->xml下建立file_path.xml檔案
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="files_root"
path="Android/data/{應用程式的包名}/" />
<external-path
name="external_storage_root"
path="." />
</paths>
注意:
path: 需要臨時授權訪問的路徑(.代表所有的路徑)
name: 表示給訪問路徑起的名字
path節點的區別:
<root-path/>: 可以訪問儲存卡中的資料
<files-path/>: 代表根目錄: Context.getFilesDir()
<external-path/>: 代表根目錄: Environment.getExternalStorageDirectory()
<cache-path/>: 代表根目錄: getCacheDir()
如果要想了解path的詳細用法,大家可以搜一下,講的更加詳細, 本文只作簡單解釋
3. 在下載完成啟動安裝進行適配不同的安裝包的開啟方式
File file = new File(apkPath);//更新包檔案
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Android7.0及以上版本
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(context, "應用包名" + ".fileProvider", file);//引數二:應用包名+".fileProvider"(和步驟一中的Manifest檔案中的provider節點下的authorities對應)
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
// Android7.0以下版本
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
context.startActivity(intent);
如果有地方寫的不對的,歡迎各位同仁指正