How to Manage Audio Focus in Android?

14 Dec, 2020
The audio focus in Android needs to be managed and it is one of the important to handle the audio interruptions. In android, many applications play media simultaneously, and to increase the User Experience the Audio interruptions are handled. For example, if the application is playing Audio, suddenly there is an incoming call then the audio file needs to be stopped and after the call is ended the Audio should continue playing from where it has stopped. In this article, it’s been discussed how to handle the Audio interruptions or how to implement the Audio Focus in Android. Have a look at the following image to get an idea of what things are going to be discussed. Note that we are going to implement this project using the Java language. 
Step 1: Create an empty activity project
Create an empty activity Android Studio project. And select Java as a programming language.
To know how to create an empty activity Android Studio project refer to Android | How to Create/Start a New Project in Android Studio?
Step 2: Working with the activity_main.xml file
The main layout in this project includes only three buttons which are used to play, pause, and to stop the Audio file playing in the application.
Invoke the following code to implement the UI.
XML
<?xml version="1.0" encoding="utf-8"?><RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity"    tools:ignore="HardcodedText">      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_marginStart="16dp"        android:layout_marginTop="32dp"        android:layout_marginEnd="16dp"        android:text="Manage Audio Focus (Handling Audio interruptions in Android"        android:textSize="18sp"        android:textStyle="bold" />      <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginTop="100dp"        android:gravity="center_horizontal"        android:orientation="horizontal">          <Button            android:id="@+id/stopButton"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginEnd="32dp"            android:backgroundTint="@color/colorPrimary"            android:drawableStart="@drawable/ic_stop"            android:text="STOP"            android:textColor="@android:color/white" />          <Button            android:id="@+id/playButton"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginEnd="32dp"            android:backgroundTint="@color/colorPrimary"            android:drawableStart="@drawable/ic_play"            android:text="PLAY"            android:textColor="@android:color/white" />          <Button            android:id="@+id/pasueButton"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:backgroundTint="@color/colorPrimary"            android:drawableStart="@drawable/ic_pause"            android:text="PAUSE"            android:textColor="@android:color/white" />      </LinearLayout>  </RelativeLayout>
Output UI:
Step 3: Working with the MainActivity.java file
The main Callback needs to implemented when there is a change in the Audio focus. Meaning the system has transferred the audio focus to another service that is used by the app, in this case, the Phone application which takes the audio focus from the current application which is playing the audio.
AudioManager.OnAudioFocusChangeListener audioFocusChangeListener -> This handles if there is change in the audio focus which the callback need to implemented according to the focus change from the audio manage.
When the call gets hanged up the focus changes to the current application and MediaPlayer is resumed.
The focus request result which is returned by the Android system is compared to the following constants.
AUDIOFOCUS_GAIN: if the system grants the audio focus gain, then the playback can be continued after the temporary loss of the audio focus.AUDIOFOCUS_LOSS_TRANSIENT: if there is temporary loss of audio focus then the playback of the audio should be paused.AUDIOFOCUS_LOSS: if there is permenant loss of the audio then the mediaplayer should be released (completely stopped).
AUDIOFOCUS_GAIN: if the system grants the audio focus gain, then the playback can be continued after the temporary loss of the audio focus.
AUDIOFOCUS_LOSS_TRANSIENT: if there is temporary loss of audio focus then the playback of the audio should be paused.
AUDIOFOCUS_LOSS: if there is permenant loss of the audio then the mediaplayer should be released (completely stopped).
To implement the Audio focus in the application same as discussed above invoke the following code in the MainActivity.java file. Comments are added for better understanding.
Java
import androidx.annotation.RequiresApi;import androidx.appcompat.app.AppCompatActivity;import android.content.Context;import android.media.AudioAttributes;import android.media.AudioFocusRequest;import android.media.AudioManager;import android.media.MediaPlayer;import android.os.Build;import android.os.Bundle;import android.view.View;import android.widget.Button;import java.io.IOException;  @RequiresApi(api = Build.VERSION_CODES.O)public class MainActivity extends AppCompatActivity {      // media player instance to playback       // the media file from the raw folder    MediaPlayer mediaPlayer;      // Audio manager instance to manage or       // handle the audio interruptions    AudioManager audioManager;      // Audio attributes instance to set the playback       // attributes for the media player instance    // these attributes specify what type of media is       // to be played and used to callback the audioFocusChangeListener    AudioAttributes playbackAttributes;      // media player is handled according to the       // change in the focus which Android system grants for    AudioManager.OnAudioFocusChangeListener audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {        @Override        public void onAudioFocusChange(int focusChange) {            if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {                mediaPlayer.start();            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {                mediaPlayer.pause();                mediaPlayer.seekTo(0);            } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {                mediaPlayer.release();            }        }    };      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);          // get the audio system service for           // the audioManger instance        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);          // initiate the audio playback attributes        playbackAttributes = new AudioAttributes.Builder()                .setUsage(AudioAttributes.USAGE_GAME)                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)                .build();          // set the playback attributes for the focus requester        AudioFocusRequest focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)                .setAudioAttributes(playbackAttributes)                .setAcceptsDelayedFocusGain(true)                .setOnAudioFocusChangeListener(audioFocusChangeListener)                .build();          // request the audio focus and          // store it in the int variable        final int audioFocusRequest = audioManager.requestAudioFocus(focusRequest);          // register all three buttons        Button bPlay = findViewById(R.id.playButton);        Button bPause = findViewById(R.id.pasueButton);        Button bStop = findViewById(R.id.stopButton);          // initiate the media player instance with          // the media file from the raw folder        mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.music);          // handle the PLAY button to play the audio        bPlay.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // request the audio focus by the Android system                  // if the system grants the permission                // then start playing the audio file                if (audioFocusRequest == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {                    mediaPlayer.start();                }            }        });          // handle the PAUSE button to pause the media player        bPause.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mediaPlayer.pause();            }        });          // handle the STOP button to stop the media player        bStop.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                mediaPlayer.stop();                  try {                    // if the mediaplayer is stopped then                      // it should be again prepared for                    // next instance of play                    mediaPlayer.prepare();                } catch (IOException e) {                    e.printStackTrace();                }            }        });      }}
Note: When there is no requirement of audio focus, abandonAudioFocusRequest method needs to be called with the AudioManager instance and it requires the parameter AudioFocusRequest focusRequest which needs to be passed.
android
Technical Scripter 2020
Android
Java
Technical Scripter
Java
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.