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) {