简体   繁体   English

MediaPlayer - setAudioAttributes 无法正常工作

[英]MediaPlayer - setAudioAttributes not working properly

I'm trying to create an alarm, everything is working fine but the stream type is always media even tho I use STREAM_ALARM , since setStreamType is deprecated, I'm using setAudioAttributes instead but it doesn't seem to work.我正在尝试创建警报,一切正常,但即使我使用STREAM_ALARM流类型始终是媒体,因为setStreamType已被弃用,我正在使用setAudioAttributes但它似乎不起作用。 here's my code :这是我的代码:

class AlarmRingtoneManager(val context: Context) {

    private lateinit var mediaPlayer: MediaPlayer

    fun start() {
        mediaPlayer = MediaPlayer.create(context,  RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
           .apply {
              setAudioAttributes(AudioAttributes.Builder()
                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                .setLegacyStreamType(AudioManager.STREAM_ALARM)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build())
              isLooping = true
              start()
           }
    }

    fun stop() {
      mediaPlayer.stop()
    }
}

The problem is that you are creating the MediaPlayer using the method MediaPlayer.create() , and it is not possible to change the AudioAttributes later if you do it like that.问题是您正在使用MediaPlayer.create()方法创建MediaPlayer ,如果您这样做,以后就不可能更改AudioAttributes

From the documentation :文档

Convenience method to create a MediaPlayer for a given resource id.为给定资源 ID 创建 MediaPlayer 的便捷方法。 On success, prepare() will already have been called and must not be called again.成功后,prepare() 将已被调用,不得再次调用。

When done with the MediaPlayer, you should call release(), to free the resources.完成 MediaPlayer 后,您应该调用 release() 以释放资源。 If not released, too many MediaPlayer instances will result in an exception.如果不释放,过多的 MediaPlayer 实例会导致异常。

Note that since prepare() is called automatically in this method, you cannot change the audio session ID (see setAudioSessionId(int)) or audio attributes (see setAudioAttributes(android.media.AudioAttributes) of the new MediaPlayer.请注意,由于在此方法中会自动调用 prepare(),因此您无法更改新 MediaPlayer 的音频会话 ID(请参阅 setAudioSessionId(int))或音频属性(请参阅 setAudioAttributes(android.media.AudioAttributes))。

Instead of using create() , just instantiate the MediaPlayer using the default constructor new MediaPlayer();不使用create() ,只需使用默认构造函数new MediaPlayer();实例化MediaPlayer new MediaPlayer(); . . Then, set the source with the method setDataSource() and set the rest of the AudioAttributes as you were doing before.然后,使用setDataSource()方法设置源并像之前一样设置其余的 AudioAttributes。

I don't know about Kotlin, but in Java it would look something like this:我不知道 Kotlin,但在 Java 中它看起来像这样:

MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                .setLegacyStreamType(AudioManager.STREAM_ALARM)
                .setUsage(AudioAttributes.USAGE_ALARM)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build());
mediaPlayer.setDataSource(context, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM));
mediaPlayer.setLooping(true);
mediaPlayer.prepare();
mediaPlayer.start();

Kotlin version科特林版

    val uri = Settings.System.DEFAULT_ALARM_ALERT_URI ?: Settings.System.DEFAULT_RINGTONE_URI
    uri?.let {
        val player = MediaPlayer()
        player.setAudioAttributes(
                AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_ALARM)
                .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
                .build()
        )
        //player.reset() //uncomment this line if you use local variable of MediaPlayer
        player.setDataSource(this@AlarmActivity, it)
        player.prepare()
        player.start()
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM