onKeyDown not always called in Android app - android

I've created a simple android game, based on the Lunar Lander sample, and I'm having a problem with handling key events. When the activity starts, the only keys that onKeyDown or onKeyUp get called for are the dpad up/down/left/right keys. Neither the menu, back, or dpad_center keys trigger onKey methods. However, once I've pushed one of the dpad up/down/left/right buttons, pressing the menu, back, or dpad_center keys do trigger these methods. I'm not getting any errors, or any indication of what's going wrong.
It's possible that the focus is set wrong - the activity is started from a button on screen, so it could be in touchscreen mode. If that's the case, shouldn't touching the back button get me in to the right focus mode so that I can catch the event?
I'm using the emulator from SDK-1.5r3. I have not been able to try this on a real phone yet. Here's my onKeyDown.
public boolean onKeyDown(int keyCode, KeyEvent msg)
{
Log.d(TAG, "onKeyDown: " + keyCode);
return super.onKeyDown(keyCode, msg);
}
Thanks
Matt

Is this onKeyDown in a view or in the activity?
If setContentView is called passing in a view, and that view has setFocusable(true) called on it, all key events will bypass the activity and go straight into the view.
On the other hand, if your onKeyDown is in the view, and you haven't called setContentView on the Activity and setFocusable(true) on the view, then your Activity will get the key events and not the View.
Look for those specific calls but I think you're right about it being a focus issue.

Activity's onKeyDown/onKeyUp methods not always called. Unlike them dispatchKeyEvent on Activity fired always. Move keydown/keyup logic here. Works well.
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
// keydown logic
return true;
}
return false;
}

insert this code
getWindow().getDecorView().setFocusable(true);
if (SDK_INT >= Build.VERSION_CODES.O) {
getWindow().getDecorView().setFocusedByDefault(true);
}

Related

Override back button on xamarin android app

I am building an application using Xamarin and it's Android Player for Android. Whenever I hit the back button it seems to back out of the application completely. I want to be able to change this default to go back to the previous page in my app. How do I override the back button behavior?
So the previous answer is correct, you can trap the hardware back button and do whatever you want with it. But I want to make sure you understand why this is happening. Android handles the hardware back button for you, and most of the time, letting Android handle it will work, it knows what to do.
But in your case, you're not actually navigating at all. Your click handler is removing one layout file and replacing it with another. This is the equivalent of showing/hiding a div in web development. You're not actually changing the screen(page).
Because of this, when you hit the back button, you're still on the first (and only) screen in your app, so the OS does the only thing it knows to do, it closes the app.
If you want to continue with the paradigm of showing/hiding layouts in lieu of actually navigating, I would trap the hardware back button and re-swap your layout files.
public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
{
if (keyCode == Keycode.Back) {
SetContentView(Resource.Layout.Login)
return false;
}
return true;
}
But the true solution that I would recommend would be to read up on how to truly navigate in Xamarin Android. Swapping your layout files and putting all the logic for your entire app in one Activity will be very hard to maintain.
You can capture the OnKeyDown and decide whether to allow the Back button to ripple up the event chain or not:
public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
{
if (keyCode == Keycode.Back) {
Toast.MakeText (this, "Back button blocked", ToastLength.Short).Show ();
return false;
}
Toast.MakeText (this, "Button press allowed", ToastLength.Short).Show ();
return true;
}
you can handle that in the OnBackPressed() event.

Override android headset hook long press

I need to override the android heaset hook button, the long press causes the music player starts auntomatically and I need to avoid this.
Is it possible in Android?
I try:
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
return true;
}
return false;
}
But it not works.
Thanks,
It is possible to just create your own gesture recognition to account for a long press. You can start a timer on KeyDown and then check that timer on KeyUp to see if the key up was at or lower than your long press time. Or you can use the getEventTime methods to do the same function. If your question was more specific on how to intercept the headset buttons I would recommend this article, Allowing applications to play nice(r) with each other: Handling remote control buttons.
If you need some other kind of help or some code samples let me know

How to handle KeyEvent of home button in an Android application?

I'm developing an application in Android, and I use the the following code to handle the KeyEvent for the back button:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
How would I go about doing this for the home button?
You can not control the behaviour of Home key. You will not get the event of Home key but you can disable it but it is highly recommended you should not do this.Before blocking the Home key refer this post.
However you can block the home key like this:
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
As this question suggests: Android Overriding home key this is unfortunately not possible. Perhaps there is some other way to implement your desired behavior?
Obvious answer is - handle home key press in onPause() method of your activity. This callback is called when user hits home key. Guaranted. Home key is not for you, but
for OS and user.
Read these :
Overriding the Home button - how do I get rid of the choice?
Android - How to catch that the Home button was pressed?
The home button is supposed to do one thing and one thing only and consistently. Get the user back to the the HOME screen. Even if you could override it's behavior it would be an extremely user-unfriendly thing to do. So don't do it and solve your problem differently!strong text

