1. 程式人生 > >android App更新7.0許可權

android App更新7.0許可權

public void InstallApk(){
    String filePath = getExternalFilesDir("Download").getAbsolutePath() + File.separator+"軟體名稱"+mVersion+".apk";
    Intent install = new Intent(Intent.ACTION_VIEW);
    if(Build.VERSION.SDK_INT>=24) {//判讀版本是否在7.0以上
Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID 
+".fileprovider", new File(filePath)); install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//新增這一句表示對目標應用臨時授權該Uri所代表的檔案 install.setDataAndType(apkUri, "application/vnd.android.package-archive"); }else { install.setDataAndType(Uri.parse
("file://"+filePath), "application/vnd.android.package-archive"); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } startActivity(install); }

1.1 定義一個FileProvider

直接使用FileProvider本身或者它的子類,需要在AndroidManifest.xml檔案中宣告元件的相關屬性,包括:

  • android:name,對應屬性值:android.support.v4.content.FileProvider或者子類完整路徑
  • android:authorities,對應屬性值是一個常量,通常定義的方式packagename.fileprovider,例如:cn.teachcourse.fileprovider
  • android:exported,對應屬性值是一個boolean變數,設定為false
  • android:grantUriPermissions,對應屬性值也是一個boolean變數,設定為true,允許獲得檔案臨時的訪問許可權
<manifest>
    ...
    <application>
        ...
        <provider            android:name="android.support.v4.content.FileProvider"            android:authorities="com.mydomain.fileprovider"            android:exported="false"            android:grantUriPermissions="true">
            ...
        </provider>
        ...
    </application>
</manifest>

想要關聯res/xml資料夾下建立的file_provider.xml檔案,需要在<provider>標籤內,新增<meta-data>子標籤,設定<meta-data>標籤的屬性值,包括:

  • android:name,對應屬性值是一個固定的系統常量android.support.FILE_PROVIDER_PATHS
  • android:resource,對應屬性值指向我們的xml檔案@xml/file_provider
<provider    android:name="android.support.v4.content.FileProvider"    android:authorities="com.mydomain.fileprovider"    android:exported="false"    android:grantUriPermissions="true">
    <meta-data        android:name="android.support.FILE_PROVIDER_PATHS"        android:resource="@xml/file_provider"/>
</provider>

1.2 指定授予臨時訪問許可權的檔案目錄

上一步說明了怎麼定義一個FileProvider,這一步主要說明怎麼定義一個@xml/file_provider檔案。Android Studio或Eclipse開發工具建立Android專案的時候預設不會建立res/xml資料夾,需要開發者手動建立,點選res資料夾新建目錄,命名xml,如下圖:

Android Studio新建xml目錄

然後,在xml資料夾下新建一個xml檔案,檔案命名file_provider.xml,指定根標籤為paths,如下圖:

xml新建file_provider.xml

在xml檔案中指定檔案儲存的區塊和區塊的相對路徑,在<paths>根標籤中新增<files-path>子標籤(稍後詳細列出所有子標籤),設定子標籤的屬性值,包括:

  • name,是一個虛設的檔名(可以自由命名),對外可見路徑的一部分,隱藏真實檔案目錄
  • path,是一個相對目錄,相對於當前的子標籤<files-path>根目錄
  • <files-path>,表示內部記憶體卡根目錄,對應根目錄等價於Context.getFilesDir(),檢視完整路徑:
    /data/user/0/cn.teachcourse.demos/files
  • 程式碼如下:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_images" path="images/"/>
    ...
</paths>

<paths>根標籤下可以新增的子標籤也是有限的,參考官網的開發文件,除了上述的提到的<files-path>這個子標籤外,還包括下面幾個:

  1. <cache-path>,表示應用預設快取根目錄,對應根目錄等價於getCacheDir(),檢視完整路徑:/data/user/0/cn.teachcourse.demos/cache

  2. <external-path>,表示外部記憶體卡根目錄,對應根目錄等價於
    Environment.getExternalStorageDirectory()
    檢視完整路徑:/storage/emulated/0

  3. <external-files-path>,表示外部記憶體卡根目錄下的APP公共目錄,對應根目錄等價於
    Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)
    檢視完整路徑:
    /storage/emulated/0/Android/data/cn.teachcourse.demos/files/Download

  4. <external-cache-path>,表示外部記憶體卡根目錄下的APP快取目錄,對應根目錄等價於Context.getExternalCacheDir(),檢視完整路徑:
    /storage/emulated/0/Android/data/cn.teachcourse.demos/cache