How to update metadata of audio file in Android Q media store?

Issue

Updating metadata of audio file in media store is not working in Android Q OS, it works in all other OS.

I am using content provider with uri specified as MediaStore.Audio.Media.EXTERNAL_CONTENT_URI. It is working fine in all below Android Q device. Below is the code that I am using to update track metadata.

ContentValues cv  new ContentValues();
ContentResolver resolver  getContentResolver();
Uri uri  MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

cv.put(MediaStore.Audio.Media.TITLE, newTitle);
cv.put(MediaStore.Audio.Media.ALBUM, newAlbumName);
cv.put(MediaStore.Audio.Media.ARTIST, newArtistName);

int rowsUpdated  resolver.update(uri, cv, 
MediaStore.Audio.Media._ID + "  ? ", new String[]{audioId});

For Android Q device, rowsUpdated is always 0 with no exception. How are other music player updating tracks metadata in Android Q ?

Solution

Finally, it took some time but I figured that out.

First, you need to obtain access to file. Here you can read about that

Next, I found out that to update title or artist fields (maybe others to, I didn’t test them) you need to set column MediaStore.Audio.Media.IS_PENDING value to 1. Like that:

    val id  //Your audio file id

    val values  ContentValues()
    values.put(MediaStore.Audio.Media.IS_PENDING, 1)

    val uri  ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id)
    contentResolver.update(uri, values, null, null)

And then you can edit fields that you need. Also to end the update process set MediaStore.Audio.Media.IS_PENDING to 0 again:

    val id  //Your audio file id
    val title  //New title
    val artist  //New artist

    val values  ContentValues()
    values.put(MediaStore.Audio.Media.IS_PENDING, 0)
    values.put(MediaStore.Audio.Media.TITLE, title)
    values.put(MediaStore.Audio.Media.ARTIST, artist)

    val uri  ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id)
    contentResolver.update(uri, values, null, null)

So in one function, it would look like this:

    @RequiresApi(value  android.os.Build.VERSION_CODES.Q)
    fun updateMetadata(contentResolver: ContentResolver, id: Long, title: String, artist: String) {
        val uri  ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id)
        val values  ContentValues()

        values.put(MediaStore.Audio.Media.IS_PENDING, 1)
        contentResolver.update(uri, values, null, null)

        values.clear()
        values.put(MediaStore.Audio.Media.IS_PENDING, 0)
        values.put(MediaStore.Audio.Media.TITLE, title)
        values.put(MediaStore.Audio.Media.ARTIST, artist)
        contentResolver.update(uri, values, null, null)
    }

It’s written in Kotlin but I think you will figure out how to do that in java.

UPDATE

By updating MediaStore you don’t updating real file at any android version. That means, if a file would be updated (for example: renamed) and/or scanned by MediaScannerConnection your changes will be lost. This answer is right.

Answered By – KingEnderBrine

Leave a Comment