Im разрабатывает приложение Android
, и я хочу, чтобы он взаимодействовал с нажатием кнопки headset
. Im тестировал его в Nexus 5 с Android KitKat 4.4.
Сначала я попробовал простую гарнитуру (не беспроводную). Полученное событие кнопки было KEYCODE_HEADSETHOOK
(79). Я создал MEDIA_BUTTON
receiver
для обработки кликов:
<receiver android:name="com.example.mytest.SearchActivity$MediaButtonIntentReceiver">
<intent-filter>
<intent-filter android:priority="1000000000">
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</intent-filter>
</receiver>
Это действие, поддерживающее приемник:
public class SearchActivity extends Activity {
private AudioManager mAudioManager;
private ComponentName mAudioReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mAudioReceiver = new ComponentName(getPackageName(),
MediaButtonIntentReceiver.class.getName());
}
@Override
protected void onResume() {
super.onResume();
mAudioManager.registerMediaButtonEventReceiver(mAudioReceiver);
}
@Override
protected void onPause() {
super.onPause();
mAudioManager.unregisterMediaButtonEventReceiver(mAudioReceiver);
}
public static class MediaButtonIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("SA", "ON RECEIVE");
...
abortBroadcast();
}
}
}
Этот код работает с моей проводной гарнитурой , только если пользователь выполняет короткий клик. Выполните длинный щелчок Google Voice Search
. Id нравится захватывать длинные клики тоже, но я не возражаю, если это невозможно.
После этого я протестировал его с помощью гарнитуры bluetooth
. В частности, я использую Bluetooth-гарнитуру Moveteck BH119A (вы можете увидеть изображение внизу этого сообщения). Эта гарнитура имеет только одну кнопку, и если я ее нажму, откроется следующее "activity
":
Мне нравится делать это событие click, если мой activity
открыт. Как мне это сделать? Я попытался добавить следующие фильтры к моему ресиверу, но он не работает:
<action android:name="android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT" />
<action android:name="android.intent.action.VOICE_COMMAND" />
<action android:name="android.intent.action.CALL_BUTTON" />
Я также попытался переопределить onKeyDown
в моей Activity, но не был вызван.
Кто-нибудь знает, как я могу перехватить эти события?
Это моя Bluetooth-гарнитура:
** РЕДАКТИРОВАТЬ **
Следуя советам Тостеров, я проверил весь журнал, ища события, которые запускает моя гарнитура.
Долгое нажатие проводной гарнитуры
Это журнал, когда я долго нажимаю на свою проводную гарнитуру (он открывает Google Voice Search
):
12-10 09:24:36.644: I/MediaFocusControl(740): voice-based interactions: about to use ACTION_WEB_SEARCH
12-10 09:24:36.644: I/ActivityManager(740): START u0 {act=android.speech.action.WEB_SEARCH flg=0x10800000 cmp=com.google.android.googlequicksearchbox/.SearchActivity} from pid 740
12-10 09:24:36.754: I/ActivityManager(740): START u0 {act=android.speech.action.WEB_SEARCH flg=0x10000000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL} from pid 10153
12-10 09:24:36.764: I/InputDispatcher(740): Dropping event because there is no focused window or focused application.
12-10 09:24:36.764: I/InputDispatcher(740): Dropping event because there is no focused window or focused application.
12-10 09:24:36.774: I/GEL(1025): handleIntent(Intent { act=android.speech.action.WEB_SEARCH flg=0x10400000 cmp=com.google.android.googlequicksearchbox/com.google.android.launcher.GEL })
12-10 09:24:36.774: V/SearchControllerCache(10153): creating SearchController
12-10 09:24:36.804: I/AudioRouter(10153): ROUTE_NONE->ROUTE_NO_BLUETOOTH
12-10 09:24:36.804: I/MediaFocusControl(740): AudioFocus requestAudioFocus() from [email protected][email protected]
12-10 09:24:36.804: I/Velvet.SdchManager(10153): Sdch cache load complete.
12-10 09:24:36.814: W/IInputConnectionWrapper(18407): showStatusIcon on inactive InputConnection
12-10 09:24:36.814: I/Icing.InternalIcingCorporaProvider(10153): Updating corpora: A: NONE, C: DELTA
12-10 09:24:36.854: I/VS.G3EngineManager(10153): create_rm: m=GRAMMAR,l=en-US
12-10 09:24:36.854: W/Search.ConcurrentUtils(10153): Executor queue length is now 9. Perhaps some tasks are too long, or the pool is too small. [GrecoExecutor-1]
12-10 09:24:36.854: I/VS.G3EngineManager(10153): Brought up new g3 instance :/system/usr/srec/en-US/grammar.config for: en-USin: 9 ms
12-10 09:24:36.864: D/audio_hw_primary(189): out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=4
12-10 09:24:36.864: D/audio_hw_primary(189): select_devices: out_snd_device(4: headphones) in_snd_device(0: )
12-10 09:24:36.874: D/audio_hw_primary(189): select_devices: out_snd_device(0: ) in_snd_device(18: headset-mic)
12-10 09:24:36.874: D/(189): Failed to fetch the lookup information of the device 00000008
12-10 09:24:36.874: E/ACDB-LOADER(189): Error: ACDB AudProc vol returned = -19
12-10 09:24:38.864: I/LATENCY(10153): 0-4,45-2064,
12-10 09:24:38.874: I/AudioRouter(10153): ROUTE_NO_BLUETOOTH->ROUTE_NONE
12-10 09:24:38.874: I/MediaFocusControl(740): AudioFocus abandonAudioFocus() from [email protected][email protected]
12-10 09:24:38.874: I/MicrophoneInputStream(10153): mic_close
Кажется, он запускает событие ACTION_WEB_SEARCH
, поэтому я попытался добавить его в фильтр. Я попробовал это двумя способами:
-
Объявление фильтра в манифесте:
<action android:name="android.intent.action.WEB_SEARCH" />
-
Объявление программно программно:
protected void onResume() { IntentFilter f = new IntentFilter(Intent.ACTION_WEB_SEARCH); registerReceiver(myReceiver, f); } private BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d("AA", "ON RECEIVE"); } };
Ни один из этих параметров не работает. Как я уже сказал, этот сценарий не имеет большого значения, я могу справиться с этим.
Беспроводная гарнитура просто нажмите
Простой щелчок беспроводной гарнитуры - это тот, который открывает Voice Dialer и его событие, которое мне действительно нужно захватить. Это вывод журнала:
12-10 10:41:22.014: E/bt-rfcomm(21800): PORT_DataInd, p_port:0x7507a7e8, p_data_co_callback is null
12-10 10:41:22.014: D/HeadsetStateMachine(21800): processVrEvent: state=1 mVoiceRecognitionStarted: false mWaitingforVoiceRecognition: false isInCall: false
12-10 10:41:22.014: I/ActivityManager(740): START u0 {act=android.intent.action.VOICE_COMMAND flg=0x10000000 cmp=com.google.android.googlequicksearchbox/com.google.android.voicesearch.handsfree.HandsFreeIntentActivity} from pid 21800
12-10 10:41:22.154: V/Avrcp(21800): New genId = 440, clearing = 1
12-10 10:41:22.154: D/HandsFreeIntentActivity(10153): #onStart(Intent { act=android.intent.action.VOICE_COMMAND flg=0x10800000 cmp=com.google.android.googlequicksearchbox/com.google.android.voicesearch.handsfree.HandsFreeIntentActivity })
12-10 10:41:22.154: D/HandsFreeIntentActivity(10153): Starting activity: Intent { act=android.intent.action.VOICE_COMMAND flg=0x10000000 cmp=com.google.android.googlequicksearchbox/com.google.android.voicesearch.handsfree.HandsFreeActivity }
12-10 10:41:22.154: I/ActivityManager(740): START u0 {act=android.intent.action.VOICE_COMMAND flg=0x10000000 cmp=com.google.android.googlequicksearchbox/com.google.android.voicesearch.handsfree.HandsFreeActivity} from pid 10153
12-10 10:41:22.204: D/OpenGLRenderer(10153): Enabling debug mode 0
12-10 10:41:22.214: W/IInputConnectionWrapper(18895): showStatusIcon on inactive InputConnection
12-10 10:41:22.244: I/ActivityManager(740): Displayed com.google.android.googlequicksearchbox/com.google.android.voicesearch.handsfree.HandsFreeActivity: +80ms (total +89ms)
12-10 10:41:22.374: I/AudioRouter(10153): ROUTE_NONE->ROUTE_BLUETOOTH_WANTED
12-10 10:41:22.384: I/MediaFocusControl(740): AudioFocus requestAudioFocus() from [email protected][email protected]
12-10 10:41:22.384: V/Avrcp(21800): New genId = 441, clearing = 1
12-10 10:41:22.384: D/BluetoothManagerService(740): Message: 30
12-10 10:41:22.384: D/BluetoothHeadset(10153): Proxy object connected
12-10 10:41:22.384: I/BluetoothController(10153): BT device connected
12-10 10:41:22.394: I/AudioRouter(10153): BT required, starting SCO
12-10 10:41:22.394: I/BluetoothController(10153): Starting VR
12-10 10:41:22.394: D/BluetoothHeadset(10153): startVoiceRecognition()
12-10 10:41:22.394: D/HeadsetStateMachine(21800): Voice recognition started successfully
12-10 10:41:22.394: D/HeadsetStateMachine(21800): Initiating audio connection for Voice Recognition
12-10 10:41:22.394: W/bt-btm(21800): BTM Remote does not support 3-EDR eSCO
12-10 10:41:22.434: I/TextToSpeech(10153): Sucessfully bound to com.google.android.tts
12-10 10:41:22.454: I/TextToSpeech(10153): Connected to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
12-10 10:41:22.454: I/TextToSpeech(10153): Set up connection to ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}
12-10 10:41:22.484: D/dalvikvm(21966): GC_CONCURRENT freed 346K, 3% free 16647K/17064K, paused 2ms+3ms, total 13ms
12-10 10:41:22.764: D/audio_hw_primary(189): out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=32
12-10 10:41:22.774: D/audio_hw_primary(189): select_devices: out_snd_device(11: bt-sco-headset) in_snd_device(0: )
12-10 10:41:24.874: I/EventLogService(1148): Aggregate from 1386666683008 (log), 1386666683008 (data)
12-10 10:41:24.994: I/ServiceDumpSys(1148): dumping service [account]
12-10 10:41:25.994: D/dalvikvm(10153): GC_CONCURRENT freed 1582K, 15% free 23868K/27920K, paused 5ms+7ms, total 60ms
12-10 10:41:26.014: I/VS.G3EngineManager(10153): create_rm: m=GRAMMAR,l=en-US
12-10 10:41:26.024: I/VS.G3EngineManager(10153): Brought up new g3 instance :/system/usr/srec/en-US/grammar.config for: en-USin: 4 ms
12-10 10:41:26.024: D/audio_hw_primary(189): out_set_parameters: enter: usecase(1: low-latency-playback) kvpairs: routing=32
12-10 10:41:26.034: D/audio_hw_primary(189): select_devices: out_snd_device(0: ) in_snd_device(25: bt-sco-mic)
12-10 10:41:26.034: D/(189): Failed to fetch the lookup information of the device 00000015
12-10 10:41:26.034: E/ACDB-LOADER(189): Error: ACDB AudProc vol returned = -19
На этот раз кажется, что он отправляет ACTION_VOICE_COMMAND
, поэтому я попытался добавить его в фильтр. Я попробовал это двумя способами:
-
Объявление фильтра в манифесте:
<action android:name="android.intent.action.VOICE_COMMAND" />
-
Объявление программно программно:
protected void onResume() { IntentFilter f = new IntentFilter(Intent.ACTION_VOICE_COMMAND); registerReceiver(myReceiver, f); } private BroadcastReceiver myReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d("AA", "ON RECEIVE"); } };
Опять же, я не получаю эти события, я не знаю, почему.