Android 6.0 / 7.0 / 8.0 的APK安裝
Android 1.x~6.x APK安裝
關於 android 7.0 之前的 apk安裝,需要注意設定 Intent.FLAG_ACTIVITY_NEW_TASK 就好
Intent intent = new Intent(Intent.ACTION_VIEW); Uri apkUri = Uri.fromFile(file); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); startActivity(intent);
Android 7.x APK安裝
在 Android 7.0 引入了“私有目錄被限制訪問”,“StrictMode API 政策”。 Android 7.0 行為變更
” StrictMode API 政策” 是指禁止向你的應用外公開 file:// URI。使用上述方法安裝APK時會出現 FileUriExposedException 異常。這個時候就需要使用FileProvider來解決這個問題:
---------------------------------------------------------------------------------------------------------------------
步驟一 (FileProvider的申請),在Manifest.xml中定義一個FileProvider,程式碼如下:
<application> <provider android:name="android.support.v4.content.FileProvider" // 指向v4包裡的FileProvider類 android:authorities="你的包名.FileProvider" // 對應你的content uri的基礎域名,生成的uri將以content://你的包名.FileProvider作為開頭 android:exported="false" // 設定不允許匯出,我們的FileProvider應該是私有的 android:grantUriPermissions="true"> // 設定允許獲取訪問檔案的臨時許可權 <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/apk_provider_paths" /> // 用於設定FileProvider的檔案訪問路徑 </provider> </application>
注意 android:authorities="你的包名.FileProvider" 中 “你的包名”為你當前專案包名
---------------------------------------------------------------------------------------------------------------------
步驟二 (建立 .xml),在res目錄新建xml資料夾,如圖所示
xml檔案下的 .xml檔名與步驟一中 android:resource="@xml/apk_provider_paths" 引用的名稱一致
---------------------------------------------------------------------------------------------------------------------
步驟三 (配置FileProvider檔案共享的路徑),在 apk_provider_paths.xml檔案中配置:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="應用名稱"
path="apk所在路徑" />
</paths>
在標籤中我們必須配置至少一個或多個path子元素, path子元素則用來定義content uri所對應的路徑目錄。
這裡說明一下, 例如將 APK 下載到了 Environment.getExternalStorageDirectory() + "/aaa/bbb" 目錄下,則配置如下
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="xxx"
path="/aaa/bbb" />
</paths>
如果你的 APK不是在 sdcard目錄下,那麼 apk_provider_paths.xml中的 paths 需要進行重新配置。具體可參考點選檢視或者Android7.0
根據文件提示,我們使用FileProvider進行處理,同時利用xml對FileProvider進行配置 ,可參考如下
Java根路徑產生方式 | 對應xml根節點名稱 | |
Context.getFilesDir() | files-path | |
getCacheDir() | cache-path | |
Environment.getExternalStorageDirectory() |
|
|
Context#getExternalFilesDir(String) Context.getExternalFilesDir(null) |
|
|
Context.getExternalCacheDir() | external-cache-path |
具體升級程式碼
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri apkUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// 授予檔案操作的臨時許可權,根據需求設定,一般安裝只需要READ許可權
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
// 獲取配置的FileProvider的 Content Uri的值
apkUri = FileProvider.getUriForFile(mContext
, "你的包名.FileProvider"
, file);
} else {
apkUri = Uri.fromFile(file);
}
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
Android 8.x APK安裝
在Android 8.0 Oreo 中,Google 移除掉了容易被濫用的“允許位置來源”應用的開關,在安裝 GooglePlay Store 之外的第三方來源的 Android 應用的時候,竟然沒有了“允許未知來源”的檢查框,如果你還是想要安裝某個被自己所信任的開發者的 app,則需要授予“安裝未知應用”的許可。
靜態許可權設定:
在Manifest.xml配置檔案中新增以下許可權,這個不是危險許可權,可以不用動態申請。
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>