一 : 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自定义。