11
votes

In Android Q the field MediaStore.Files.FileColumns.DATA has been deprecated, and may be Null or apps have no rights to read it when targeting such OS version, so will be preferable to work using only a file’s content Uri.

Since the MediaScannerConnection only accepts file paths, I found that for Android Q this is no longer an option.

What would be the way to force an automatic MediaStore update/re-scan of a single file, without knowing its real path and using only its Uri? The intention is not to even try to find the real path and rely only in the Uri.

Consider that the Uri to force the update is a media content Uri (not a SAF Uri).
Example: content://media/external/images/media/123

The solution must not be to re-scan the entire storage or un-mount / mount the storage again, as this will have a high performance hit in our workflow and will make it completely unusable.

And because the intention is to use only the Uri, then to avoid forcing a scan of any specific directory of files, which would also have an impact if it contains lots of files, and implies that a real directory path must be resolved from the Uri, which is not an option.

UPDATE:

We have tried with unsuccessful results the ContentResolver.refresh method introduced in Android O, yet this method doesn't do any refresh at all when it comes to a media content Uri in a format such as: content://media/external/images/media/123

final ContentResolver resolver = context.getContentResolver();
resolver.refresh(uri, null, null);
1

1 Answers

4
votes

I'm currently also trying to redesign my app to use just URIs rather than using all of the hacky solutions to convert them to filepaths (like guessing the path based on the uri authority, etc.) Previously, I used MediaScannerConnection.scanFile(...), which worked without a flaw, but as you've probably already tried, this doesn't work with URIs.

I am finding success by manually updating the MediaStore URI with my new data like this:

public void updateMediaStore(final Uri content, final String title) {
    final ContentValues values = new ContentValues();
    values.put(MediaStore.Audio.AudioColumns.TITLE, title);
    // ... the rest of your data
    cr.update(res, values, null, null);
}

Still, it seems like an oversight to not provide a way to rescan a specific file. For example, if this URI comes from somewhere else, such as on an sdcard via SAF, you will have to first search for it in the MediaStore before updating it.