一 : content-url(content://)相比於file-url(file:///),安全很多。intent通過把uri設置為它的參數,並通過setFlags設置flag,可以讓其他app獲得該uri的臨時訪問。而file的話,授權是永久的,除非手動改變。
二:使用fileProvider的步驟如下:
-
<manifest> ... <application> ... <provider android:name="androidx.core.content.FileProvider" 固定 android:authorities="com.mydomain.fileprovider" 自定義,一般包名加provider就行 android:exported="false" 是否public,是否可被訪問 android:grantUriPermissions="true"> 是否允許授予臨時訪問權限給文件 ... </provider> ... </application> </manifest>
- 因為fileprovider只能給你“事先指定”的文件路徑下的文件授權,所以我們需要指定哪些文件是可以被授權的:
https://developer.android.com/reference/kotlin/androidx/core/content/FileProvider#specifying-available-files, paths標簽下可以有1或多個元素,
<files-path name="這里是啥無所謂" path="." />-----------1
<external-path name="這里是啥無所謂" path="." />-------------2
似乎上面那里path那個路徑我除了用 . , 其他都不行 -
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> 根據第二步的文件夾名,在第一步的標簽下加上
- 如果在內部存儲目錄下放置一張圖片“1.png”的話,要生成uri,首先第二步那里要采用1,然后這樣生成:
val fileDir = context.applicationContext.filesDir val file = File(fileDir, "1.png") val contentUri:Uri = getUriForFile(getContext(), "com.mydomain.fileprovider", file)//fragment里用requireContext(), 第二個參數和第一步里的“自定義”對應
file的absolute path為: /data/user/0/包名/files/1.jpg 盡管實際上是 data/data/包名/files/1.png uri打印出來是: content://自定義的那個/這里是啥無所謂的那個/1.png
如果在外部存儲目錄下放置圖片,第二步那里要用2,然后這樣:
val fileDir = context.applicationContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)//里面可以是Environment類里的其他常數 val file = file(fileDir, filename)
val contentUri:Uri = getUriForFile(getContext(), "com.mydomain.fileprovider", file)//fragment里用requireContext(), 第二個參數和第一步里的“自定義”對應file的absolute path為:
/storage/emulated/0/Android/data/包名/files/Pictures/filename
uri打印出來是:
content://自定義的那個權限名/這里是啥無所謂的那個/Android/data/包名/files/Pictures/filename - 還可以靈活使用query和delete對content-uri進行操作,如果要使用insert和update要繼承fileProvider自定義。