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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:55:23