android 测试 动态触发intent,Android中通过耳机按键控制音乐播放的实现

今天在研究Android中实现Android 4.2.2源码中的Music应用的源码,关于通过耳机按键控制音乐播放的实现,有点好奇,就仔细分析了一下源码,

主要由 MediaButtonIntentReceiver 这个类来实现。

在AndroidManifest.xml中有如下Receiver的注册:

其实关键是对这两个ACTION的监控:

android.intent.action.MEDIA_BUTTON的说明如下,从注释看,就是媒体按键被按下后,通过Intent.EXTRA_KEY_EVENT 中带上触发此事件的具体按钮事件:

/**

* Broadcast Action: The "Media Button" was pressed. Includes a single

* extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that

* caused the broadcast.

*/

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)

public static final String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON";

android.intent.action.AUDIO_BECOMING_NOISY的说明如下(自己翻译的,大概这个意思),

从注释看,当音频变得“吵闹”,比如耳机拔出,或者A2DP音频通道(比如通过蓝牙音箱播放音乐就是一种A2DP的应用场景)断开,

音频系统将会自动将音频转到自带的扬声器。收到此intent的控制音频的应用可以暂停,降低音量或其它操作,以防扬声器突然发出声音让用户受惊:

/**

* 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";

MediaButtonIntentReceiver 的关键实现如下:

public class MediaButtonIntentReceiver extends BroadcastReceiver

{

...

@Override

public void onReceive(Context context, Intent intent)

{

String intentAction = intent.getAction();

if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intentAction))

{

Intent i = new Intent(context, MediaPlaybackService.class);

i.setAction(MediaPlaybackService.SERVICECMD);

i.putExtra(MediaPlaybackService.CMDNAME,

MediaPlaybackService.CMDPAUSE);

context.startService(i);

}

else if (Intent.ACTION_MEDIA_BUTTON.equals(intentAction))

{

KeyEvent event = (KeyEvent) intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);

if (event == null)

{

return;

}

int keycode = event.getKeyCode();

int action = event.getAction();

long eventtime = event.getEventTime();

// single quick press: pause/resume.

// double press: next track

// long press: start auto-shuffle mode.

String command = null;

switch (keycode)

{

case KeyEvent.KEYCODE_MEDIA_STOP:

command = MediaPlaybackService.CMDSTOP;

break;

case KeyEvent.KEYCODE_HEADSETHOOK:

case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:

command = MediaPlaybackService.CMDTOGGLEPAUSE;

break;

case KeyEvent.KEYCODE_MEDIA_NEXT:

command = MediaPlaybackService.CMDNEXT;

break;

case KeyEvent.KEYCODE_MEDIA_PREVIOUS:

command = MediaPlaybackService.CMDPREVIOUS;

break;

case KeyEvent.KEYCODE_MEDIA_PAUSE:

command = MediaPlaybackService.CMDPAUSE;

break;

case KeyEvent.KEYCODE_MEDIA_PLAY:

command = MediaPlaybackService.CMDPLAY;

break;

}

通过接收此事件的广播,想进行什么操作,完全看你的业务需求了。

一开始以为耳机插拔,是通过ACTION_HEADSET_PLUG这个Action来控制,但Music并没有监听此事件,

/**

* Broadcast Action: Wired Headset plugged in or unplugged.

*

*

The intent will have the following extra values:

**

state - 0 for unplugged, 1 for plugged.

*

name - Headset type, human readable string

*

microphone - 1 if headset has a microphone, 0 otherwise

*

*

*/

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)

public static final String ACTION_HEADSET_PLUG =

"android.intent.action.HEADSET_PLUG"; 自己测试了一下,在AndroidManifest.xml中静态注册,是不会生效的,为啥?

一个很简单的解释,如果你的应用还没有运行,这时插入耳机,系统如何把这个消息给这个应用?

因此,"android.intent.action.HEADSET_PLUG"只能通过动态注册来接收此广播消息。

如果让 MediaButtonIntentReceiver 还接收"android.intent.action.HEADSET_PLUG"的广播消息,

则MediaButtonIntentReceiver会先收到"android.media.AUDIO_BECOMING_NOISY" 这个消息,然后才会收到"android.intent.action.HEADSET_PLUG"这个消息?

为什么这样,代码层面还没有分析,后面抽空再研究下Android源码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值