How to set Audio Focus ChangeListener in Android API O?

前端 未结 5 2060
暗喜
暗喜 2021-02-15 20:29

Since requestAudioFocus(AudioManager.OnAudioFocusChangeListener l, int streamType, int durationHint) is deprecated in API O , how do you set audio focus change list

相关标签:
5条回答
  • 2021-02-15 20:50

    Try to use setOnAudioFocusChangeListener()

    0 讨论(0)
  • 2021-02-15 20:53

    What I have founded in official docs:

    Explicit requests for audio focus: Your service can submit a more fine-grained request for receiving device-wide audio focus by using the requestAudioFocus() method. Pass in an AudioFocusRequest object, which you create using AudioFocusRequest.Builder. In this builder class, you can specify the following options:

    The type of focus you wish to gain, such as AUDIOFOCUS_GAIN_TRANSIENT or AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK. Whether your service should continue more quietly or pause completely when another audio service takes over device focus. Whether your service can wait to gain focus until the device is ready.

    Note: When building your instance of AudioFocusRequest, if you indicate that your service can wait to produce sound by calling setAcceptsDelayedFocusGain(), you must also call setOnAudioFocusChangeListener() so that your service knows when it can begin producing sound.

    As @kelebro63 mentioned the following example shows how to use an AudioFocusRequest.Builder to build an AudioFocusRequest and request and abandon audio focus:

    mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
    mPlaybackAttributes = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .build();
    mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
            .setAudioAttributes(mPlaybackAttributes)
            .setAcceptsDelayedFocusGain(true)
            .setOnAudioFocusChangeListener(mMyFocusListener, mMyHandler)
            .build();
    mMediaPlayer = new MediaPlayer();
    final Object mFocusLock = new Object();
    
    boolean mPlaybackDelayed = false;
    boolean mPlaybackNowAuthorized = false;
    
    // ...
    int res = mAudioManager.requestAudioFocus(mFocusRequest);
    synchronized(mFocusLock) {
        if (res == AUDIOFOCUS_REQUEST_FAILED) {
            mPlaybackNowAuthorized = false;
        } else if (res == AUDIOFOCUS_REQUEST_GRANTED) {
            mPlaybackNowAuthorized = true;
            playbackNow();
        } else if (res == AUDIOFOCUS_REQUEST_DELAYED) {
           mPlaybackDelayed = true;
           mPlaybackNowAuthorized = false;
        }
    }
    
    // ...
    @Override
    public void onAudioFocusChange(int focusChange) {
        switch (focusChange) {
            case AudioManager.AUDIOFOCUS_GAIN:
                if (mPlaybackDelayed || mResumeOnFocusGain) {
                    synchronized(mFocusLock) {
                        mPlaybackDelayed = false;
                        mResumeOnFocusGain = false;
                    }
                    playbackNow();
                } 
                break;
            case AudioManager.AUDIOFOCUS_LOSS:
                synchronized(mFocusLock) {
                    mResumeOnFocusGain = false;
                    mPlaybackDelayed = false;
                }
                pausePlayback();
                break;
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                synchronized(mFocusLock) {
                    mResumeOnFocusGain = true;
                    mPlaybackDelayed = false;
                }
                pausePlayback();
                break;
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                // ... pausing or ducking depends on your application
                break;
            }
        }
    }
    

    References:

    Audio Focus Enhancements

    Android O Features and APIs

    0 讨论(0)
  • 2021-02-15 20:55

    To gain the focus use below (It will pause other player) :

     mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);       
     mAudioManager.requestAudioFocus(null,AudioManager.STREAM_MUSIC,AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
    

    To leave the focus use below (It will resume that player) :

       mAudioManager.abandonAudioFocus(null);
    
    0 讨论(0)
  • 2021-02-15 21:02

    Another option is to use AudiomanagerCompat together with AudioAttributesCompat and AudioRequestCompat, all part of Jetpack (androidx) compatibility libraries: https://developer.android.com/reference/androidx/media/AudioManagerCompat

    In this way, you can use the same code for Android O+ and also for previous versions (without conditional checks on the API version. But one of the drawbacks of this approach is that you can't use: .setAcceptsDelayedFocusGain(true)

    If you decide for this approach, then you have to use requestAudioFocus(mAudioManager, mFocusRequest) and abandonAudioFocusRequest(mAudioManager, mFocusRequest) to obtain and release audio focus.

    Partial sample code (in Kotlin): (Note: if you do not use Timber for logging, replace it by the standard Log function)

    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")
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-15 21:09

    https://developer.android.com/guide/topics/media-apps/audio-focusOfficial Link for the resource

     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);
        }
    
    0 讨论(0)
提交回复
热议问题