1. 程式人生 > >Android N及以上版本應用安裝包下載完成自動彈出安裝介面的適配方法

Android N及以上版本應用安裝包下載完成自動彈出安裝介面的適配方法

Android N及以上版本應用安裝包下載完成自動彈出安裝介面的適配方法

  在實現下載和安裝APP功能的時候在Android較高版本可能會遇到如下的問題:

  • 安裝Apk時報錯:android.os.FileUriExposedException: file:///storage/emulated/0/Download/*.apk exposed beyond app through Intent.getData();
  • 彈不出安裝介面。

  上面遇到的這兩個問題主要是Android 8.0針對未知來源應用做了許可權限制,針對該問題的解決及完整適配方法如下。

完整適配步驟

1、適配Android 8.0及以上系統,需要在AndroidManifest.xml中新增安裝許可權:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

  Android O及Android 8.0及以上系統若不加該許可權,會遇到跳轉到安裝介面時閃退的問題,原因是8.0針對未知來源應用,在應用許可權設定的“特殊訪問許可權”中,加入了“安裝其他應用”的設定。
2、在AndroidManifest.xml中新增provider宣告:

<application
    ......
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

3、在res目錄下新建一個名為xml的目錄,並在xml目錄下新建一個名為file_paths.xml的檔案;
4、在file_paths.xml的檔案中新增如下程式碼:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-files-path name="external_files_path" path="Download" /><!--path:需要臨時授權訪問的路徑(.代表所有路徑)
    name:就是你給這個訪問路徑起個名字-->
    <!--為了適配所有路徑可以設定 path = "." -->
    <external-path path="." name="external_storage_root" />
</paths>

5、適配Android N彈出安裝介面的程式碼:

private void isAPK(String filePath) {
    File file = new File(filePath);
    if (file.getName().endsWith(".apk")) {
        try {
            Intent intent = new Intent(Intent.ACTION_VIEW);
            Uri uri;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 適配Android 7系統版本
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //新增這一句表示對目標應用臨時授權該Uri所代表的檔案
                uri = FileProvider.getUriForFile(XRetrofitApp.getApplication(), XRetrofitApp.getApplication().getPackageName() + ".fileprovider", file);//通過FileProvider建立一個content型別的Uri
            } else {
                uri = Uri.fromFile(file);
            }
            intent.setDataAndType(uri, "application/vnd.android.package-archive"); // 對應apk型別
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            XRetrofitApp.getApplication().startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

PS:下載完檔案,可以通過傳送掃描廣播,告訴系統掃描資料庫及時重新整理文件裡面的檔案,這樣即使下載安裝出錯,還可以進入文件檢視安裝應用包,程式碼如下:

Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
//根據需要自定義IMG_PATH路徑
Uri uri = Uri.fromFile(new File(downLoadPath + java.io.File.separator));
intent.setData(uri);
context.sendBroadcast(intent);