Android中如何获取铃声的绝对文件路径(适配全API)
通过RingtoneManager的URI获取铃声绝对路径(适配全API)
不存在能一刀切适配所有Android API的单一方法,但可以通过分版本兼容的逻辑实现,同时也有更简便的替代方案满足你的需求:
一、分版本路径获取方案
1. API 29+(Android 10及以上)
受Scoped Storage限制,直接获取绝对路径的逻辑被限制,可通过MediaStore查询拼接路径,或复制文件到应用私有目录:
- 查询拼接方式(仅适用于外部存储的铃声):
fun getRingtonePath(context: Context, uri: Uri): String? { val projection = arrayOf(MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.RELATIVE_PATH) context.contentResolver.query(uri, projection, null, null, null)?.use { cursor -> if (cursor.moveToFirst()) { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val relativePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.RELATIVE_PATH)) Environment.getExternalStorageDirectory().absolutePath + "/" + relativePath } else { cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)) } } } return null }
- 复制到私有目录(适配所有铃声,包括系统铃声):
fun copyRingtoneToPrivateDir(context: Context, uri: Uri): String? { return try { context.contentResolver.openInputStream(uri)?.use { input -> val tempFile = File(context.filesDir, "temp_ringtone") FileOutputStream(tempFile).use { output -> input.copyTo(output) } tempFile.absolutePath } } catch (e: IOException) { e.printStackTrace() null } }
2. API 28及以下
直接通过MediaStore.MediaColumns.DATA字段即可获取绝对路径,上述第一段代码已包含该逻辑。
二、更简便的无循环播放方案
其实你不需要刻意获取绝对路径,直接用RingtoneManager拿到的Uri就能实现MediaPlayer无循环播放,适配所有API:
MediaPlayer mediaPlayer = MediaPlayer.create(context, ringtoneUri); mediaPlayer.setLooping(false); mediaPlayer.start();
内容的提问来源于stack exchange,提问作者Aleksandr Kozlovskiy
相关产品推荐
相关产品推荐

