如何拦截蓝牙耳机的通话按钮?

3

我有一款单按钮蓝牙耳机(Jabra BT2045),想要拦截按键操作。我想这样,后台助手Service可以解释用户的语音命令并做出相应的动作。

我定义了一个名为MediaButtonIntentReceiverBroadcastReceiver,可以很好地拦截ACTION_MEDIA_BUTTON(使用带线媒体耳机),但重要的是我需要拦截BT呼叫按钮。我已经尝试拦截CALL_BUTTON操作,基于另一个建议,但也失败了。

或者,当我双击该按钮时,会呼叫最近联系人,长按它会启动语音拨号器。

我如何拦截单个按钮或这些过程(+防止它们)?由于我正在原型设计一个想法,所以欢迎各种hack方法,但适用于所有Android版本的解决方案最好。

我正在使用安卓4.3的Galaxy Nexus手机。

AndroidManifest.xml(包括接收器定义)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="nz.ac.waikato.ssc10.BlindAssistant">

    <uses-sdk android:minSdkVersion="17"/>

    <uses-permission android:name="android.permission.ACCESS_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <!-- Bluetooth Headset -->
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

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

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name">
        <activity
            android:name=".activities.VoicePromptActivity"
            android:screenOrientation="portrait"
            android:label="Voice Prompt">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service android:name=".services.BlindAssistantService"/>
        <service android:name=".services.WalkingDirectionsUpdateService"/>

        <receiver android:name=".receivers.MediaButtonIntentReceiver">
            <intent-filter>
                <action android:name="android.intent.action.CALL_BUTTON"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

接收方定义:

public class CallButtonIntentReceiver extends BroadcastReceiver {
    private static String TAG = "CallButtonIntentReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction(); // I never get to this point in debugger (breakpoint set here)

        // Code to actually handle button press ...
    }
}

更新1:

如果我为活动设置一个额外的意图过滤器(见下文),并将其设置为默认,那么在长按后会启动它。这似乎是我朝着正确方向前进,但现在该活动启动了多次并引起了奇怪的效果。

现在,我正在研究仅启动一次该活动,并且当该活动恢复时,必须能够检测是否从启动器或VOICE_COMMAND操作开始启动。为使此方法发挥作用,我需要强制仅启动一次该活动(按下按钮时只需恢复活动)。

此外,如果可能的话,我想让该活动只在服务运行时才是默认活动。

<intent-filter>
    <action android:name="android.intent.action.VOICE_COMMAND"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

更新2:

不幸的是,在蓝牙耳机SCO通道被激活的时候,该活动将不会继续创建。我的应用程序需要该通道保持打开状态,因为用户将定期收到必须从BT耳机中发出的更新(通过TTS)。这种方法可能会产生很大的开销。

1个回答

1

您可以使用测试活动的onKeyDown方法来识别耳机按钮的键代码:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
  Log.d("KeyCode", keycode + "");
  Log.d("KeyEvent", event + "");
  return super.onKeyDown(keyCode, event);
}

只需运行活动并在查看logcat时按下耳机按钮。 您可以参考http://developer.android.com/reference/android/view/KeyEvent.html

您还可以从onKeyDown覆盖其行为,但我认为出于明显的安全原因,您无法在Activity之外甚至在Service中监听键事件。


很不幸,这是一个没有定义onKeyDown()的服务。我希望有一种方法或者技巧可以跳进去并且假装我是语音拨号器(我可能已经找到了一种半解决方案,会在第一篇帖子中进行编辑)。 - Simon Campbell

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接