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发现之旅之媒体按键(耳机按键播放暂停键等)处理过程相关推荐

  1. 媒体控件的播放暂停继续与停止 winform

    媒体控件的播放暂停继续与停止 winform 准备媒体 把媒体放在了一个路径 bin/debug,是项目资源的根目录 播放功能 暂停功能 继续播放 停止播放

  2. android求助:关于播放器中的“播放/暂停”键: 用ImageButton来设置点击效果时的问题...

    ============问题描述============ 大家好,我最近遇到个问题:    大家都知道,播放器中的播放/暂停键是这样的逻辑:当用户点击了这个键,如果当前显示的是"播放&quo ...

  3. Android耳机线控-播放/暂停/上一曲/下一曲

    起因 前一阵子完成了用有线耳机控制Android手机App的音频播放,具体实现了用耳机线的按键完成播放.暂停.上一曲.下一曲的功能.在网上查阅了一些资料,但不是特别尽如人意,记得有一篇写的很不错的这方 ...

  4. android耳机上报流程,Android系统中耳机按键键值上报不正确 解决过程

    [问题现象] 根据测试组同事反馈:在我们的设备上使用 JBL 品牌某款带有 3 个按键的有线耳机时,按下"音量+"键时设备会减小音量而不是增加音量,按下"音量-" ...

  5. android连接蓝牙控制音乐播放器播放暂停/上一曲/下一曲,且断开蓝牙暂停音乐

    客户需求要蓝牙设备可以控制音乐播放器的暂停等操作,当时只做了蓝牙的权限配置,未对这些操作做处理. 1.配置清单文件 <serviceandroid:name=".PlayerServi ...

  6. Android 蓝牙 A2DP基础概念、A2DP音频流的建立及传输流程、A2DP播放暂停音乐命令交互过程分析 - 史上最全分析

    同学,别退出呀,我可是全网最牛逼的 Android 蓝牙分析博主,我写了上百篇蓝牙文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦. Androi ...

  7. Android 系统(253)---O版本,用耳机按键控制FM的修改方法

    O版本,用耳机按键控制FM的修改方法 收音机播放时,按下耳机hook键,收音机暂停:若再次按hook键,收音机又会播放,之前的FAQ13878 由于架构改变,在O版本上会无效,现提供新的修改方法. 一 ...

  8. android之broadcastreceiver 耳机按键,Android 实时监听耳机按钮事件

    写作背景:最近在做视频播放器,客户提出两项新需求: 插耳机看视频,拔出耳机,视频需要暂停.(Android 实时监听耳机拔出事件) 视频播放时,按耳机按钮,视频暂停播放:再按耳机按钮,视频暂停. 如何 ...

  9. 我的Android进阶之旅------gt;Android中通过adb shell input来模拟滑动、按键、点击事件...

    今天在维护公司的一个小项目的时候,发现按公司手机的某个物理按键,激活相应的Service后,会在屏幕上模拟的点击了屏幕的某个坐标点.好家伙,原来是之前该项目的版本是按这个物理按键后,会弹出一个对话框, ...

最新文章

  1. IE和火狐都支持的方法(输入用户名和密码后按下 enter 键)
  2. 使用JavaScript让网页title动起来
  3. 一仅仅小蜜蜂(杭电2044)
  4. javaScript如何监听浏览器关闭事件
  5. Oracle杀死Java EE:名正言顺转到.NET Core
  6. 【POJ - 1562】Oil Deposits (dfs搜索,连通块问题)
  7. 通过css3制作熊在冰川奔跑效果(animation、精灵图)
  8. python机器学习案例系列教程——最小生成树(MST)的Prim算法和Kruskal算法
  9. 面试65个问题教你怎么机智回答面试官及回答技巧
  10. log4j 配置文件路径问题
  11. jrtplib java,jrtplib 分包处理
  12. TFTPD32, 3CDaemon, FlashFxp
  13. obs多推流地址_如何使用OBS推流直播线上广交会(图文详解) | 文末福利
  14. unity编辑器一些设置
  15. 光猫通过 Telnet 修改自带 WLAN 功能 SSID 强制 ChinaNet- 问题
  16. PHP - MAC下PhpStorm安装调试环境xdebug
  17. Deadline = Diedline?拖延症幻想美好
  18. 界面布局上大胆突破,关注到的细分领域
  19. 网络错误:windows无法访问\\,你没有权限访问\\
  20. cmd 下删除mysql 服务命令

热门文章

  1. Linux的root用户路径
  2. LTE 物理层、资源网格配置
  3. python二进制转十进制算法_python进制转换:十进制转二进制的用法
  4. 计算机机房环控模块箱的作用,机房环境监控系统的作用【斯必得智慧机房】
  5. RFID在模块管理中的应用
  6. 软件开发平台实现目标归纳
  7. 小组项目第三周:后端数据——模拟炒股系统
  8. js轮播最后一张跳到第一张的处理
  9. eclipse编写java游戏_Ballgame eclipse编写的java小游戏 - 下载 - 搜珍网
  10. 【项目实战课】从零掌握安卓端Pytorch原生深度学习模型部署