從 Android N 開始,不允許在 App 間用 file:// 的方式傳遞 File,否者會丟擲 FileUriExposedException的錯誤,須改透過 FileProvider來提供Uri進行檔案傳送.
使用方法
1. 配置AndroidManifest
exported: FileProvider 是否要公開出去
granUriPermissions: 是否允許授權檔案的臨時訪問許可權
2. 在res的建xml目錄, 建立 file_paths.xml 檔案, 依需求配置相關屬性
► 外部儲存的公共目錄 Environment.getExternalStoragePublicDirectory() 配合下參數取得
使用方法
1. 配置AndroidManifest
authorities: 一般用package name<provider android:name="android.support.v4.content.FileProvider" android:authorities="{package}.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
exported: FileProvider 是否要公開出去
granUriPermissions: 是否允許授權檔案的臨時訪問許可權
2. 在res的建xml目錄, 建立 file_paths.xml 檔案, 依需求配置相關屬性
3. 程式內將 File 轉為 Uri<!-- 配置root-path。這樣子可以讀取到sd卡和一些應用分身的目錄 File 在私有路徑下其根目錄為 / 開頭會造成 FileProvider.getUriForFile 轉換時錯誤 Failed to find configured root that contains xxx --> <root-path name="rootPath" path="" /> <!-- <external-files-path name="ext-files_path" path="." /> ContextCompat.getExternalFilesDirs() 獲取目錄 <external-cache-path name="ext-cache_path" path="." /> ContextCompat.getExternalCacheDirs() 獲取目錄 <external-media-path --> <external-path name="ext-download" path="Download/"/><!-- Environment.getExternalStorageDirectory() 獲取目錄 --> <external-path name="ext-imgfile" path="Pictures/"/> <!-- 私有路徑 --> <files-path name="myfile" path="files/"/> <!-- content.getFileDir() 獲取到的目錄 --> <cache-path name="mycache" path="cache/"/> <!-- content.getCacheDir() 獲取到的目錄 -->
► xml 配置與實際路徑對照Uri fileUri = FileProvider.getUriForFile(this, this.getPackageName() + ".fileprovider", tarFile);
Tag | Path | 對應方法 |
---|---|---|
root-path | / | |
私有路徑 | ||
files-path | /data/data/{Package}/files | content.getFileDir() |
cache-path | /data/data/{Package}/cache | content.getCacheDir() |
公有路徑 | Android 10(Q) 則對公有路徑進一步限制, 須採用 ASF 或 MediaStore+getContentResolver() 來取得Uri | |
external-path | /storage/emulate/0 | Environment.getExternalStorageDirectory() getExternalStoragePublicDirectory() |
external-files-path | /storage/emulate/0/Android/data/{Package}/files | ContextCompat.getExternalFilesDirs() |
external-cache-path | /storage/emulate/0/Android/data/{Package}/cache | ContextCompat.getExternalCacheDirs() |
► 外部儲存的公共目錄 Environment.getExternalStoragePublicDirectory() 配合下參數取得
DIRECTORY_MUSIC:音樂 /storage/emulate/0/music
DIRECTORY_PICTURES:圖片
DIRECTORY_MOVIES:電影
DIRECTORY_DCIM:相機照片,視訊 /storage/emulate/0/DCIM
DIRECTORY_DOWNLOADS:下載檔案 /storage/emulate/0/downloads
DIRECTORY_DOCUMENTS:文件
DIRECTORY_RINGTONES:鈴聲
DIRECTORY_ALARMS:鬧鐘提示音
DIRECTORY_NOTIFICATIONS:通知提示音
DIRECTORY_PODCASTS:播客音訊
DIRECTORY_PICTURES:圖片
DIRECTORY_MOVIES:電影
DIRECTORY_DCIM:相機照片,視訊 /storage/emulate/0/DCIM
DIRECTORY_DOWNLOADS:下載檔案 /storage/emulate/0/downloads
DIRECTORY_DOCUMENTS:文件
DIRECTORY_RINGTONES:鈴聲
DIRECTORY_ALARMS:鬧鐘提示音
DIRECTORY_NOTIFICATIONS:通知提示音
DIRECTORY_PODCASTS:播客音訊