title: Creating a writeable DocumentFile from URI
body: <p>I'm trying to adapt a <code>File</code>-based document system to something using <code>DocumentFile</code> in order to allow external storage read/write access on API >= 29.</p>
  
  <p>I get the user to select the SD card root using <code>Intent.ACTION_OPEN_DOCUMENT_TREE</code>, and I get back a <code>Uri</code> as expected, which I can then handle using:</p>
  
  <pre><code>    getContentResolver().takePersistableUriPermission(resultData.getData(),
                              Intent.FLAG_GRANT_READ_URI_PERMISSION
                              | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
  </code></pre>
  
  <p>I can browse successfully through the external storage contents up to the selected root. All good.</p>
  
  <p>But what I need to be able to do is write an arbitrary file in the chosen (sub)folder, and that's where I'm running into problems.</p>
  
  <pre><code>    DocumentFile file = DocumentFile.fromSingleUri(mContext, Uri.parse(toPath));
      Uri uri = file.getUri();
      FileOutputStream output = mContext.getContentResolver().openOutputStream(uri);
  </code></pre>
  
  <p>Except on the <code>openOutputStream()</code> call I get:</p>
  
  <p><code>java.io.FileNotFoundException: Failed to open for writing: java.io.FileNotFoundException: open failed: EISDIR (Is a directory)</code></p>
  
  <p>That's slightly confusing to me, but the "file not found" part suggests I might need to create the blank output file first, so I try that, like:</p>
  
  <pre><code>    DocumentFile file = DocumentFile.fromSingleUri(mContext, Uri.parse(toPath));
      Uri uri = file.getUri();
      if (file == null) {
          return false;
      }
      if (file.exists()) {
          file.delete();
      }
      DocumentFile.fromTreeUri(mContext, Uri.parse(getParentPath(toPath))).createFile("", uri.getLastPathSegment());
      FileOutputStream output = mContext.getContentResolver().openOutputStream(uri);
  </code></pre>
  
  <p>I get a <code>java.io.IOException</code>:</p>
  
  <pre><code>    java.lang.IllegalStateException: Failed to touch /mnt/media_rw/0B07-1910/Testing.tmp: java.io.IOException: Read-only file system
      at android.os.Parcel.createException(Parcel.java:2079)
      at android.os.Parcel.readException(Parcel.java:2039)
      at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:188)
      at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
      at android.content.ContentProviderProxy.call(ContentProviderNative.java:658)
      at android.content.ContentResolver.call(ContentResolver.java:2042)
      at android.provider.DocumentsContract.createDocument(DocumentsContract.java:1327)
      at androidx.documentfile.provider.TreeDocumentFile.createFile(TreeDocumentFile.java:53)
      at androidx.documentfile.provider.TreeDocumentFile.createFile(TreeDocumentFile.java:45)
  </code></pre>
  
  <p>Which doesn't make sense to me, since the tree <em>should</em> be writeable.</p>
  
  <p>For what it's worth, the <code>Uri</code> I get back from <code>Intent.ACTION_OPEN_DOCUMENT_TREE</code> looks like this:</p>
  
  <p><code>content://com.android.externalstorage.documents/tree/0B07-1910%3A</code></p>
  
  <p>Interestingly, when I use that <code>Uri</code> to create a <code>DocumentFile</code> object to browse, using <code>documentFile = DocumentFile.fromTreeUri(context, uri)</code>, then <code>documentFile.getURI().toString()</code> looks like:</p>
  
  <p><code>content://com.android.externalstorage.documents/tree/0B07-1910%3A/document/0B07-1910%3A</code></p>
  
  <p>i.e., it's had something appended to the end of it.</p>
  
  <p>Then, I descend into what should be a writeable folder (like "Download"), and try creating a writeable file as described above. The "Download" folder gets the <code>Uri</code>:</p>
  
  <p><code>content://com.android.externalstorage.documents/tree/0B07-1910%3A/document/0B07-1910%3ADownload</code></p>
  
  <p>and the <code>Uri</code> I'm using for <code>toPath</code>, above, is then:</p>
  
  <p><code>content://com.android.externalstorage.documents/tree/0B07-1910%3A/document/0B07-1910%3ADownload/Testing.tmp</code></p>
  
  <p>which leads to the problems described previously trying to create it.</p>
  
  <p>I haven't actually found any decent information about writing an arbitrary file under Storage Access Framework restrictions.</p>
  
  <p>What am I doing wrong? Thanks. :)</p>