【问题标题】:How to capture key events from bluetooth headset with android如何使用 android 从蓝牙耳机捕获关键事件
【发布时间】:2013-07-23 01:56:58
【问题描述】:

我的应用可以通过普通耳机控制。它只是覆盖“onKeyDown”。但是蓝牙耳机的关键事件没有被捕获 - 为什么?或者如何捕捉蓝牙按键事件?

如果我按下耳机上的按钮,“日志猫”会显示以下内容:

Bluetooth AT recv(3043): AT+VGS=15
AudioPolicyManagerBase(13654): FM radio recording off
AudioService(2261): sendVolumeUpdate, isKeyguardLocked...Not to update Volume Panel.
VolumePanel(2261): change volume by MSG_VOLUME_CHANGED
VolumePanel(2261): onVolumeChanged(streamType: 6, flags: 0)
VolumePanel(2261): Call setChangeSeekbarColor(false)

我也尝试处理媒体按钮操作,但这不起作用。我的想法是一个免费的可配置键映射:用户选择“设置键”我的应用程序在所有键(硬件、媒体按钮、蓝牙耳机)上听到,然后用户按下一个键,事件/键代码存储在配置中。

总结不起作用答案: 音量按钮必须由“VOLUME_CHANGED_ACTION”捕获。问题是这个意图被广播到其他应用程序并且 abortBroadcast() 不起作用(它仅适用于“有序”广播)。另一个问题是有线耳机和电话上的按键触发 onReceive() 两次(为什么?)蓝牙耳机触发一次。 下一个问题是蓝牙耳机的第三把钥匙。它触发语音命令(s-voice 从 s3 开始),我试图捕捉许多不同的意图,但我无法“接收”这个按钮按下并且不知道为什么。 最后,我想捕获各种按钮,并且不希望它们被其他应用程序处理(例如使用 onKeyDown 并返回 true)。

【问题讨论】:

  • 哪个版本的安卓?
  • 最低版本为 4.0,最高版本为 4.2(在 manifest 中指定),在 Galaxy s3 上使用 4.1 测试
  • @dermoritz 你有没有偶然解决这个问题?
  • 对不起,我不记得了,太久远了

标签: android bluetooth android-bluetooth


【解决方案1】:

MEDIA_BUTTON添加广播监听器:

<intent-filter android:priority="<some number>"> 
   <action android:name="android.intent.action.MEDIA_BUTTON" /> 
</intent-filter> 

您应该在您的应用程序中注册您的广播接收器(而不是在清单文件中)。否则,谷歌音乐播放器将捕捉您的广播并登上它。

您的IntentFilter 优先级应该高于您手机中其他媒体播放器的优先级)

在清单中添加android.permission.BLUETOOTH 权限以支持蓝牙耳机

收到您的密钥后,您必须使用abortBroadcast() 手动中止广播。

但是,只要每个应用只在 例如播放了一些东西。 但是一些用户还希望在按下按钮时启动(或开始播放)“默认播放器”,就像默认播放器一样,因此可能会发生某些具有更高优先级编号的应用程序不会让意图进入您的应用程序

onReceive中,可以用

获取按钮事件
KeyEvent key = (KeyEvent) 
intent.getParcelableExtra(Intent.EXTRA_KEY_EVENT); 

key.getKeyAction() 告诉您按钮是被释放还是按下,key.getKeyCode() 告诉您按下哪个按钮。

如果您还想处理单键有线耳机,也可以 关注键码KEYCODE_HEADSETHOOK

在任何活动中覆盖onKeyDown 方法并检查 KeyEvent.KEYCODE_MEDIA_KEYCODE_pressed_key

例如

 boolean onKeyDown(int keyCode, KeyEvent event) { 
            AudibleReadyPlayer abc; 
            switch (keyCode) { 
            case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: 
                    // code for fast forward 
                    return true; 
            case KeyEvent.KEYCODE_MEDIA_NEXT: 
                    // code for next 
                    return true; 
            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: 
                    // code for play/pause 
                    return true; 
            case KeyEvent.KEYCODE_MEDIA_PREVIOUS: 
                    // code for previous 
                    return true; 
            case KeyEvent.KEYCODE_MEDIA_REWIND: 
                    // code for rewind 
                    return true; 
            case KeyEvent.KEYCODE_MEDIA_STOP: 
                    // code for stop 
                    return true; 
            } 
            return false; 
    } 

