[英]Android: How to get a content:// URI for a file in the external storage PUBLIC directory
我已經按照這個Google教程開始使用new Intent(MediaStore.ACTION_IMAGE_CAPTURE)
捕獲圖像。 本教程建議將公共目錄與getExternalStoragePublicDirectory
一起使用,這對我的應用程序非常getExternalStoragePublicDirectory
。 但是他們的例子改為使用getExternalFilesDir
。 然后使用MediaStore.EXTRA_OUTPUT
將文件的URI傳遞給intent我必須得到一個內容URI,因為我想定位Android N.在定位NI之前,只需傳遞一個文件:// URI,除了谷歌之外的所有人都很開心。 現在在NI上開始獲得看起來不太有利的FileUriExposedException
。
所以鑒於我有這樣的文件......
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyAppFolder");
if (!storageDir.exists() && !storageDir.mkdir())
Log.w(TAG, "Couldn't create photo folder: " + storageDir.getAbsolutePath());
File image = new File(storageDir, timeStamp + ".jpg");
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
...我可以使用公共圖片目錄的內置提供程序來獲取內容URI嗎? 如果是這樣的話?
我嘗試過類似的東西
takePictureIntent.putExtra(
MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(this, MediaStore.AUTHORITY, createImageFile()));
但它只是拋出
IllegalArgumentException:缺少android.support.FILE_PROVIDER_PATHS元數據
該權威是否正確? 如果我必須使用自己的提供程序來共享公共文件,那么我可以在FILE_PROVIDER_PATHS元數據中指定哪條路徑? 我能找到的所有選項都是針對私人目錄的。
TL:DR <external-path name="MyAppFolder" path="." />
<external-path name="MyAppFolder" path="." />
的作品,但它的安全?
您需要制作自己的FileProvider
。 值得一讀它的文檔 ,但這里有一個簡短的概述。
正如@CommonsWare所提到的,你需要用"com.example.fileprovider"
替換你的例子中的MediaStore.AUTHORITY
,這是你將在清單中定義的權限,如此...
在AndroidManifest的<application>
標記內,鍵入以下內容:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
您獲得的異常是由於沒有<meta-data>
標記鏈接到xml文件,該文件包含允許FileProvider
接觸的所有路徑。 但這就是我自己一直在努力爭取的文件。
在鏈接的教程結束時,在“ 保存全尺寸照片”部分的末尾,Google為此file_paths.xml
提供的示例是:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="Android/data/com.example.package.name/files/Pictures" />
</paths>
在您的示例中, "my_images"
將替換為"MyAppFolder"
。 在Google的那篇教程中聲稱
路徑組件對應於使用Environment.DIRECTORY_PICTURES調用時由getExternalFilesDir()返回的路徑。 確保將com.example.package.name替換為應用的實際包名稱。
...並打字輸出讓我意識到這並不是指你和我正在尋找的公共圖片目錄。 這解釋了為什么使用該路徑會產生此異常:
java.lang.IllegalArgumentException:無法找到包含/storage/emulated/0/Pictures/MyAppFolder/{filename}.jpg的已配置根目錄
我將把它留在這里以供將來參考,然后繼續回答您的大問題 - 您可以指定哪條路徑允許其他應用與您的應用目標API級別24+創建的公共圖片目錄中的文件進行交互?
正如@CommonsWare所說,“所需子目錄的詳細信息因設備而異”,因此您無法聲明公共圖片目錄的路徑,但我找到了一種有效的方法。
<external-path name="MyAppFolder" path="." />
<external-path name="MyAppFolder" path="." />
將允許您的FileProvider
為其他應用程序(如相機)提供內容URI,然后可以讀取和寫入它解析的文件。
如果這有任何危險或缺點,我很樂意聽到他們。
這是我在我的應用程序中使用的圖片公共目錄。
像這樣創建文件:
File theFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "YOUR_APP_NAME" + File.separator + "YOUR_FILE_NAME");
在文件提供程序的元數據中指定以下路徑:
<paths> <external-path name="secure_name" path="Pictures/YOUR_APP_NAME" /> </paths>
“secure_name”用於隱藏您出於安全原因共享的子目錄(在本例中為“YOUR_APP_NAME” )的名稱。
“圖片”對應於Environment.DIRECTORY_PICTURES
。
獲得Uri
與Intent
一起發送:
final Uri theUri = FileProvider.getUriForFile(activity, getString(R.string.fileprovider_authorities), theFile); theIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); theIntent.putExtra(MediaStore.EXTRA_OUTPUT, theUri);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.