4

I have a game that uses a callback to Java from C++ to force open the soft keyboard when the user touches the screen. The Java code is simply this:

this._inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

This has worked fine for a while but recently we've been receiving complaints from some Motorola Droid users that the soft keyboard fails to open for them. Since we've only recently started to get these complaints and it's a number of users I'm thinking it was some kind of update to those devices.

Is there a better way I can force the keyboard to open? All the links I find online talk about using textbox controls and such but my app is primarily C++ and doesn't use the standard controls at all.

Nick Gotch
  • 9,167
  • 14
  • 70
  • 97

1 Answers1

7

I don't know if this is related to your problem, but I was running into some issues using only InputMethodManager.toggleSoftInput() when devices would sometimes get "out of sync" and hide when I wanted to show and vice versa.

I've had some success by taking advantage of the fact that while IMM.showSoftInput() won't show a keyboard, IMM.hideSoftInputFromWindow() will reliably close one, so when I want to show a keyboard I now call IMM.hideSoftInputFromWindow() followed by IMM.toggleSoftInput(), and use IMM.hideSoftInputFromWindow() by itself to hide one.

[A day later...]

Writing the above yesterday made me rethink how I was dealing with the soft keyboard (I mean, showSoftinput() does work, just not the way we expected it to) and so here is a better way to do it:

First, you need to set up your view so that Android knows it can have a soft keyboard - described in the docs for InputMethodManager. In my case I have a single view derived from GLSurfaceView and so I added:

setFocusable(true);
setFocusableInTouchMode(true);

to the constructor and then the following 2 overrides:

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs)
{
    outAttrs.actionLabel = "";
    outAttrs.hintText = "";
    outAttrs.initialCapsMode = 0;
    outAttrs.initialSelEnd = outAttrs.initialSelStart = -1;
    outAttrs.label = "";
    outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI;        
    outAttrs.inputType = InputType.TYPE_NULL;        

    return  new BaseInputConnection(this, false);       
}     

@Override
public boolean onCheckIsTextEditor ()
{
    return true;
}

Now I can show the keyboard with:

InputMethodManager mgr = (InputMethodManager)mActivity.getSystemService(Context.INPUT_METHOD_SERVICE); 
mgr.showSoftInput(mView, 0);

and the keypresses get reported via the view's onKeyUp() and onKeyDown() methods.

Hiding it is still done using hideSoftInputFromWindow()

jimkberry
  • 1,317
  • 7
  • 8
  • This is the best suggestion I've heard. Unfortunately I can't test this on devices actually experiencing the problem since we don't have any but I'm going to try this out. If it works I'll mark this as the answer then. Thanks! – Nick Gotch Sep 22 '11 at 23:42
  • Tried this and a few variations on it but the issue is still showing up on the Droid Bionic. Nothing I do seems to successfully manage to open up the soft keyboard on that device. – Nick Gotch Oct 14 '11 at 17:31
  • Do you have access to a Bionic? I'd really be curious if the keyboard works on it for "PocketSat3 Demo" (free from the Market). The app starts up with a keyboard compatibility test. – jimkberry Oct 20 '11 at 21:14
  • I don't have one myself; I know a fellow developer who tests this for me. – Nick Gotch Oct 21 '11 at 08:46
  • Getting rid of keyUp and keyDown in activity, and using this method solved the issues with keyboard lag. (its rendered on top of the game window, lag was very annoying!) – FDIM Jan 23 '14 at 21:35