Having invoked a directory selector on Android with:
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.addFlags(
Intent.FLAG_GRANT_READ_URI_PERMISSION
or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
or Intent.FLAG_GRANT_PREFIX_URI_PERMISSION
)
activity?.startActivityForResult(intent, REQUEST_CODE_FOLDER_PERMISSION)
And having obtained the URI of said route in onActivityResult()
, being the URI of the form (example in case of having chosen a folder named backup in the root of the external storage):
content://com.android.externalstorage.documents/tree/primary:backup
At this point, how do you write a file to that location? After researching various answers on how to write files using the Media Store API, all the examples I've seen use constants to refer to already existing media directories, but in my case I want to create a new document (which is a JSON file) in the directory chosen by the user.
Thanks to @CommonsWare for pointing me in the right direction:
var outputStream: OutputStream? = null
try {
val uri = Uri.parse(path)
val document = DocumentFile.fromTreeUri(context, uri)
val file = document?.createFile(mimeType, filename)
?: throw Exception("Created file is null, cannot continue")
val fileUri = file.uri
val contentResolver = context.contentResolver
outputStream = contentResolver.openOutputStream(fileUri)
val bytes = content.toByteArray()
outputStream?.write(bytes)
outputStream?.flush()
} catch (e: Exception) {
// Handle error
} finally {
outputStream?.close()
}