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.
Related
I'm trying to detect when the soft keyboard gets closed, I found this code snippet
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
//detects that keyboard was hidden
}
return super.onKeyPreIme(keyCode, event);
}
but this needs to be added to a subclass that extends editText, I'm not intrested in implementing the functionality I want to add on keyboard hidden in all my app, I want to add it for just one Activity, I tried onKeyDown, onKeyBack, onKeyUp, onBackPressed nothing seems to log the back press that closes the soft keyboard.
so my question is there a way to detect the click on the button that hides the keybaord?
I am working on an app and i want it to be such that when the user presses home then nothing should happen. Is it possible to accomplish that? If that is not possible then is it possible that some other action is performed when hone is pressed. the whole idea is user should not leave the app directly from any screen.
update:can someone tell me how to define my app as launcher?
No, you cannot. Whenever Home button is pressed, the framework will always throw you back on android's home screen. Sorry, you are out of luck. :)
you cant make it work as you want, but you can disable it
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
and you can tell user that home button is disabled:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_HOME) {
Context context = getApplicationContext();
Toast toast = Toast.makeText(context,"Home button is disabled",1);
toast.setGravity(Gravity.CENTER_VERTICAL,0,0);
toast.show();
return true;
}
return super.onKeyDown(keyCode, event);
}
I am working on an app and i want it to be such that when the user presses home then nothing should happen. Is it possible to accomplish that?
Make your app be the home screen. The user can still remove your app by rebooting in safe mode.
I've made the logic for showing a confirm dialog when the user press back button by overriding backPressed method, but this implies an unusual behaviour. If soft input keyboard is shown, on back key event, it must be hidden and other back key event must launch the confirmation dialog. There is a way to achieve this? Maybe by detecting if soft input keyboard is up and bypass the confirmation dialog?
Here is a code sample to make this clear:
public boolean onKeyUp(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK)
{
//here is the mystery
if (soft keyboard is visible)
{
return super.onKeyUp(keyCode, event);
} else
{
//method which shows the close dialog and close the application
onBackPressed();
return true;
}
}
return super.onKeyUp(keyCode, event);
}
if soft keyboard is shown ,I don't think Activity can receive back key event. the default behaviour is back key make soft keyboard disappear.
View also can block key event, the simple way is setOnKeyListener. make sure that your View is focusable and when it receive back key event just return true .
Code to hide the softkey pad :
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
you can put this code onBackKeyPressed no matter keyboard is showing or not
When calling my PreferenceActivity from a screen, and after pressing the Back button, the return screen is always the main screen (the activity that shows after app start) of the application. Is it possible to go back to the previous screen?
I tried to solve it through overriding the onKeyDown (inside my PreferenceActivity class) method without luck:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return super.onKeyDown(keyCode, event);
}
Thanks in advance for any help.
Assuming you use Activities/Intents as designed, there's actually no special code required. Pushing back will automatically stop the current activity, and go back to the activity which called it. See the Android Activity and Task guide.
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);
}