Open In App

How to Manage Audio Focus in Android?

Improve
Improve
Like Article
Like
Save
Share
Report

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. 

Audio Focus in Android

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

  • 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: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:

Audio Focus in Android

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.
  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).
  • 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.

Output: Run on Emulator



Last Updated : 19 Jul, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads