I'm trying to insert audio file to shared storage in Android. I'm getting error on api 29(emulator).
Error :
java.lang.IllegalArgumentException: Primary directory (invalid) not allowed for content://media/external_primary/audio/media; allowed directories are [Alarms, Music, Notifications, Podcasts, Ringtones]
My Code is:
...
Uri collection = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
? MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
: MediaStore.Audio.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
values = new ContentValues();
values.put(MediaStore.Audio.Media.DISPLAY_NAME, targetFileName);
values.put(MediaStore.Audio.Media.RELATIVE_PATH, targetFileDirPath);
values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg");
values.put(MediaStore.Audio.Media.IS_PENDING, 1);
resolver = getContentResolver();
uri = resolver.insert(collection, values); // error throws from here
outputStream = uri != null ? resolver.openOutputStream(uri) : null;
...
What is the cause of this error and how can I solve this problem?
Apparently, MediaStore.Audio.Media.getContentUri()
does not return a directly-usable Uri
, at least on Android 10+. It points to an abstract location for "audio", but you cannot write content directly to that Uri
. Instead, you need to use RELATIVE_PATH
to specify one of the supported collections (Alarms
, Music
, Notifications
, Podcasts
, Ringtones
), and then any path that you want inside of there.
Note, though, that RELATIVE_PATH
itself is new to Android 10. For Android 9 and older devices, I recommend just writing to the filesystem directly.