android发现之旅之媒体按键(耳机按键播放暂停键等)处理过程
android对媒体按键,比如上一首,下一首,播放,暂停,快进,快退等。当然,也包括耳机上的按键,拨打电话,接听电话,挂断电话等。本篇来讲述android如何传递媒体按键的。
1. 都有哪些媒体按键(PhoneWindowManager.java)
4167 case KeyEvent.KEYCODE_HEADSETHOOK:
4168 case KeyEvent.KEYCODE_MUTE:
4169 case KeyEvent.KEYCODE_MEDIA_STOP:
4170 case KeyEvent.KEYCODE_MEDIA_NEXT:
4171 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
4172 case KeyEvent.KEYCODE_MEDIA_REWIND:
4173 case KeyEvent.KEYCODE_MEDIA_RECORD:
4174 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
4175 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
2. 按键传递的发源地
(之前的流程,参考android按键处理)
PhoneWindowManager.java里接口dispatchUnhandledKey负责处理下层报过来的按键。调用interceptFallback。interceptFallback调用interceptKeyBeforeQueueing。
interceptKeyBeforeQueueing接口根据按键类型,做不同的处理,比如著名的power键也是在这处理的。这里只关注媒体按键,处理媒体按键,发送了一个消息给自己:
4182 mBroadcastWakeLock.acquire();
4183 Message msg = mHandler.obtainMessage(
MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK,
4184 new KeyEvent(event));
4185 msg.setAsynchronous(true);
4186 msg.sendToTarget();
后边用dispatchMediaKeyWithWakeLock处理这个消息,实际调用了dispatchMediaKeyWithWakeLockToAudioService接口,4309 void dispatchMediaKeyWithWakeLockToAudioService(KeyEvent event) {
4310 if (ActivityManagerNative.isSystemReady()) {
4311 IAudioService audioService = getAudioService();
4312 if (audioService != null) {
4313 try {
4314
audioService.dispatchMediaKeyEventUnderWakelock(event);
4315 } catch (RemoteException e) {
4316 Log.e(TAG, "dispatchMediaKeyEvent threw exception " + e);
4317 }
4318 }
调用了AudioService的dispatchMediaKeyEventUnderWakelock。
AudioService.java里dispatchMediaKeyEventUnderWakelock接口,调用了mMediaFocusControl.dispatchMediaKeyEventUnderWakelock。
MediaFocusControl.java的dispatchMediaKeyEventUnderWakelock接口调用了,filterMediaKeyEvent接口,处理媒体按键。
746 private void filterMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) { 747 // sanity check on the incoming key event
先判断是不是媒体按键。
748 if (!isValidMediaKeyEvent(keyEvent)) {
749 Log.e(TAG, "not dispatching invalid media key event " + keyEvent);
750 return;
751 }
如果有telephony相关的锁,优先处理把事件给telephony来处理。
752 // event filtering for telephony
753 synchronized(mRingingLock) {
754 synchronized(mRCStack) {
755 if ((mMediaReceiverForCalls != null) &&
756 (mIsRinging || (mAudioService.getMode() == AudioSystem.MODE_IN_CALL))) {
757 dispatchMediaKeyEventForCalls(keyEvent, needWakeLock);
758 return;
759 }
760 }
761 }
如果telephony没处理,先判断是不是语音按键,不是就调用dispatchMediaKeyEvent
762 // event filtering based on voice-based interactions
763 if (isValidVoiceInputKeyCode(keyEvent.getKeyCode())) {
764 filterVoiceInputKeyEvent(keyEvent, needWakeLock);
765 } else {
766 dispatchMediaKeyEvent(keyEvent, needWakeLock);
767 }
768 }
dispatchMediaKeyEvent接口,
先准备了一个Intent:
801 private void dispatchMediaKeyEvent(KeyEvent keyEvent, boolean needWakeLock) {
802 if (needWakeLock) {
803 mMediaEventWakeLock.acquire();
804 }
805 Intent keyIntent = new Intent(Intent. ACTION_MEDIA_BUTTON , null);
806 keyIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
之后判断是否有专门关注媒体按键的客户端,有就调用。
807 synchronized(mRCStack) {
808 if (!mRCStack.empty()) {
809 // send the intent that was registered by the client
810 try {
811 mRCStack.peek().
mMediaIntent.send(mContext,
812 needWakeLock ? WAKELOCK_RELEASE_ON_FINISHED : 0 /*code*/,
813 keyIntent, this, mEventHandler);
没有就广播了,这样大家都能收到了。
824 final long ident = Binder.clearCallingIdentity();
825 try {
826 mContext.
sendOrderedBroadcastAsUser(keyIntent,
UserHandle.ALL,
827 null, mKeyEventDone,
828 mEventHandler, Activity.RESULT_OK, null, null);
3. 理清AudioService里的几个接口
registerRemoteControlClient 注册远程控制客户端,所谓远程控制,实际上就是寄生的界面,同时用receiver处理媒体按键的一种播放形式,比如后台的音乐。
registerMediaButtonIntent注册媒体按键,用于获取和处理媒体按键。
registerMediaButtonEventReceiverForCalls注册通话媒体按键处理。
4. 场景举例
(1) 处理耳机按键
根据实现,我们知道,有2种方法:
--1-- 关心Intent.ACTION_MEDIA_BUTTON
--2-- 其实也是关心Intent.ACTION_MEDIA_BUTTON,不过更加复杂一点,用到:
MediaButtonEventReceiver。
(2) 如何阻止music应用在耳机按键按下后自动播放音乐
我们知道,music应用启动MediaPlaybackService后注册了一个RemoteControlClient以及MediaButtonEventReceiver。这就意味着,我们如果是关心Intent.ACTION_MEDIA_BUTTON的话,是拿不到耳机按键的,会被music应用截掉。
所以我们只能也注册一个MediaButtonEventReceiver了。
android发现之旅之媒体按键(耳机按键播放暂停键等)处理过程相关推荐
- 媒体控件的播放暂停继续与停止 winform
媒体控件的播放暂停继续与停止 winform 准备媒体 把媒体放在了一个路径 bin/debug,是项目资源的根目录 播放功能 暂停功能 继续播放 停止播放
- android求助:关于播放器中的“播放/暂停”键: 用ImageButton来设置点击效果时的问题...
============问题描述============ 大家好,我最近遇到个问题: 大家都知道,播放器中的播放/暂停键是这样的逻辑:当用户点击了这个键,如果当前显示的是"播放&quo ...
- Android耳机线控-播放/暂停/上一曲/下一曲
起因 前一阵子完成了用有线耳机控制Android手机App的音频播放,具体实现了用耳机线的按键完成播放.暂停.上一曲.下一曲的功能.在网上查阅了一些资料,但不是特别尽如人意,记得有一篇写的很不错的这方 ...
- android耳机上报流程,Android系统中耳机按键键值上报不正确 解决过程
[问题现象] 根据测试组同事反馈:在我们的设备上使用 JBL 品牌某款带有 3 个按键的有线耳机时,按下"音量+"键时设备会减小音量而不是增加音量,按下"音量-" ...
- android连接蓝牙控制音乐播放器播放暂停/上一曲/下一曲,且断开蓝牙暂停音乐
客户需求要蓝牙设备可以控制音乐播放器的暂停等操作,当时只做了蓝牙的权限配置,未对这些操作做处理. 1.配置清单文件 <serviceandroid:name=".PlayerServi ...
- Android 蓝牙 A2DP基础概念、A2DP音频流的建立及传输流程、A2DP播放暂停音乐命令交互过程分析 - 史上最全分析
同学,别退出呀,我可是全网最牛逼的 Android 蓝牙分析博主,我写了上百篇蓝牙文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦. Androi ...
- Android 系统(253)---O版本,用耳机按键控制FM的修改方法
O版本,用耳机按键控制FM的修改方法 收音机播放时,按下耳机hook键,收音机暂停:若再次按hook键,收音机又会播放,之前的FAQ13878 由于架构改变,在O版本上会无效,现提供新的修改方法. 一 ...
- android之broadcastreceiver 耳机按键,Android 实时监听耳机按钮事件
写作背景:最近在做视频播放器,客户提出两项新需求: 插耳机看视频,拔出耳机,视频需要暂停.(Android 实时监听耳机拔出事件) 视频播放时,按耳机按钮,视频暂停播放:再按耳机按钮,视频暂停. 如何 ...
- 我的Android进阶之旅------gt;Android中通过adb shell input来模拟滑动、按键、点击事件...
今天在维护公司的一个小项目的时候,发现按公司手机的某个物理按键,激活相应的Service后,会在屏幕上模拟的点击了屏幕的某个坐标点.好家伙,原来是之前该项目的版本是按这个物理按键后,会弹出一个对话框, ...
最新文章
- IE和火狐都支持的方法(输入用户名和密码后按下 enter 键)
- 使用JavaScript让网页title动起来
- 一仅仅小蜜蜂(杭电2044)
- javaScript如何监听浏览器关闭事件
- Oracle杀死Java EE:名正言顺转到.NET Core
- 【POJ - 1562】Oil Deposits (dfs搜索,连通块问题)
- 通过css3制作熊在冰川奔跑效果(animation、精灵图)
- python机器学习案例系列教程——最小生成树(MST)的Prim算法和Kruskal算法
- 面试65个问题教你怎么机智回答面试官及回答技巧
- log4j 配置文件路径问题
- jrtplib java,jrtplib 分包处理
- TFTPD32, 3CDaemon, FlashFxp
- obs多推流地址_如何使用OBS推流直播线上广交会(图文详解) | 文末福利
- unity编辑器一些设置
- 光猫通过 Telnet 修改自带 WLAN 功能 SSID 强制 ChinaNet- 问题
- PHP - MAC下PhpStorm安装调试环境xdebug
- Deadline = Diedline?拖延症幻想美好
- 界面布局上大胆突破,关注到的细分领域
- 网络错误:windows无法访问\\,你没有权限访问\\
- cmd 下删除mysql 服务命令