diff --git a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler.java b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler.java index 6db3c95c6b..a1b6766235 100644 --- a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler.java +++ b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler.java @@ -58,6 +58,8 @@ public class AndroidInputHandler implements View.OnTouchListener, View.OnKeyListener { private static final Logger logger = Logger.getLogger(AndroidInputHandler.class.getName()); + // in API level 11. + private static final int VIRTUAL_KEYBOARD_DEVICE_ID = -1; protected GLSurfaceView view; protected AndroidTouchInput touchInput; @@ -238,7 +240,9 @@ public boolean onKey(View view, int keyCode, KeyEvent event) { // logger.log(Level.INFO, "onKey source: {0}, isTouch: {1}", // new Object[]{source, isTouch}); - if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD && joyInput != null) { + if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD + && joyInput != null + && !isVirtualKeyboardEvent(event)) { joyInput.onKeyboardInput(); } @@ -250,4 +254,15 @@ public boolean onKey(View view, int keyCode, KeyEvent event) { } + /** + * Tests whether a key event identifies a software or on-screen keyboard. + * + * @param event the key event to test + * @return true if the event came from a virtual keyboard + */ + protected boolean isVirtualKeyboardEvent(KeyEvent event) { + int virtualFlags = KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_VIRTUAL_HARD_KEY; + return (event.getFlags() & virtualFlags) != 0 || event.getDeviceId() == VIRTUAL_KEYBOARD_DEVICE_ID; + } + } diff --git a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler14.java b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler14.java index 355d3c55fa..0b37a913ce 100644 --- a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler14.java +++ b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler14.java @@ -179,7 +179,9 @@ public boolean onKey(View view, int keyCode, KeyEvent event) { boolean isUnknown = (source & android.view.InputDevice.SOURCE_UNKNOWN) == android.view.InputDevice.SOURCE_UNKNOWN; - if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD && joyInput != null) { + if ((source & InputDevice.SOURCE_KEYBOARD) == InputDevice.SOURCE_KEYBOARD + && joyInput != null + && !isVirtualKeyboardEvent(event)) { joyInput.onKeyboardInput(); } diff --git a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler16.java b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler16.java new file mode 100644 index 0000000000..6798c853d7 --- /dev/null +++ b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler16.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2009-2026 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.jme3.input.android; + +import android.view.InputDevice; +import android.view.KeyEvent; + +/** + * Extends {@link AndroidInputHandler14} with input-device APIs introduced in + * Android API level 16. + */ +public class AndroidInputHandler16 extends AndroidInputHandler14 { + + @Override + protected boolean isVirtualKeyboardEvent(KeyEvent event) { + if (super.isVirtualKeyboardEvent(event)) { + return true; + } + + InputDevice device = event.getDevice(); + return device != null && device.isVirtual(); + } +} diff --git a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler24.java b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler24.java index ce405ec3f4..511db34b07 100644 --- a/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler24.java +++ b/jme3-android/src/main/java/com/jme3/input/android/AndroidInputHandler24.java @@ -33,13 +33,13 @@ package com.jme3.input.android; /** - * AndroidInputHandler24 extends AndroidInputHandler14 to + * AndroidInputHandler24 extends AndroidInputHandler16 to * use AndroidMouseInput24 which adds usage of newer events and also enables cursor visibility * and cursor image change. * * @author joliver82 */ -public class AndroidInputHandler24 extends AndroidInputHandler14 { +public class AndroidInputHandler24 extends AndroidInputHandler16 { public AndroidInputHandler24() { super(); diff --git a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java index 2dbb590926..6a0571c1b9 100644 --- a/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java +++ b/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java @@ -50,6 +50,7 @@ import com.jme3.input.*; import com.jme3.input.android.AndroidInputHandler; import com.jme3.input.android.AndroidInputHandler14; +import com.jme3.input.android.AndroidInputHandler16; import com.jme3.input.android.AndroidInputHandler24; import com.jme3.input.android.AndroidInputHandler26; import com.jme3.input.controls.SoftTextDialogInputListener; @@ -166,6 +167,8 @@ public GLSurfaceView createView(Context context) { androidInput = new AndroidInputHandler26(); } else if (Build.VERSION.SDK_INT >= 24) { androidInput = new AndroidInputHandler24(); + } else if (Build.VERSION.SDK_INT >= 16) { + androidInput = new AndroidInputHandler16(); } else if (Build.VERSION.SDK_INT >= 14) { androidInput = new AndroidInputHandler14(); } else if (Build.VERSION.SDK_INT >= 9) {