自從 Android 7.0 開始傳輸檔案的 URI 就不能用絕對路徑,而是要用 應用程式的 私有目錄。
簡單來說,我的 App 裡面有一張圖片(私有),想要交由其他可以裁切圖片的 App 來處理圖片,那麼在 Android 7.0 以上在傳輸圖片時的 Uri 只能用 content:// Uri。
那麼 File Provider 如何使用呢?
首先在 Manifest 註冊一個 Provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="chatRoom.fileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepath" />
</provider>
</application>
android:authorities=”chatRoom.fileProvider” 這句指的是 provider 的名字,這裡我取名為 chatRoom.fileProvider,grantUriPermissions=”true” 這句指的是別的 App 可以存取我的 App 中的 Uri (檔案的 Uri)。
接著新增 filepath,限制 Camera 可以存取的檔案路徑,android:resource=”@xml/filepath” 代表存取路徑的限制。
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepath" />
filepath 檔案如下
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="my_images" path="/images"/>
</paths>
name 用於 path 所指定的子目錄名稱的別名。Create content:// URI 時,會使用 name 來取代真實的 路徑。
講一下幾種檔案目錄以及對應的 filepath
files-path:對應的是 App 的 internal storage。
cache-path:對應的是 App 的 internal storage,但是是屬於 cache file。
external-path:對應 App 的 external storage。
external-files-path:對應 App 的 external private storage。
external-cache-path:對應 App 的 external cache storage。
external-media-path:對應 App 的 externalMediaDirs。
例子:傳 Uri 給相機儲存大圖
var file: File? = null
val filePath = this.filesDir.toString() + "/images/stickerImage.jpg"
file = File(filePath)
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir()
}
fileUri = FileProvider.getUriForFile(this, "chatRoom.fileProvider", file!!)
var i = Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE)
i.putExtra(MediaStore.EXTRA_OUTPUT, fileUri)
startActivityForResult(i, CAMERA_RETURN)
其實 File Provider 只是為了不讓檔案的絕對路徑到處傳阿~~~