簡體   English   中英

Android:如何獲取內容://外部存儲PUBLIC目錄中文件的URI

[英]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,然后可以讀取和寫入它解析的文件。

如果這有任何危險或缺點,我很樂意聽到他們。

這是我在我的應用程序中使用的圖片公共目錄。

  1. 像這樣創建文件:

     File theFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "YOUR_APP_NAME" + File.separator + "YOUR_FILE_NAME"); 
  2. 在文件提供程序的元數據中指定以下路徑:

     <paths> <external-path name="secure_name" path="Pictures/YOUR_APP_NAME" /> </paths> 

“secure_name”用於隱藏您出於安全原因共享的子目錄(在本例中為“YOUR_APP_NAME” )的名稱。

“圖片”對應於Environment.DIRECTORY_PICTURES

  1. 獲得UriIntent一起發送:

     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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM