1. 程式人生 > >Android7.0、8.0應用內安裝apk實現

Android7.0、8.0應用內安裝apk實現

最近,公司線上專案發現,部分手機應用內更新下載apk後安裝無反應的問題。由於測試我並未參與,得知同事的問題描述後誤認為是部分機型的相容性問題,費了半天勁。最後才發現是Andorid8.0許可權問題,很是惱火啊,哈哈。鑑於此,還是把不同Android版本正確發起應用內安裝的實現分享給大家。

首先將現有的Android版本進行分一下界限,Android 1.x~6.x 和Android 7.x 及Android 8.x。可以看下圖,如果看不懂,接下來我會詳細解說,如果你領悟了就不用往下看了。

Android8.0的變化是,未知應用安裝許可權的開關被除掉,取而代之的是未知來源應用的管理列表,需要在裡面開啟每個應用的未知來源的安裝許可權。Google這麼做是為了防止一開始正經的應用後來開始通過升級來做一些不合法的事情,侵犯使用者權益。

解決辦法是新增許可權,如下:

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

Android7.0為了提高私有檔案的安全性,對檔案訪問做了限制。官方描述 

解決辦法是使用FileProvider:

1.清單檔案中application節點下定義 FileProvider

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

2.新增可訪問的檔案目錄

在res目錄下,增加xml資料夾,並新建一個名為 file_paths.xml 的檔案。檔案內容格式如下:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="downloadApk"
        path="tolvgx" />
</paths>

實現安裝apk的程式碼

/**
 * 安裝apk
 */
private void installApk(File file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Log.d("installApk", "版本大於 N ,開始使用 fileProvider 進行安裝");

        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Uri contentUri = FileProvider.getUriForFile(this, "com.tolvgx.demo.fileprovider", file);
        intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
    } else {
        Log.d("installApk", "正常進行安裝");

        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
    }
    startActivity(intent);
}