2017-08-28 28 views
1

我爲用戶設置了一個首選項,以使用Storage Access Framework爲我的應用程序選擇保存文件夾。在獲得uri onActivityResult後,我將它保存爲SharedPreferences作爲字符串,並保存要保存的圖像。從Storage Access Framework UI獲取文件夾後保存圖像

我正在使用此方法成功保存圖像。

public void saveImageWithDocumentFile(String uriString, String mimeType, String name) { 
    isImageSaved = false; 
    try { 
     Uri uri = Uri.parse(uriString); 
     DocumentFile pickedDir = DocumentFile.fromTreeUri(this, uri); 
     DocumentFile file = pickedDir.createFile(mimeType, name); 
     OutputStream out = getContentResolver().openOutputStream(file.getUri()); 
     isImageSaved = mBitmap.compress(CompressFormat.JPEG, 100, out); 
     out.close(); 

    } catch (IOException e) { 
     throw new RuntimeException("Something went wrong : " + e.getMessage(), e); 
    } 
    Toast.makeText(MainActivity.this, "Image saved " + isImageSaved, Toast.LENGTH_SHORT).show(); 
} 

如果用戶刪除使用SAF選擇的文件夾,的iget空DocumentFile file和應用程序崩潰。我的第一個問題是,如何在不打開SAF ui的情況下檢查文件夾是否存在。

我也想用ParcelFileDescriptor保存相同的圖像用這種方法

public void saveImageWithParcelFileDescriptor(String folder, String name) { 
    if (mBitmap == null) { 
     Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT).show(); 
     return; 
    } 
    String image = folder + File.separator + name + ".jpg"; 
    Toast.makeText(MainActivity.this, "image " + image, Toast.LENGTH_LONG).show(); 

    Uri uri = Uri.parse(image); 
    ParcelFileDescriptor pfd = null; 
    FileOutputStream fileOutputStream = null; 
    try { 
     pfd = getContentResolver().openFileDescriptor(uri, "w"); 
     fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); 
     mBitmap.compress(CompressFormat.JPEG, 100, fileOutputStream); 

    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } finally { 
     if (pfd != null) { 
      try { 
       pfd.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 

     if (fileOutputStream != null) { 
      try { 
       fileOutputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
    Toast.makeText(MainActivity.this, "Image saved " + isImageSaved, Toast.LENGTH_SHORT).show(); 

} 

我得到java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/612E-B7BF%3Aname/imagePFD.jpg 上線pfd = getContentResolver().openFileDescriptor(uri, "w");

這是我如何調用該方法,currentFolder是文件夾我在第一種方法上使用intent和相同的文件夾。

saveImageWithParcelFileDescriptor(currentFolder, "imagePFD"); 

我該如何解決這個問題,以及哪種方法更可取,爲什麼?

回答

1

如何檢查如果文件夾中存在

DocumentFile具有exists()方法。理論上,pickedDir.exists()應該告訴你它是否存在。實際上,這取決於存儲提供商。

我也想用ParcelFileDescriptor保存相同的圖像用這種方法

該代碼有錯誤:

  • 使用grantUriPermission()

  • 您不能授予自己權限不能通過串聯發明任意的Uri值,特別是對於提供者這是不是你的

我怎樣才能解決這個

刪除它。

該方法是更優選的

第一個。

爲什麼?

第一個將工作,也許稍作調整。第二個沒有工作的機會。

+0

是的,第一個工作只要保存的文件夾存在。我將檢查documentFile.exist()是否存在文件夾。沒有辦法用自定義名稱和ParcelFileDescriptor保存圖像嗎? – Thracian

+1

@FatihOzcan:歡迎您用getContentResolver()從第一個代碼片段中替換'OutputStream out = getContentResolver()。openOutputStream(file.getUri())'。openFileDescriptor(file.getUri(),「w」)'並以這種方式使用'ParcelFileDescriptor'。我不知道優點是什麼,結果會比第一個代碼片段長得多,並且結果不會與第二個代碼片段非常相似。關鍵是使用'createFile()',所以存儲提供者就是你寫的'Uri'。 – CommonsWare

+0

我刪除了'grantUriPermission()'。獲得權限或持久性權限僅對uA on'onActivityResult'有效?沒有關於這個文件的信息。在文檔上「您的應用程序訪問的最近的URI可能不再有效 - 另一個應用程序可能已刪除或修改了文檔。因此,您應該始終調用getContentResolver()。takePersistableUriPermission()來檢查最新的數據。」我如何檢查一個文件夾是否存在與此方法。它不會返回任何東西。 – Thracian

相關問題