You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android API 29及以上版本中ContentResolver无法打开插入的音频文件问题求助

Android API 29及以上版本中ContentResolver无法打开插入的音频文件问题求助

各位好,我碰到了一个兼容性难题,想请大家帮忙排查下。我写的这段代码在API 28及以下版本都能正常运行,但到了API 29及以上就出问题了——我想把自定义音频设置为闹钟铃声,现在删除和插入操作看起来都执行成功了,但就是没法打开对应的文件,设置闹钟后也只会播放默认铃声。

先贴一下我的代码:

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);

我的文件绝对路径是:/storage/emulated/0/Android/data/some.package/files/Alarms/myFile.mp3

目前的情况是,delete和insert操作看起来都完成得很顺利,newUri.toString()的结果类似content://media/external_primary/audio/media/39。但之后只要尝试打开文件或者文件描述符(比如注释掉的那行代码),就会抛出这个异常:

java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)

另外,尝试设置这个文件为闹钟时,日志里会输出这些警告:

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

奇怪的是,操作并没有完全失败——闹钟应用里能看到我的文件名,但播放的却是默认的闹钟声音,看起来ContentResolver里确实插入了记录,但文件的引用好像是无效的。

有没有大佬知道我该怎么调整这段代码,才能让它在API 29及以上版本正常工作呢?

备注:内容来源于stack exchange,提问作者awa993

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 08:43:10