Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't update MediaStore on Android 10

I've been updating meta data in the MediaStore through a ContentResolver, but this no longer works with Android Q (API 29). The following code gives me a warning, and the description is not updated:

ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DESCRIPTION, "Some text");

int res = getContext().getContentResolver().update(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        values,
        MediaStore.Images.Media._ID + "= ?", new String[]{sImageId});

android.process.media W/MediaProvider: Ignoring mutation of description from com.example.android.someapp.app

This Medium post describes how Google has changed the API for accessing and updating files, but what about updating just the meta data? The warning seems to tell me Google no longer wants to allow third party apps to use the MediaStore, and I also found where the warning comes from:  https://android.googlesource.com/platform/packages/providers/MediaProvider/+/master/src/com/android/providers/media/MediaProvider.java#2960

Does anyone know why the update is not working on Android 10, and what is the proper workaround?

like image 937
joakimk Avatar asked Feb 23 '20 20:02

joakimk


1 Answers

OK, with the help of joakimk, I found the problem.

To update an individual piece of content, you need to use a Uri that points to that individual piece of content:

    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.DESCRIPTION, text);

    Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imgId);

    int res = getContentResolver().update(uri, values, null, null);

This form of update() will throw a RecoverableSecurityException. You can catch that and raise a system dialog that should give you the permission to successfully update this content.

Basically, the logic that decides whether to throw a RecoverableSecurityException depends on the Uri itself having the ID of the content, rather than it being in a WHERE clause. A side effect of this is that you cannot modify more than one piece of content at a time, though the new Android R APIs for that may help.

I tested this on Android 10 and Android R DP1.

like image 60
CommonsWare Avatar answered Oct 23 '22 03:10

CommonsWare