Android再也不容許在app中把file://Uri暴露給其餘app,包括但不侷限於經過Intent或ClipData 等方法。緣由在於使用file://Uri會有一些風險,好比:android
file://Uri
的app沒法訪問該文件。READ_EXTERNAL_STORAGE
權限,在讀取文件時會引起崩潰。所以,google提供了FileProvider
,使用它能夠生成content://Uri
來替代file://Uri
。安全
AndroidManifest.xml
中添加providerFileProvider.getUriForFile
()方法得到Url
在 res/xml 目錄下新建一個 xml 文件,用於存放應用須要共享的目錄文件。這個 xml 文件的內容相似這樣:app
<paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="cam" path="images" /> </paths>
能夠看出,這五種子元素基本涵蓋內外存儲空間全部目錄路徑,包含應用私有目錄。同時,每一個子元素都擁有 name 和 path 兩個屬性。其中,path 屬性用於指定當前子元素所表明目錄下須要共享的子目錄名稱。注意:path 屬性值不能使用具體的獨立文件名,只能是目錄名。而 name 屬性用於給 path 屬性所指定的子目錄名稱取一個別名。後續生成 content:// URI 時,會使用這個別名代替真實目錄名。這樣作的目的,很顯然是爲了提升安全性。若是咱們須要分享的文件位於同級別目錄下不一樣的子目錄中,就須要添加多個子元素逐一指定要分享的文件目錄,或者共享他們通用的父目錄也行。ide
不一樣的app可能會有要求不一樣的共享目錄,這個要求的共享目錄能夠在報錯裏找到,添加對應的報錯路徑便可.this
AndroidManifest.xml
中添加provider<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.yt.demo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider>
請注意authorities這行,須要添加你的包名 加 後綴google
FileProvider.getUriForFile
()方法得到Url例子代碼以下:spa
String filePath = Environment.getExternalStorageDirectory() + "/images/"+System.currentTimeMillis()+".jpg"; File outputFile = new File(filePath); if (!outputFile.getParentFile().exists()) { outputFile.getParentFile().mkdir(); } Uri contentUri = FileProvider.getUriForFile(this, getPackageName()+".fileprovider", outputFile);