How to prevent the soft keyboard from ever appearing in my Activity?

I'm writing an Android game that runs in fullscreen landscape mode, and has buttons placed at the bottom left and bottom right of the window. The problem is that one of these buttons is (on many phones) right next to the Menu button, so the player might accidentally press Menu instead.
If it is pressed briefly, I simply pause the game and show the in-game menu. No problem there.
But if the button is held down longer, Android opens up the soft keyboard on the bottom half of the screen. Since it gets in the way, and is completely useless in this Activity, I would like to disable it.
I tried the following approaches.
Via InputMethodManager
From: Hide soft keyboard on activity without any keyboard operations
Since I have only one view (a GLSurfaceView) I tried this in my Activity.onCreate():
InputMethodManager imm = ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE));
imm.hideSoftInputFromInputMethod(glSurfaceView.getApplicationWindowToken(), 0);
It doesn't work: the soft keyboard still comes up on Menu long-press.
Via the AndroidManifest.xml
From: How to stop the android soft keyboard from ever coming up in my entire application
I added this to my manifest:
<activity
android:windowSoftInputMode="stateAlwaysHidden"
>
Does a great deal of nothing as well.
So... is there even a way? How?
Here is, at least, a solution to my immediate problem. It shows the in-game menu, no matter how long the button was pressed.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
event.startTracking();
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyLongPress(int keyCode, KeyEvent event) {
// From the docs:
// "Note that in order to receive this callback, someone in the event [chain]
// must return true from onKeyDown(int, KeyEvent) and call startTracking() on the event."
if (keyCode == KeyEvent.KEYCODE_MENU) {
// Override default handling, and don't pop up the soft keyboard.
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU) {
openOptionsMenu();
return true;
}
return super.onKeyUp(keyCode, event);
}
But it feels like a hack, so I'm hoping that someone comes up with a better solution.
But if the button is held down longer,
Android opens up the soft keyboard on
the bottom half of the screen.
What phone do you have? Are you sure? I've never once seen that happen and I just tried it and it doesn't work on my phone.
Also, that sounds like a user problem. Don't try to subvert the user. If the user REALLY wants to open a keyboard in your app, you should let them and if it's useless, they'll hit back and it will go away.
A more concerning issue should be that your buttons are so close to the menu buttons.
Try using hideSoftInputFromWindow() instead. According to the documentation:
request to hide the soft input window from the context of the window that is currently accepting input.
use android:windowSoftInputMode="adjustPan" in android manifest.
I think this is best choice to prevent the view goes up.

Key Events in TabActivities?

I have a TabActivity and want to catch and handle presses of HOME and BACK. Where do I need to catch these events?
In my subclass of TabActivity I implement the following:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
// Code handling
}
return super.onKeyDown(keyCode, event);
}
Didn't work.
So I placed a breakpoint on the switch statement line. But this function never gets called, whether I press volume up/down, menu, home, or back. Where do I need to catch these KeyEvents?
It turns out to be pretty easy. Add the following code to your child tab activity :
#Override
public void onBackPressed() {
this.getParent().onBackPressed();
}
Then in the TabActivity do the real logic:
#Override
public void onBackPressed() {
// Called by children
}
Otherwise, the children will intercept and consume the event without notifying the tab host.
I had the same issue and found overriding dispatchKeyEvent worked.
An example of which can be found here for back button press:
http://android-developers.blogspot.com/2009/12/back-and-other-hard-keys-three-stories.html
Each tab's Activity handled the "back" presses.
I have a TabActivity and want to catch
and handle presses of HOME and BACK.
Where do I need to catch these events?
You cannot "handle presses of HOME", ever.
With respect to BACK, you can use onKeyDown() (for Android 1.x) or onBackPressed() (for Android 2.x). However, your TabActivity may be too late. For example, if you have activities as the contents of your tabs, it may be that one of them is catching the BACK press and arranging for normal processing (i.e., closing up of the activity). Since I avoid activities-as-tabs like the plague (except for one book example), I have not experimented with BACK button processing in that scenario.
try this in your oncreate()
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
setDefaultKeyMode(DEFAULT_KEYS_SEARCH_GLOBAL);

Categories

Resources