Android中的音频焦点需要管理,这是处理音频中断的重要方法之一。在android中,许多应用程序同时播放媒体,并且为了增加用户体验,音频中断得到处理。例如,如果应用程序正在播放音频,则突然有一个来话呼叫,则需要停止音频文件,并且在通话结束后,音频应从停止处继续播放。本文讨论了如何处理音频中断或如何在Android中实现音频焦点。请看以下图片,以了解将要讨论的内容。注意,我们将使用Java语言实现该项目。
实施音频焦点或处理音频中断的步骤
步骤1:创建一个空的活动项目
- 创建一个空的活动Android Studio项目。并选择Java作为编程语言。
- 要了解如何创建一个空的活动Android Studio项目,请参阅Android |如何在Android Studio中创建/启动新项目?
步骤2:使用activity_main.xml文件
- 该项目的主要布局仅包含三个按钮,这些按钮用于播放,暂停和停止在应用程序中播放音频文件。
- 调用以下代码以实现UI。
XML
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();
}
}
});
}
}
输出界面:
步骤3:使用MainActivity。 Java文件
- 当音频焦点发生变化时,需要实现主要的回调。意味着系统已将音频焦点转移到该应用程序使用的另一服务,在这种情况下,是Phone应用程序,该应用程序从正在播放音频的当前应用程序获取音频焦点。
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.
- 挂断电话后,焦点将更改为当前应用程序,并恢复MediaPlayer。
- 将Android系统返回的焦点请求结果与以下常量进行比较。
- 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).
- 要在与上述相同的应用程序中实现音频焦点,请在MainActivity中调用以下代码。 Java文件。添加了注释以便更好地理解。
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.