如何在Android API O中设置Audio Focus ChangeListener?

2022-09-04 07:22:16

由于在API O中已弃用,如何使用AudioFocusRequest设置音频焦点更改监听器requestAudioFocus(AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint)


答案 1

https://developer.android.com/guide/topics/media-apps/audio-focus资源的官方链接

 AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);


    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        mAudioManager.requestAudioFocus(new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                .setAudioAttributes(
                        new AudioAttributes.Builder()
                                .setUsage(AudioAttributes.USAGE_GAME)
                                .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                                .build()
                )
                .setAcceptsDelayedFocusGain(true)
                .setOnAudioFocusChangeListener(new AudioManager.OnAudioFocusChangeListener() {
                    @Override
                    public void onAudioFocusChange(int focusChange) {
                       //Handle Focus Change 
                    }
                }).build()
        );
    } else {

        mAudioManager.requestAudioFocus(focusChange -> {

                   //Handle Focus Change for earliest version of oreo
                },
                AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);
    }

答案 2

另一种选择是将AudiomanagerCompat与AudioAttributesCompat和AudioRequestCompat一起使用,所有这些都是Jetpack(androidx)兼容性库的一部分:https://developer.android.com/reference/androidx/media/AudioManagerCompat

通过这种方式,您可以对Android O +和以前的版本使用相同的代码(无需对API版本进行条件检查)。但这种方法的缺点之一是你不能使用:.setAcceptsDelayedFocusGain(true)

如果您决定采用这种方法,那么您必须使用 requestAudioFocus(mAudioManager,mFocusRequest)和 abandonAudioFocusRequest(mAudioManager,mFocusRequest)来获取和释放音频焦点。

部分示例代码(在 Kotlin 中):(注意:如果您不使用 Timber 进行日志记录,请将其替换为标准 Log 函数)

class MyClass : AudioManager.OnAudioFocusChangeListener {

    internal var audioManager: AudioManager? = null
    private var focusRequest: AudioFocusRequestCompat? = null
    private var playbackAttributes : AudioAttributesCompat? = null

    // Create AudioManager and other audio related objects
    audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager?
    playbackAttributes = AudioAttributesCompat.Builder()
                .setUsage(AudioAttributesCompat.USAGE_MEDIA)
                .setContentType(AudioAttributesCompat.CONTENT_TYPE_SPEECH)
                .build()

    focusRequest = AudioFocusRequestCompat.Builder(AudioManagerCompat.AUDIOFOCUS_GAIN)
                .setAudioAttributes(playbackAttributes ?: return)
                .setWillPauseWhenDucked(false)
                .setOnAudioFocusChangeListener(this)
                .build()

    // Request audio focus and check if it was granted to us
    if (requestAudioFocus(audioManager!!, focusRequest!!) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
         // We obtained audio focus

    }
    else {
        // We could not obtain audio focus

    }

    // And to remove audio focus
    if (audioManager != null && focusRequest != null)
            abandonAudioFocusRequest(audioManager!!, focusRequest!!)



    // Implementation of OnAudioFocusChangeListener
    override fun onAudioFocusChange(focusState: Int) {

        // Invoked when the audio focus of the system is updated.
        when (focusState) {
            AudioManager.AUDIOFOCUS_GAIN -> {
                // We recovered audio focus.
                Timber.d("Audio Focus obtained")
            }
            AudioManager.AUDIOFOCUS_LOSS -> {
                // Lost focus for an unbounded amount of time
                Timber.d("Audio Focus lost")
            }
            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
                // Lost focus for a short time, but it's ok to keep playing at an attenuated level
                Timber.d("Audio Focus transient loss - can duck")
            }
            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
                // Lost focus for a short time
                Timber.d("Audio Focus transient loss - cannot duck")
            }
        }
    }
}

推荐