MediaPlayer setDataSource 失败,status=0x80000000 for defaultUri

MediaPlayer setDataSource failed with status=0x80000000 for defaultUri

我有一个 RingTone class 我用来播放设备的铃声,一次或循环播放。

class RingTone(context: Context) {

    private val player = MediaPlayer()
    private val audioManager: AudioManager

    init {
        val alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
        player.setDataSource(context, alert) // this line may crash

        audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    }

   fun play(isLooping: Boolean = true): RingTone {
        if (audioManager.getStreamVolume(AudioManager.STREAM_RING) != 0) {
            val attributes = AudioAttributes.Builder()
                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                    .setUsage(AudioAttributes.USAGE_NOTIFICATION)
                    .build()

            player.setAudioAttributes(attributes)
            player.isLooping = isLooping
            player.prepare()
            player.start()
        }
        return this
    }
}

这在我正在测试的设备上运行良好,但我们 运行 遇到了一个问题,即我们的其中一台设备在尝试 setDataSource 时会 100% 崩溃。

我们有多个相同的设备,全部 运行 Android 5.1.

异常:

Caused by java.io.IOException: setDataSource failed.: status=0x80000000
       at android.media.MediaPlayer.nativeSetDataSource(MediaPlayer.java)
       at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1090)
       at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1079)
       at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1032)
       at android.media.MediaPlayer.setDataSource(MediaPlayer.java:968)
       at com.xxxx.yyy.RingTone.<init>(RingTone.kt:21)

如何重现此崩溃并解决问题?

感谢您的宝贵时间。

我能够通过使用允许我将铃声设置为 "NONE" 的另一台设备重现此问题。虽然这在有问题的设备上是不可能的,但我认为这就是问题所在。

现在,要处理这种情况,您似乎必须做一个 try/catch,因为在尝试之前没有任何东西可以检查源是否有效。

    initialized = try {
        player.setDataSource(context, alert)
        true
    } catch (ex: IOException) {
        false
    }

然后在play.

   fun play(isLooping: Boolean = true): RingTone {
        if (initialized && audioManager.getStreamVolume(AudioManager.STREAM_RING) != 0) {
              ...
        }
        return this
    }