2017-08-28 4 views
1

Ich habe eine Einstellung für Benutzer festgelegt, die den Speicherordner für meine App mit Storage Access Framework auswählen. Nachdem ich uri onActivityResult bekommen habe, speichere ich es unter SharedPreferences als String und speichere das Bild, wenn es gespeichert werden soll.Speichern eines Bildes nach dem Abrufen des Ordners von der Benutzeroberfläche des Storage Access Framework

Ich verwende diese Methode, um Bild erfolgreich zu speichern.

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(); 
} 

Wenn der Benutzer den Ordner löscht SAF ausgewählt verwenden, iGet null DocumentFile file und App-Abstürze. Meine erste Frage ist, wie kann ich prüfen, ob Ordner existieren, ohne SAF ui wieder zu öffnen.

Ich möchte auch ParcelFileDescriptor verwenden gleiche Bild mit dieser Methode

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(); 

} 

i java.lang.IllegalArgumentException: Invalid URI: content://com.android.externalstorage.documents/tree/612E-B7BF%3Aname/imagePFD.jpg on line erhalten speichern pfd = getContentResolver().openFileDescriptor(uri, "w");

Dies ist, wie ich diese Methode aufrufen, current der Ordner I Verwenden Sie Absicht und gleichen Ordner auf der ersten Methode.

saveImageWithParcelFileDescriptor(currentFolder, "imagePFD"); 

Wie kann ich das beheben, und welche Methode ist vorzuziehen und warum?

Antwort

1

Wie kann ich überprüfen, ob Ordner vorhanden

DocumentFile eine exists() Methode hat. In der Theorie sollte pickedDir.exists() Ihnen sagen, wenn es existiert. In der Praxis liegt es beim Speicheranbieter.

Ich möchte auch ParcelFileDescriptor verwenden gleiche Bild mit dieser Methode

Dieser Code Fehler zu speichern hat:

  • Sie können sich Berechtigungen nicht gewähren grantUriPermission()

  • Sie mit kann nicht willkürlich Uri Werte über Verkettung, insbesondere für einen Anbieter erfinden das ist nicht dein

Wie kann ich diese

löschen es zu beheben.

das Verfahren bevorzugter,

Die erste ist.

und warum?

Der erste wird funktionieren, vielleicht mit geringfügigen Anpassungen. Der zweite hat keine Chance zu arbeiten.

+0

Ja, das erste funktioniert so lange wie ein gespeicherter Ordner existiert. Ich werde prüfen, ob der Ordner mit documentFile.exist() existiert. Gibt es keine Möglichkeit, ein Bild mit einem benutzerdefinierten Namen und ParcelFileDescriptor zu speichern? – Thracian

+1

@FatihOzcan: Sie können 'OutputStream out = getContentResolver() gerne ersetzen. OpenOutputStream (file.getUri())' aus Ihrem ersten Code-Snippet mit 'getContentResolver(). OpenFileDescriptor (file.getUri()," w ")' und mit einem 'ParcelFileDescriptor' gehen. Ich weiß nicht, was der Vorteil wäre, das Ergebnis wäre viel länger als Ihr erstes Code-Snippet, und das Ergebnis würde Ihrem zweiten Code-Snippet nicht sehr ähnlich sein. Der Schlüssel benutzt 'createFile()', also ist der Speicheranbieter derjenige, der mit dem 'Uri' kommt, in den Sie schreiben. – CommonsWare

+0

Ich habe 'grantUriPermission()' entfernt. Die Erlaubnis oder persistierbare Erlaubnis erhalten ist nur gültig für URI, die Sie auf "onActivityResult" bekommen? Es gibt keine Informationen darüber auf Dokumenten. Auf Dokumenten "Die neuesten URIs, auf die Ihre App zugegriffen hat, sind möglicherweise nicht mehr gültig - eine andere App hat möglicherweise ein Dokument gelöscht oder geändert. Daher sollten Sie getContentResolver(). TakePersistableUriPermission() aufrufen, um nach den neuesten Daten zu suchen.", Wie kann ich prüfen, ob ein Ordner mit dieser Methode existiert? Es gibt nichts zurück. – Thracian

Verwandte Themen