The significance of audio focus management
Two or more Android applications can play audio to the same output stream simultaneously. The system mixes all the audio streams together. Although this is an excellent technology, it will cause great trouble to users. To avoid all music apps playing simultaneously, Android introduced the concept of "audio focus". Only one app can get audio focus at a time.
When your app needs to output audio, it needs to request to get the audio focus, and once it gets the focus, it can play the sound. However, after you get the audio focus, you may not be able to hold it until the playback is complete. Other apps can request focus, thus taking up the audio focus you hold. If this happens, your app should pause playback or lower the volume so that the user can hear the new audio source.
Code of conduct for audio focus management
- Call requestAudioFocus() before the playback is about to begin and verify that the call returns AUDIOFOCUS_REQUEST_GRANTED.
- When other applications gain audio focus, playback should be stopped or paused, or the volume should be lowered.
- Audio focus should be abandoned after playback is stopped
Version compatible
Starting from Android 8.0 (version O, API 26), there have been subtle changes in the request method of audio focus and system management. The following is explained in two parts.
Implementation of specific processing of audio focus before Android 8.0 (API 26)
When you want to record or play a song, it is best to request the audio focus (not necessary). At this time, you need to call the() method. The function prototype is as follows
(OnAudioFocusChangeListener l, int streamType, int durationHint)
The first parameter is used to monitor focus changes
The second parameter indicates that the requested audio focus affects the type of stream. For example, if we record, we must affect the audio stream of Music, so you can choose AudioManager.STREAM_MUSIC. Of course there are many types.
/** Call related */ public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL; /** System Sound */ public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM; /** Ringtone */ public static final int STREAM_RING = AudioSystem.STREAM_RING; /** Music related */ public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC; /** Alarm clock related */ public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
The third parameter is used to indicate the duration of the audio focus. This is very critical. It also has many types, listed below.
- AudioManager.AUDIOFOCUS_GAIN: The API document says that the duration of this type of audio focus requested is unknown, and is usually used to indicate that the focus is obtained for a long time, and can be used to play music, record, etc.
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: Indicates that the requested audio focus lasts for a short time and is usually used to play the sound of the navigation route or to play the notification sound.
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: This also indicates that the requested audio focus duration is relatively short, but during this time, it expects other applications to continue playing at lower volumes. For example, when we use navigation, we can listen to music. When navigation voice appears, the volume of the music will be lowered so that we can hear the navigation voice clearly. After the navigation voice is played, the music will return to the volume and continue to play.
- AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: This also indicates that the audio focus duration of the sound request is relatively short, but during this period, no application (including system applications) is expected to do anything related to audio, and even if the volume is lowered, it is not desirable. For example, when we record or voice recognition, we do not want other sounds to interfere.
The return value of () indicates the result of the request AudioManager.AUDIOFOCUS_REQUEST_FAILED indicates the request focus failed, and AudioManager.AUDIOFOCUS_REQUEST_GRANTED indicates the request focus was successful.
When we successfully request focus, we can do something related to audio, such as playing music, recording, or voice recognition. When these tasks are done, we have to call (onAudioFocusChangeListener l) to release the audio focus.
Implemented after 8.0
Starting with Android 8.0 (API 26), there are some subtle changes in the way audio focus is requested and the system's management of audio focus changes. First, the changes in the management of audio focus changes are reflected in two aspects: delaying focus acquisition and automatic volume reduction.
Delayed to get focus
Before Android 8.0, when we requested audio focus, we only returned two results, either the request was successful (AUDIOFOCUS_REQUEST_GRANTED) or the request failed (AUDIOFOCUS_REQUEST_FAILED).
Starting from Android 8.0, there is another result, delaying the successful request (AUDIOFOCUS_REQUEST_DELAYED), which is also a successful request, but this request is delayed. For example, when we are on a call, we obviously don't want any app to get audio focus to do something, such as playing music.
However, only by setting true can this result be obtained, which we will talk about later. So how do we know when the audio focus has been obtained? Of course, we also need to set up a monitor for the audio focus change to confirm when the audio focus has been obtained through callback.
Automatically lower the volume
Prior to Android 8.0, if the AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK parameter was used, it indicates that other applications that want to have audio focus to lower the volume to use audio, but not all applications will do this (probably the developer forgot to optimize), because this is not system-forced. But, starting from Android 8.0, this work of reducing volume is the system's default behavior, which can be said to be a conscientious optimization.
What if I don’t want the system to automatically lower the volume, but want to pause audio-related work by myself? This can cancel the system's default behavior by (true) method and then monitor the audio focus changes
Audio focus request method
Starting from Android 8.0 (API level 26), when you call requestAudioFocus(), the AudioFocusRequest parameter must be provided. To release audio focus, call the abandonAudioFocusRequest() method, which also accepts AudioFocusRequest as a parameter. The same AudioFocusRequest instance should be used when requesting and abandoning focus
To create an AudioFocusRequest, use . Since the focus request always has to specify the type of the request, this type is included in the constructor of the builder. Use the builder method to set other fields of the request
setFocusGain(): Only this method is necessary, and the passed parameters are the same as the third parameter passed in using() before 8.0, and are used to represent the duration.
setAudioAttributes(): This method is used to describe the usage of the app. This method requires passing in an AudioAttributes object, which is also constructed using the Builder mode. For example, using () to describe what to do with this audio. We can pass in an AudioAttributes.USAGE_MEDIA to indicate that this audio is used as a media file to play, or we can pass in an AudioAttributes.USAGE_ALARM to indicate that this is used as an alarm.
setWillPauseWhenDucked(): This is mentioned earlier to override the system's default volume reduction behavior, but it must be set to handle this situation yourself.
setAcceptsDelayedFocusGain(): As mentioned earlier, this is a necessary condition to delay the acquisition of focus, but it also needs to be set to know when to obtain focus.
setOnAudioFocusChangeListener(): Audio focus change listener. It is worth mentioning that this method has an overloaded method. There is an overloaded method with two parameters. The second parameter is a Handler object. When you see the Handler, you should understand that it is to use its message queue to process the callbacks in sequence.
Respond to audio focus changes
When an app gets the audio focus, it must be able to release the focus when other apps request the audio focus for itself. When this happens, your application receives a call to the onAudioFocusChange() method in AudioFocusChangeListener, which is specified when you call requestAudioFocus().
The focusChange parameter passed to onAudioFocusChange() represents the type of change that occurred. It corresponds to the duration prompt used by the application that gets the focus. Your application should respond appropriately
Temporarily losing focus
If the focus change is temporary (AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK or AUDIOFOCUS_LOSS_TRANSIENT), your app should lower the volume (if you do not depend onAutomatically lower the volume) or pause playback, otherwise it remains the same.
When temporarily losing audio focus, you should continue to monitor the changes in the audio focus and be ready to resume normal playback after regaining the focus. When the focus-taking app abandons focus, you receive a callback (AUDIOFOCUS_GAIN). At this point, you can return the volume to normal level or restart playback.
Permanent loss of focus
If the audio focus is permanently lost (AUDIOFOCUS_LOSS), other applications will play the audio. Your app should pause playback immediately because it will not receive the AUDIOFOCUS_GAIN callback. To restart playback, the user must perform explicit actions, such as pressing the play transfer control in the notification or application interface.
With basic audio knowledge
Sampling and sampling frequency:The number of times you sample in one second is called the sampling frequency. The higher the sampling frequency, the closer it is to the original signal, but it also increases the complexity of the calculation processing. According to the Nyquist sampling theorem, in order to reconstruct the original signal, the sampling frequency must be twice the highest frequency in the signal. The frequency range that people can feel is 20HZ-20kHZ. The sampling frequency of general music is 44.1kHZ, and the higher ones can be 48kHZ and 96kHZ. However, most people feel that there is no difference when listening to it with their ears. Voice is mainly about communication and does not need to be as clear as music. Voice sampled by 16k is called high-definition voice. The mainstream voice sampling frequency is now 16kHz.
Number of sample bits:Digital signals are represented by 0 and 1. The number of sample bits is how many bits the sample value is represented by 0 and 1, which is also called sampling accuracy. The more bits you use, the closer you are to the real sound. If expressed in 8 bits, the sample value range is -128--127. If expressed in 16 bits, the sample value range is -32768--32767. Nowadays, 16-bit sample bits are generally used.
Saying:A channel refers to whether the processed sound is mono or stereo. Android supports two-channel stereo and mono. CHANNEL_IN_MONO Mono, CHANNEL_IN_STEREO Stereo. Mono only has a single data stream during sound processing, while stereo requires two data streams of the left and right channels. Obviously, stereo sound is better, but the corresponding data volume is doubled compared to the mono data volume.
Bit rate:It's the bit rate. The bit rate refers to the number of bits transmitted per second. Bit rate = sampling rate X number of sample bits X number of channels.
Audio acquisition and playback:Generally, special chips (usually called codec chips) are used to collect audio, perform AD conversion, and then digital signals are sent to the CPU through the I2S bus (mainstream I2S bus, or other buses, such as PCM bus) (some will also integrate codec chips and CPU chips into one chip). When playing, the CPU will send the audio digital signal to the codec chip through the I2S bus, and then perform DA conversion to obtain the analog signal and then play it out.
Summarize
This is all about this article about Android audio focus management. For more related content on Android audio focus management, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!