Focus acquisition and return of measured Android audio

Posted by Stray_Bullet on Wed, 09 Feb 2022 08:31:50 +0100

Focus acquisition and return of measured Android audio

preface

Recently, the boss wants to pause the music player in the mobile phone during the live broadcast of the short video in the product, and the mobile phone's music player can continue to play the previous music after exiting the video playback.

First try wechat, emmm. It's really OK.

Android official website: manage audio focus

Guidelines for managing audio focus on the official website:

  • Call requestAudioFocus() before you start playing and verify whether the call returns AUDIOFOCUS_. REQUEST_ GRANTED. If you design the application according to the instructions in this guide, you should call requestAudioFocus() in the callback of onPlay() in the media session.
  • When other apps get audio focus, stop or pause playback, or reduce the volume.
  • When playback stops, discard the audio focus.

Different versions of audio focus are handled differently:

  • Starting with Android 2.2 (API level 8), applications manage audio focus by calling requestAudioFocus() and abandonAudioFocus(). The application must also register AudioManager for these two calls Onaudiofofocuschangelistener to receive callbacks and manage your own volume.

  • For applications targeting Android 5.0 (API level 21) and higher, audio applications should use AudioAttributes to describe the type of audio the application is playing. For example, an application that plays voice should specify CONTENT_TYPE_SPEECH.

  • Applications for Android 8.0 (API level 26) or higher should use the requestAudioFocus() method, which will accept the AudioFocusRequest parameter. AudioFocusRequest contains information about the audio context and functions of the application. The system uses this information to automatically manage the gain and loss of audio focus.

API introduction

Audio focus is handled through AudioManager. The following is the method to obtain the instance of this class:
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);

requestAudioFocus() / / used to apply for audio focus
abandonAudioFocus() / / used to release audio focus
AudioManager. Onaudiofofocuschangelistener interface provides onaudiofofocuschange() method to monitor audio focus change

  • requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) parameter:

    • AudioManager.OnAudioFocusChangeListener l:
      It is used to monitor the change of audio focus, so that appropriate operations can be carried out, such as pause playback, etc.

    • streamType :
      The audio type for applying for audio focus processing. For example, when playing music, it can be passed into STREAM_MUSIC ; When playing a ringtone, you can pass in STREAM_RING . Some optional values are listed in the table:

      typemeaningvalue
      STREAM_VOICE_CALLconversation0
      STREAM_SYSTEMsystem1
      STREAM_RINGRinging tone2
      STREAM_MUSICmusic3
      STREAM_ALARMAlarm4
      STREAM_NOTIFICATIONSystem notification5
      .........
    • durationHint (PS: important parameter):
      There are five optional values:
      (1) AUDIOFOCUS_GAIN: this parameter indicates that you want to apply for a permanent audio focus, and you want the last App with audio focus to stop playing; For example, when you need to play music.
      (2) AUDIOFOCUS_ GAIN_ Transfer: it means to apply for a short audio focus and it will be released immediately. At this time, you want the last App with audio focus to pause playing. For example, play a reminder sound.
      (3) AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: the effect is the same as that of audioocus_ GAIN_ Transient, I just want the last App that held the focus to reduce its playback sound (but it can still be played), and it will be mixed and played at this time. For example, navigation broadcast.
      (4) AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: it means to apply for a short audio focus and hope that the system will not play any sudden sound (such as notification, reminder, etc.), such as the user is recording.

    • Return value:
      AUDIOFOCUS_ REQUEST_ Graded or audioocus_ REQUEST_ FAILED .

  • Audioandfocus manager parameter OnAudioFocusChangeListener .

  • AudioManager. Onaudiofofocuschangelistener: call back the onaudiofofocuschange (int focuschange) method when the audio focus changes;

new AudioManager.OnAudioFocusChangeListener() {
  @Override
  public void onAudioFocusChange(int focusChange) {
    switch (focusChange) {
      case AudioManager.AUDIOFOCUS_GAIN:
        // TBD continues playing
        break;
      case AudioManager.AUDIOFOCUS_LOSS:
        // TBD stop playing
        break;
      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
        // TBD pause playback
        break;
      case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
        // TBD mix playback 
        break;
      default:
        break;
    }
  }
};

Measured code:

The core is the need to put AudioManager AUDIOFOCUS_ Gain changed to AudioManager AUDIOFOCUS_ GAIN_ TRANSIENT

public class MainActivity extends Activity {

    private AudioManager mAudioManager;
    private AudioFocusRequest mFocusRequest;
    private AudioManager.OnAudioFocusChangeListener mListener;
    private AudioAttributes mAttribute;
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mListener = new AudioManager.OnAudioFocusChangeListener() {
            @Override
            public void onAudioFocusChange(int focusChange) {
                switch (focusChange) {
                    case AudioManager.AUDIOFOCUS_GAIN:
                       // TBD continues playing
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS:
                       // TBD stop playing
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                        // TBD pause playback
                        break;
                    case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                        // TBD mix playback 
                        break;
                    default:
                        break;
                }

            }
        };
        //android version 5.0
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mAttribute = new AudioAttributes.Builder()
                    .setUsage(AudioAttributes.USAGE_MEDIA)
                    .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                    .build();
        }
        //android version 8.0
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)
                    .setWillPauseWhenDucked(true)
                    .setAcceptsDelayedFocusGain(true)
                    .setOnAudioFocusChangeListener(mListener, mHandler)
                    .setAudioAttributes(mAttribute)
                    .build();
        }
    }
    private void requestAudioFocus() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
					mAudioManager.requestAudioFocus(mFocusRequest);
        } else {
          mAudioManager.requestAudioFocus(mListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
        }
    }
    private void abandonAudioFocus() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            mAudioManager.abandonAudioFocusRequest(mFocusRequest);
        } else {
          mAudioManager.abandonAudioFocus(mListener);
        }

    }
}

reference resources:

https://segmentfault.com/a/1190000022234509

https://www.jianshu.com/p/26ea60c499a7

This is the end of the article. If you need to communicate with others, you can leave a message ~! ~!

If you want to read more articles by the author, you can check me out Personal blog And public number:

Topics: Java Android