问题场景:有线耳机或者蓝牙耳机断开,此时音乐播放就会自动暂停,接下来分析下代码流程。
基于Android P MTK的代码
该场景注意使用的主要有一个系统广播:
android.media.AUDIO_BECOMING_NOISY
frameworks/base/media/java/android/media/AudioManager.java
/**
* Broadcast intent, a hint for applications that audio is about to become
* 'noisy' due to a change in audio outputs. For example, this intent may
* be sent when a wired headset is unplugged, or when an A2DP audio
* sink is disconnected, and the audio system is about to automatically
* switch audio route to the speaker. Applications that are controlling
* audio streams may consider pausing, reducing volume or some other action
* on receipt of this intent so as not to surprise the user with audio
* from the speaker.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
发送该广播的位置:
frameworks/base/services/core/java/com/android/server/audio/AudioService.java
/**
* Receiver for misc intent broadcasts the Phone app cares about.
*/
private class AudioServiceBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
...
} else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
if (mUserSwitchedReceived) {
// attempt to stop music playback for background user except on first user
// 接收到 ACTION_USER_SWITCHED 广播时,发送 Msg
// switch (i.e. first boot)
sendMsg(mAudioHandler,
MSG_BROADCAST_AUDIO_BECOMING_NOISY,
SENDMSG_REPLACE,
0,
0,
null,
0);
}
mUserSwitchedReceived = true;
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
...
//使用handler机制发送广播
case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
onSendBecomingNoisyIntent();
break;
//这里发送广播
private void onSendBecomingNoisyIntent() {
sendBroadcastToAll(new Intent(AudioManager.ACTION_AUDIO_BECOMING_NOISY));
}
接收该广播的位置:(已系统Music为例,也可能是自己的应用)
监听此广播的地方就可以暂停音乐的播放。
packages/apps/Music/src/com/android/music/utils/Playback.java
private IntentFilter mAudioNoisyIntentFilter =
new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
private BroadcastReceiver mAudioNoisyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
Log.d(TAG, "Headphones disconnected.");
if (isPlaying()) {
Intent i = new Intent(context, MediaPlaybackService.class);
i.setAction(MediaPlaybackService.ACTION_CMD);
i.putExtra(MediaPlaybackService.CMD_NAME, MediaPlaybackService.CMD_PAUSE);
mService.startService(i); // 这里执行暂停
}
}
}
};