1. 程式人生 > >Android 6.0 / 7.0 / 8.0 的APK安裝

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()

external-path

Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)
external-files-path
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"/>