0

在我的應用程序中,圖像文件列表在recyclerview中被誇大了。然後應用程序編輯Image文件的元數據。Get Persistable SD Cad使用SAF編寫權限

我寫代碼的元數據 -

DocumentFile fos = DocumentFile.fromFile(new File(fileIn)); 

ByteSource bytsInputStream = new ByteSourceFile(new File(fileIn)); 
byte[] byteArrayInputStream = bytsInputStream.getAll(); 

try { 
    ParcelFileDescriptor pfd = context.getContentResolver(). 
      openFileDescriptor(fos.getUri(), "w"); 
    FileOutputStream fileOutputStream = 
      new FileOutputStream(pfd.getFileDescriptor()); 

    rewriter.updateExifMetadataLossy(byteArrayInputStream,fileOutputStream,outputSet); 

    fileOutputStream.close(); 
    pfd.close(); 

} 
catch (Exception e){e.printStackTrace();} 

我能夠更新存儲在手機內存中的圖像文件,但是對於SD卡的圖像,我得到錯誤---->

java.io.FileNotFoundException: Permission denied 

我知道從android 5開始,我們需要使用SAF來獲得許可。 我採取許可代碼: -

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 
intent.addFlags(
     Intent.FLAG_GRANT_READ_URI_PERMISSION 
       | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 
       | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 
startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT_TREE); 












@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    switch (requestCode) { 
     case REQUEST_CODE_OPEN_DOCUMENT_TREE: 
      if (resultCode == Activity.RESULT_OK) { 
       Uri treeUri = data.getData(); 
       int takeFlags = data.getFlags(); 
       takeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | 
           Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 

       if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { 
        this.getContentResolver().takePersistableUriPermission(treeUri, takeFlags); 
       } 
      } 
    } 

現在我不知道該怎麼做這個treeUri。 我希望我只在初始啓動時取得一次SdCard權限。

簡單來說,我的問題涉及到這樣一個問題: -

This Link

回答

0

takePersistableUriPermission() 

保存URI是要獲得絕對正確的。該權限一直保留到卸載或清除應用數據。 下一步是保留Uri以便以後訪問(即SharedPreferences)。

This會幫到你。

+0

但在將Uri存儲到sharedPreferences之後要做什麼。正如我的問題所述,我想編輯一個現有的文檔。那麼如何使用Uri訪問這個特定的文件 –

+0

將Uri路徑映射到文件路徑。這樣,您可以使用授予的權限訪問路徑下的文件:getFullPathFromTreeUri()[link](https://github.com/jeisfeld/Augendiagnose/blob/7e09f12cec5921b65541d28bd11caa6ce8d96e53/AugendiagnoseIdea/augendiagnoseLib/src/main/java/de/jeisfeld /augendiagnoselib/util/imagefile/FileUtil.java#L774) – Farasy

+0

無法得到您的觀點。請幫助我在這個問題: - http://stackoverflow.com/q/39054454/5309039 –

1
DocumentFile documentFile = DocumentFile.fromTreeUri(this, treeUri); 

這裏treeUri是你從SAF權限獲得的。意味着你在OnActivityResult()中獲得的。

DocumentFile fos = DocumentFile.fromFile(new File(fileIn));

在此,fileIn是您選擇的文件。然後

String[] parts = (fileIn.getPath()).split("\\/"); 
for (int i = 3; i < parts.length; i++) { 
if (documentFile != null) { 
    documentFile = documentFile.findFile(parts[i]); 
} 
} 

以下爲獲得的ByteArray,你需要使用此代碼

try { 
         InputStream iStream = getContentResolver().openInputStream(documentFile.getUri()); 
         byte[] byteArrayInputStream = getBytes(iStream); 
        } catch (FileNotFoundException e) { 
         e.printStackTrace(); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 

讓你想繼續你的代碼的字節數組後,也低於我求佛。

try { 
         ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(fos.getUri(), "w"); 
         FileOutputStream fileOutputStream = new FileOutputStream(pfd.getFileDescriptor()); 
         rewriter.updateExifMetadataLossy(byteArrayInputStream,fileOutputStream,outputSet); 
         fileOutputStream.close(); 
         pfd.close(); 
        }catch (Exception e){ 
         e.printStackTrace(); 
        } 

還沒有,我想這會幫助你。如果您發現任何錯誤,請糾正它。謝謝