[英]How can I intercept a bluetooth headset CALL button?
I have a single button Bluetooth headset (Jabra BT2045) and would like to intercept the button presses. 我有一个按钮蓝牙耳机 (Jabra BT2045),并希望截取按钮按下。 I want this so that a background assistant
Service
can interpret the user's voice command and act accordingly. 我希望这样,以便后台助理
Service
可以解释用户的语音命令并采取相应的行动。
I have defined a BroadcastReceiver
named MediaButtonIntentReceiver
which can intercept ACTION_MEDIA_BUTTON
just fine (using a wired media headset) but it is important that I intercept the BT call button. 我已经定义了一个名为
MediaButtonIntentReceiver
的BroadcastReceiver
,它可以很好地拦截ACTION_MEDIA_BUTTON
(使用有线媒体耳机)但是我拦截BT呼叫按钮很重要。 I have tried intercepting the CALL_BUTTON
action based on another suggestion I have read but this also fails. 我已经尝试根据我读过的另一个建议拦截
CALL_BUTTON
操作,但这也失败了。
Alternatively, when I double tap the button it calls the most recent person and when I long press it brings up a voice dialler. 或者,当我双击按钮时,它会调用最近的人,当我长按它时会调出一个语音拨号器。
How can I intercept the single button or these procedures (+prevent them)? 如何拦截单个按钮或这些程序(+防止它们)? Hacks are welcome since I am prototyping an idea, but solutions that work regardless of Android versions are best.
黑客是受欢迎的,因为我正在构思一个想法,但无论Android版本如何工作的解决方案都是最好的。
I am using a Galaxy Nexus with Android 4.3. 我正在使用Android 4.3的Galaxy Nexus。
AndroidManifest.xml (incl. receiver definition) 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>
Receiver definition: 接收者定义:
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 ...
}
}
Update 1: 更新1:
If I set an additional intent filter (see below) for the activity it will launch on a long press (after setting it as the default). 如果我为活动设置了一个额外的意图过滤器 (见下文),它将在长按(在将其设置为默认值后)启动。 This seems like I am going in the right direction but now the activity starts many times and causes weird effects.
这似乎是我朝着正确的方向前进,但现在活动开始很多次并导致奇怪的效果。
Now I am investigating only starting the activity once and when the activity resumes I must be able to detect if it was started from the launcher or from the VOICE_COMMAND
action. 现在我正在调查只启动活动一次,当活动恢复时,我必须能够检测它是从启动器启动还是从
VOICE_COMMAND
操作启动。 In order for this method to work I'll need to enforce that the activity is only started once (pressing the button should simply resume the activity). 为了使这个方法起作用,我需要强制执行活动只启动一次(按下按钮应该只是恢复活动)。
Additionally, if possible, I would like to make it so the activity is only the default while the service is running. 另外,如果可能的话,我想这样做,因此活动只是服务运行时的默认值。
<intent-filter>
<action android:name="android.intent.action.VOICE_COMMAND"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
Update 2: 更新2:
Unfortunately, the activity will not continue to be created while the Bluetooth headset SCO channel is activated. 遗憾的是,在激活蓝牙耳机SCO通道时,不会继续创建活动。 My application requires this channel to be open as the user will receive periodic updates (via TTS) which MUST come out of the BT headset.
我的应用程序要求打开此频道,因为用户将接收定期更新(通过TTS),必须从BT耳机中获取。 This method may incur a lot of overhead.
这种方法可能会产生很多开销。
You could maybe identify the headset button's keycode with a test activity's onKeyDown method: 您可以使用测试活动的onKeyDown方法识别耳机按钮的键码:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d("KeyCode", keycode + "");
Log.d("KeyEvent", event + "");
return super.onKeyDown(keyCode, event);
}
Then just run the activity and hit the headset button while looking at the logcat. 然后只需运行活动并按下耳机按钮,同时查看logcat。 You can refer to http://developer.android.com/reference/android/view/KeyEvent.html
您可以参考http://developer.android.com/reference/android/view/KeyEvent.html
You could also override its behaviour from onKeyDown, but I don't think you can listen to key events outside of an Activity, let alone in a Service, for obvious security reasons. 您也可以从onKeyDown覆盖其行为,但出于明显的安全原因,我认为您不能在Activity之外监听关键事件,更不用说在服务中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.