Android 7.0 安裝 App

前言

Andrid 7.0 繼續(xù)提高了對用戶隱私的保護和系統(tǒng)安全性,直接禁止掉了 file:// 協(xié)議,我們通常使用下面的代碼安裝apk就會出現(xiàn)問題:

    /**
     * 調(diào)用系統(tǒng)安裝應用
     */
    public static boolean install(Context context, File file) {
        if (file == null || !file.exists() || !file.isFile()) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
        return true;
    }

在 7.0 的設備上運行的時候會報 FileUriExposedException (文件Uri暴露)錯誤:

Caused by: android.os.FileUriExposedException

解決辦法是通過定義 FileProvider,觀察發(fā)現(xiàn)使用的是content:// 協(xié)議

清單文件中定義 FileProvider

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.graypn.android_common.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths"/>
</provider>

注意下 authorities字段,同一個手機上,只能有一個名字為這個 authoritiesProvider ,不能重復。

這里的 meta-data 設置了可訪問的文件路徑。

添加可訪問的文件目錄

在res目錄下,增加xml文件夾,并新建一個名為 file_paths.xml 的文件。文件內(nèi)容格式如下:

<paths>
    <external-path
        name="external_storage_root"
        path="."/>
</paths>

這里指定了根目錄

與6.0及以下的系統(tǒng)兼容

以上這種通過 FileProvider 形式取得的 Uri 只能在 7.0 以上的設備上使用,在以下的系統(tǒng)回報這個錯誤:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://com.graypn.android_common.fileProvider/external_storage_root/szssmartparty.apk typ=application/vnd.android.package-archive flg=0x1 }

所以要有對不同的系統(tǒng)進行不同的處理,最終代碼如下:

    /**
     * 調(diào)用系統(tǒng)安裝應用
     */
    public static boolean install(Context context, File file) {
        if (file == null || !file.exists() || !file.isFile()) {
            return false;
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Uri apkUri;
        // Android 7.0 以上不支持 file://協(xié)議 需要通過 FileProvider 訪問 sd卡 下面的文件,所以 Uri 需要通過 FileProvider 構造,協(xié)議為 content://
        if (Build.VERSION.SDK_INT >= 24) {
            // content:// 協(xié)議
            apkUri = FileProvider.getUriForFile(context, "com.graypn.android_common.fileProvider", file);
            //Granting Temporary Permissions to a URI
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            // file:// 協(xié)議
            apkUri = Uri.fromFile(file);
        }
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        context.startActivity(intent);
        return true;
    }
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 上周,寫了個小demo,正好同事使用的小米手機系統(tǒng)內(nèi)核更新到7.0,遂拿來測試了一番。其中遇到的小問題,現(xiàn)在來跟大...
    monkey_who閱讀 4,867評論 0 13
  • 由于 Android 7.0 或更高版本的系統(tǒng)在國內(nèi)手機市場上的占比不是很高,很多 Android 開發(fā)人員并沒有...
    亦楓閱讀 4,409評論 1 39
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 昨天坐在我旁邊的小伙伴在聊最近校園周邊的八卦,我八卦的觸角立馬接通,疲憊的時候總想用點八卦來啟動癱瘓的大腦主機。然...
    佛系肉團閱讀 426評論 0 0
  • 我們村的學校很迷你,只有兩間教室,一間幼兒園,一間一二年級合用,一間辦公室,一間廁所,一方小小的天井。三年級開始就...
    公子戀戀閱讀 268評論 0 1

友情鏈接更多精彩內(nèi)容