How to move a mediastore content item to another directory via DocumentContract.moveDocument()?

Viewed 621

Since Android is enforcing the use of storage access framework by scoped storage accessing, app cannot use direct java.io.file operation to move files.

The purpose is to move some specific media item which is queried from the mediastore database to another specific directory (same partition of the source file), which user has already granted rw permissions to the app.

However, when I try to create a DocumentFile instance using method

DocumentFile fromTreeUri(@NonNull Context context, @NonNull Uri treeUri)

The parent DocumentFile of the created instance is null in this case. And the method

Uri moveDocument(@NonNull ContentResolver content, @NonNull Uri sourceDocumentUri, @NonNull Uri sourceParentDocumentUri, @NonNull Uri targetParentDocumentUri)

requires the source parent to move the Document file. I know I can after all copy the source to target by reading/writing IO streams, but that is not efficient. So, how can I accomplish this in a recommended manner?

An additional question is if there is a way to move the content from mediastore to another place, how can I delete it from the database without delete the underlying file entity?

1 Answers

DocumentContract.moveDocument() is only available since API 24. Hence, to support older versions you can use this library. It could help you to move and copy files like this:

val file: DocumentFile = // from tree URI
file.moveFileTo(context, targetFolder, callback)
file.copyFileTo(context, targetFolder, callback)

// For media
val media = MediaFile(context, mediaUri)
media.moveTo(context, targetFolder, callback)
media.copyTo(context, targetFolder, callback)

moveTo() uses DocumentContract.moveDocument() when possible, considering its fast performance.

Related