【问题标题】:How can I intercept a bluetooth headset CALL button?如何拦截蓝牙耳机的 CALL 按钮?
【发布时间】:2013-09-01 02:49:20
【问题描述】:

我有一个单按钮蓝牙耳机 (Jabra BT2045),想拦截按钮按下。我想要这个,以便后台助手Service 可以解释用户的语音命令并采取相应的行动。

我定义了一个名为MediaButtonIntentReceiverBroadcastReceiver,它可以很好地拦截ACTION_MEDIA_BUTTON(使用有线媒体耳机),但重要的是我拦截了BT 呼叫按钮。我已经尝试拦截 CALL_BUTTON 动作 based on another suggestion 我已阅读,但这也失败了。

或者,当我双击按钮时,它会呼叫最近的人,当我长按时,它会调出语音拨号器。

如何拦截单个按钮或这些程序(+阻止它们)?由于我正在对一个想法进行原型设计,因此欢迎黑客攻击,但无论 Android 版本如何都能工作的解决方案是最好的。

我正在使用搭载 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:

如果我set an additional intent filter(见下文)进行活动,它将在长按时启动(在将其设置为默认值之后)。这似乎我正朝着正确的方向前进,但现在活动开始多次并导致奇怪的影响。

现在我正在调查只启动一次活动,当活动恢复时,我必须能够检测它是从启动器启动还是从 VOICE_COMMAND 操作启动的。为了让这个方法起作用,我需要强制该活动只启动一次(按下按钮应该只是恢复活动)。

此外,如果可能的话,我想将其设置为仅在服务运行时活动是默认设置。

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

更新 2:

很遗憾,当蓝牙耳机 SCO 通道被激活时,Activity 将不会继续创建。我的应用程序要求打开此通道,因为用户将收到必须来自 BT 耳机的定期更新(通过 TTS)。这种方法可能会产生很多开销。

【问题讨论】:

    标签: android android-intent bluetooth android-service headset


    【解决方案1】:

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

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

    然后运行 ​​Activity 并在查看 logcat 时按下耳机按钮。 可以参考http://developer.android.com/reference/android/view/KeyEvent.html

    您也可以从 onKeyDown 覆盖其行为,但出于明显的安全原因,我认为您不能在 Activity 之外监听关键事件,更不用说在 Service 中了。

    【讨论】:

    • 不幸的是,这是针对未定义 onKeyDown() 的服务。我希望有一种黑客或一种方法可以跳进去假装我是语音拨号器(我可能已经找到了一个半解决方案,将编辑第一篇文章)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多