ContentResolver - can't open inserted file on Android API 29+

82 Views Asked by At

Here's my code. It works as expected on API level 28 and below, but not on 29 and higher.

ContentResolver contentResolver = getContentResolver();
ContentValues values = new ContentValues();
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) {
    values.put(MediaStore.Audio.Media.DATA, myFile.getAbsolutePath());
} else {
    values.put(MediaStore.Audio.Media.RELATIVE_PATH, "Alarms/" + myFile.getName());
}
values.put(MediaStore.Audio.Media.DISPLAY_NAME, myFile.getName());
values.put(MediaStore.Audio.Media.TITLE, myFile.getName());
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
    values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
} else {
    values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg");
}
values.put(MediaStore.Audio.Media.SIZE, myFile.length());
values.put(MediaStore.Audio.Media.ARTIST, R.string.app_name);
values.put(MediaStore.Audio.Media.IS_RINGTONE, false);
values.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
values.put(MediaStore.Audio.Media.IS_ALARM, true);
values.put(MediaStore.Audio.Media.IS_MUSIC, false);

Uri uri = MediaStore.Audio.Media.getContentUriForPath(myFile.getAbsolutePath());
int cnt = contentResolver.delete(uri, MediaStore.Audio.Media.DISPLAY_NAME + " = ?", new String[]{myFile.getName()});

Uri newUri = contentResolver.insert(uri, values);
//contentResolver.openFileDescriptor(newUri, "r");
RingtoneManager.setActualDefaultRingtoneUri(getApplicationContext(), TYPE_ALARM, newUri);

Absolute path of my file is: /storage/emulated/0/Android/data/some.package/files/Alarms/myFile.mp3

Both delete and insert seem to finish correctly. Value of newUri#toString is something like: content://media/external_primary/audio/media/39

Any attempt thereafter to open the file/descriptor (e.g. commented line) fails on this exception: java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)

An attempt to set this file as alarm logs this:

W  Failed to open directly; attempting failover: java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
W  Failed to cache ringtone: java.io.IOException: java.lang.SecurityException: Uri is not ringtone, alarm, or notification: content://0@media/external_primary/audio/media/39

(It doesn't actually fail & in Alarm application I see name of my file, but the played alarm sound is some default alarm sound, not my sound. Almost looks like as if values get inserted into contentResolver correctly, but reference to my file is somehow invalid.)

How do I adjust this code to make it work on API level 29+?

0

There are 0 best solutions below