Open In App

How to Manage Audio Focus in Android?

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. 



Steps to Implement the Audio Focus or handle Audio interruptions

Step 1: Create an empty activity project

Step 2: Working with the activity_main.xml file






<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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

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.

  1. AUDIOFOCUS_GAIN: if the system grants the audio focus gain, then the playback can be continued after the temporary loss of the audio focus.
  2. AUDIOFOCUS_LOSS_TRANSIENT: if there is temporary loss of audio focus then the playback of the audio should be paused.
  3. AUDIOFOCUS_LOSS: if there is permanent loss of the audio then the mediaplayer should be released (completely stopped).




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.

Output: Run on Emulator


Article Tags :