I am developing an Android app. I have written my own code for back key event.
For that i am catching events using this method
public boolean onKeyDown(int keyCode, KeyEvent event) .....
I also want to use Menu options I have used Inflator for that.
But when I click on menu button, that event caught by my onKeyDown method.
I am not expecting that, I expect to execute following methods,
public boolean onCreateOptionsMenu(Menu menu){ // creating menu using MenuInflator }
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case :
return true;
default:
}
}
How could I use both the things on the same activity?? Any Idea ???
According to the documentation of onKeyDown():
it is normal that it receives the 'menu button pressed' event, as any KeyEvent
but if you return false, this event will continue to be propagated and will therefore lead onOptionsItemSelected() to be called
So you should code your onKeyDown() in a way that lets the KeyEvent to propagate if you do not handle it on your own.
In the following example, we have two keys that are interesting to us: one we fully handle on our own, one we just track, and we ignore all the rest:
protected boolean onKeyDown(int keyCode, KeyEvent event) {
boolean handled = false; // By default we let the event propagation turned on
if (keyCode == A_KEY_YOU_WOULD_LIKE_TO_HANDLE_BY_YOURSELF) {
doSomething();
handled = true; // Stops the event propagation
}
else if (keyCode == A_KEY_YOU_WOULD_LIKE_TO_TRACK_WITHOUT_PREVENTING_THE_SYSTEM_FROM_HANDLING_IT) {
doSomethingElse();
}
// else, you neither handle or track that key
return handled;
}
Related
I have a Bluetooth barcode scanner that acts as a hardware keyboard. I implemented these methods in my Activity (just testing):
#Override
public boolean onKeyUp (int keyCode, KeyEvent event) {
Log.d("debug", "up: "+KeyEvent.keyCodeToString(keyCode));
return true;
}
#Override
public boolean onKeyDown (int keyCode, KeyEvent event) {
Log.d("debug", "down: "+KeyEvent.keyCodeToString(keyCode));
return true;
}
Yet, whatever I return (be it true or false), the keys are always also handled by the default handler, resulting in unwanted behavior.
Update it seems to be missing the KEYCODE_ENTER, which is handled by a default handler. I tried explicitly setting setDefaultKeyMode(DEFAULT_KEYS_DISABLE), but it had no effect.
Am I missing something here?
There are some buttons on the Activity's view that were focused. The focused Button would get my KEYCODE_ENTER and handle it, leaving nothing for my Activity.
I am trying to catch events generated by the arrow keys (UP, DOWN, RIGHT and LEFT) and disable them. Below code snippet is from one of the activity class.
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(event.getAction() == KeyEvent.KEYCODE_DPAD_DOWN) return true;
else return true;
}
However, with those code in place, key navigation is working. I tried adding key listener to activity which doesn't work either.
The target device is Samsung GT-I5500 with Android 2.2 version on.
Am I missing anything?
Override onKeyDown also and return true and not false.
Somnething like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT:
case KeyEvent.KEYCODE_DPAD_UP:
case KeyEvent.KEYCODE_DPAD_DOWN:
return true;
}
return false;
}
In the documentation, it is stated that you should return:
true if you handled the event
false if if you want to allow the event to be handled by the next receiver.
Your method is returning false, so you are passing the event to the default key handler
I have 2 activities, where I overrided the onKeyUp event:
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
Log.d(TAG, "Key up: " + keyCode);
return super.onKeyUp(keyCode, event);
}
The first is the main activity of the application, the other one is secondary. The first works fine, but the second captures events for Left-Right-Up-Down but not for Center click. Why?
Since you have a Gallery in your layout, take a look at: https://github.com/android/platform_frameworks_base/blob/master/core/java/android/widget/Gallery.java#L1216 . It might be possible that the Gallery steals your DPAD_CENTER event (and also ENTER).
I suggest you to use Activity.dispatchKeyEvent(android.view.KeyEvent) to stop the event before it even goes to that Gallery.
Try using it like this (in your Activity):
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if(event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER) {
// Do your stuff here.
return true; // Consume the event (or not, your call)
}
return super.dispatchKeyEvent(event);
}
How can I set a listener for long-click performed on hardware Menu button? What is the way of programmatic access to the Menu button?
Moreover how can I distinguish long-click from single-click? (As far as I know when long-click is performed the single-click event is propagated as well - I do not want this to happen because I need 2 different actions for these 2 situations. Long-click and single-click separate listeners for the device Menu button)
Thank you!
This shoule be fairly straight forward. Check out the KeyEvent.Callback on the Android developer's website.
There you will find onKeyLongPress() as well as onKeyDown() and onKeyUp(). This should get you on the right track. Comment or post you code if you need any further help.
Edit: I just re-read the question. If you are having trouble distinguishing single click from long click, you will need to use onKeyDown and onKeyUp and check the duration of the click. Esentially you will start a timer in the onKeyDown and check the time in the onKeyUp. You will have to watch for FLAG_CANCELED.
Further Edit: I found the time to do a couple of tests. This code should do what you want (onKeyUp() gets only short press events and onLongPress() gets only long press events).
The key thing here is in the call to event.startTracking() in the onKeyDown() handler.
Place in Activity (this should also work in a custom view as well but untested):
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
// Handle Long Press here
Log.i("KeyCheck", "LongPress");
return true;
}
return super.onKeyLongPress(keyCode, event);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i("KeyCheck", "KeyDown" + keyCode);
if (keyCode == KeyEvent.KEYCODE_MENU) {
event.startTracking(); //call startTracking() to get LongPress event
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.isTracking()
&& !event.isCanceled()) {
// handle regular key press here
Log.i("KeyCheck", "KeyUp");
return true;
}
return super.onKeyUp(keyCode, event);
}
Right now when you hold down the menu button on my android device it pulls up a soft keyboard.Is there a way to override this? I would rather choose what happens on a long touch of this button.
When using onKeyLongPress it only detects when the "Back" button is held down. How can I make this work for the menu button?
For this, you can use the onKeyLongPress()-method, offered by the KeyEvent.Callback-class (can be used in Activity's too, since they are a subclass of the KeyEvent.Callback-class).
There is also a little trick to make this work: You'll have to tell Android to track a long-press click on the "Menu"-button as the onKeyLongPress()-method will not be triggered otherwise. This is done in the normal onKeyDown()-method.
So your code might look like this:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
// this tells the framework to start tracking for
// a long press and eventual key up. it will only
// do so if this is the first down (not a repeat).
event.startTracking();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_MENU){
// Do what you want...
Toast.makeText(this, "I'm down!", Toast.LENGTH_SHORT).show();
return true;
}
return super.onKeyLongPress(keyCode,event);
}
A great article with further informations can be found on the Android Developer Blog.