Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.IllegalArgumentException Volume external_primary not found in Android 10 devices

Crash : java.lang.IllegalArgumentException Volume external_primary not found

When querying for tracks from media store, I am getting this crash in some Android 10 devices (Most of them are from Xiaomi Mi A2 Lite, Motorola, HMD Global Nokia).

Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);

Should I be passing a different URI for Android 10 devices ?. (However it is working fine in most of the devices )

Stack trace :

Caused by java.lang.IllegalArgumentException: Volume external_primary not found
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:170)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:140)
at android.content.ContentProviderProxy.query(ContentProviderProxy.java:423)
at android.content.ContentResolver.query(ContentResolver.java:946)
at android.content.ContentResolver.query(ContentResolver.java:881)
at android.content.ContentResolver.query(ContentResolver.java:837)
at com.example.musicplayer.CursorFactory.getAllSongsCursor(CursorFactory.java:164)

Edit : Based on this issue reported, Suspect it could be an issue with sdcard in those devices with Android 10 OS.

like image 944
Velu Avatar asked Jul 27 '20 08:07

Velu


Video Answer


2 Answers

Post Android 10, API 28, there are some changes when accessing the media content from other sources.

Google mentioned it in this link https://developer.android.com/training/data-storage/shared/media#storage-volume

You can get more information on how to resolve this issue with more information given by google with the below code:

// Add a specific media item.
ContentResolver resolver = getApplicationContext()
        .getContentResolver();

// Find all audio files on the primary external storage device.
// On API <= 28, use VOLUME_EXTERNAL instead.
Uri audioCollection = MediaStore.Audio.Media.getContentUri(
        MediaStore.VOLUME_EXTERNAL_PRIMARY);

// Publish a new song.
ContentValues newSongDetails = new ContentValues();
newSongDetails.put(MediaStore.Audio.Media.DISPLAY_NAME,
        "My Song.mp3");

// Keeps a handle to the new song's URI in case we need to modify it
// later.
Uri myFavoriteSongUri = resolver
        .insert(audioCollection, newSongDetails);

Hope this works for you!

like image 78
Siraj Sumra Avatar answered Oct 02 '22 22:10

Siraj Sumra


Google added a thing called Scoped Storage which changes the File operation a bit. so you should use VOLUME_EXTERNAL/VOLUME_EXTERNAL_PRIMARY instead of EXTERNAL_CONTENT_URI

val uri =
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL)
        } else {
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI
        }

Going with VOLUME_EXTERNAL/VOLUME_EXTERNAL_PRIMARY is the right direction but there is a really rare case that the user stores their audio file on SD card but the phone doesn't recognize it which leads to the crash. This is a device error and there is nothing you can do about it.

From the doc of https://developer.android.com/reference/android/provider/MediaStore#VOLUME_EXTERNAL_PRIMARY

you could use getExternalVolumeNames to check is there any external storage available before making the query.

https://developer.android.com/reference/android/provider/MediaStore#getExternalVolumeNames(android.content.Context)

like image 36
Harvey Avatar answered Oct 02 '22 22:10

Harvey