音量键集成示例 Android - Volume Buttons used in my application
这个可能需要权限

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />


或者您可以通过以下链接尝试更简洁的实现

Android Developer Blog : Handling remote control buttons
Android Tales : Add Headset button support to your Android application

【讨论】:

  • 谢谢,但我认为您没有阅读其他答案和我的 cmets。这不起作用:音量按钮不是“MEDIA_BUTTONS”。它们由“volume_change”捕获。由于此意图似乎是“未排序的”,因此“abortBroadcast()”不起作用 - 会引发错误并且无论如何音量都会发生变化。另一方面,“KEYCODE_HEADSETHOOK”仅适用于有线耳机。蓝牙耳机发送启动语音识别的内容(s3 上的 s-voice)。我几乎没有试图捕捉到这一点,但我没有成功。
  • 你说得对,我好像在匆忙中错过了一些东西,抱歉。似乎这是您正在寻找的答案 [link]stackoverflow.com/questions/2874743/… 还添加权限&lt;uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /&gt;
  • @YashwanthKrishnan:嘿,我应该设置什么优先级,以便我们的应用程序而不是默认音乐播放器接收 media_button 键事件?即使我的应用程序在前台,音乐播放器正在接收键事件和玩,我把它设置为 10000 但仍然没有运气。
  • 根据developer.android.com/guide/topics/manifest/…这个优先级必须大于-1000小于1000。
【解决方案2】:

查看this article。它解释了如何使用媒体按钮操作来实现类似的东西。

我知道你提到你走这条路没有成功,还是试试看。请注意与注册广播接收器、设置意图过滤器优先级和添加权限相关的问题(所有内容都在文章中进行了解释)。

希望这会有所帮助。

【讨论】:

  • 谢谢 - 我会试试的。如果这项工作你会得到赏金
  • 我试过了,但它不起作用:问题是它捕获了意图(音量更改或媒体按钮),但这个意图也由所有其他音量按钮发送,并且由所有人处理注册到该事件的其他活动。我想捕捉事件并“使用”它 - 就像 HW-Keys 的“onKeyDown”一样。
  • @dermoritz 你确定你在广播接收器中调用了abortBroadcast
  • 我刚试过:音量变化似乎是“无序广播” - abortBroadcast() 不起作用。耳机上的另一个按钮(用于语音命令)根本无法捕获。我尝试添加各种动作,如“android.intent.action.VOICE_COMMAND”和“android.speech.action.RECOGNIZE_SPEECH”,但我的动作没有反应——总是手机内置的“s-voice”正在启动。
  • @dermoritz 我有一个想法,严格来说并不是您问题的答案,但可能会阻止您最终找到解决方案。看看这个应用程序:play.google.com/store/apps/details?id=com.kin.bluetooth_launch。它说它适用于大多数蓝牙耳机(至少符合标准的耳机)。如果它适用于您的情况,您可以尝试询问作者/查找来源或对其进行逆向工程以查看它是如何解决的。如果需要,我实际上可以帮助您进行逆向工程部分(以前做过类似的事情)。
【解决方案3】:

如果您尝试从活动中侦听此内容,请使用 onKeyDown() 并捕获 KEYCODE_MEDIA_PLAY_PAUSEKEYCODE_MEDIA_PLAYKEYCODE_MEDIA_PAUSE ICS 后)关键事件。

为了让广播接收器解决方案正常工作,请确保没有在后台安装和运行其他应用程序来捕获这些可能优先于您的事件的应用程序。

也看看这个:Android - registering a headset button click with BroadcastReceiver

【讨论】:

  • thx - 但 onKeyDown 不适用于蓝牙,它仅捕获有线耳机和电话键。而且我永远无法确定某人运行或安装了哪些应用程序。
  • 有趣,我认为它会赶上 onKeyDown ,就像这里提到的:groups.google.com/forum/#!topic/android-developers/v_7lT-o0ERg ?另请查看链接中的第二个答案。
  • 哪个版本的安卓?可能会在 Jelly bean 之后使用所有新的蓝牙内容进行更改
  • 最低版本是 4.0,最高版本是 4.2 - 我正在 Galaxy s3 上使用 4.1 进行测试
猜你喜欢
  • 2020-10-14
  • 1970-01-01
  • 2014-07-09
  • 1970-01-01
  • 1970-01-01
  • 2019-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多