How to Create an Android Service That Listens for Hardware Key Presses

Is it possible to create an Android Service that listens for hardware key presses?

As far as I know KeyEvents can only be handled by Activities as they are the interface to the user pressing the keys. Services run in the background and are not intended to react on user input. That's also the reason of your compiler warning "onKeyDown is undefined for the type Service". Service or any of it's Superclasses don't implement the KeyEvent.Callback interface. As a workaround you could register an Activity in your AndroidManifest.xml to react on certain system notifications such as android.intent.action.SCREEN_ON. When the power button is pressed to turn on the screen your activity could be started, initializing a service of some kind and go back to the background. If that's what you intend to do. See Intent docs for possible Actions.

Hope that helped...

Is it possible to create a service that listens for Volume key (hardware) presses?

You can use an OnKeyListener which can detect keyevents (including volume keys). You can find the keycodes here. Good Luck!

How to capture key events inside a service?

Yes, Android's activities only receives KeyEvents when they have focus.

The only way to "globally" capture a back button press is creating an InputMethod so you can intercept hard key events.
Remember that using your own InputMethod will not allow you to use custom keyboards like Swiftkey for instance.

Did you try to reach HTC on this issue?

Android - Listener for hard keys press at background

KeyEvents can only be handled by Activities as they are the interface to the user pressing the keys and only when they are in the foreground. Even Services that run in the background are not intended to react on user input.

But by using a service you can have a workaround. You can create a service that responds to hard key press events by registering a BroadcastReceiver. For example in the AOSP music app, they have a Service (MediaPlaybackService) that responds to volume key events by registering a BroadcastReceiver (MediaButtonIntentReceiver).

Here's the code where it registers the receiver:

mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
ComponentName rec = new ComponentName(getPackageName(),
MediaButtonIntentReceiver.class.getName());
mAudioManager.registerMediaButtonEventReceiver(rec);

This works even if the Music app is not in the foreground. Code snippet from this answer.

Listening to key press events blocks the keys from working

overriding the onKeyDown() of Activity is easier; because it's always KeyEvent.ACTION_DOWN:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP: {
System.out.println("UP");
}
case KeyEvent.KEYCODE_VOLUME_DOWN: {
System.out.println("DOWN");
}
}
return super.onKeyDown(keyCode, event);
}

Android:how to get any KeyPress event with example?

Answer to this question should be twofold. It is determined by the way how the key was generated. If it was press on the hardware key, then both approaches described below are valid. If it was press on the software key, then it depends on actual context.

1.) If key was result of the pressing on the soft keyboard that was obtained by long press on the Menu key:

You need to carefully override the following function:

@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {
case KeyEvent.KEYCODE_A:
{
//your Action code
return true;
}
}
return super.onKeyDown(keyCode, event);
}

2.) If your activity contains EditText, and softkeyboard was obtained from it, then first approach does not work because key event was already consumed by EditText. You need to use text changed Listener:

mMyEditText.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
}
public void beforeTextChanged(CharSequence s, int start, int count, int after)
{
/*This method is called to notify you that, within s, the count characters beginning at start are about to be replaced by new text with length after. It is an error to attempt to make changes to s from this callback.*/
}
public void onTextChanged(CharSequence s, int start, int before, int count)
{
}
);


Related Topics



Leave a reply



Submit