From 431323814c4e827bdf24722bed05219ac8c6ed8e Mon Sep 17 00:00:00 2001 From: Riccardo Balbo Date: Wed, 29 Apr 2026 23:16:10 +0200 Subject: [PATCH 1/5] android fixup Co-authored-by: Copilot --- build.gradle | 53 +- common-android-app.gradle | 2 +- gradle/jacoco.gradle | 4 +- gradle/libs.versions.toml | 3 + jme3-android-examples/build.gradle | 96 ++- .../jme3androidexamples/ApplicationTest.java | 18 +- .../src/main/AndroidManifest.xml | 6 +- .../jme3androidexamples/JmeFragment.java | 70 +- .../jme3androidexamples/MainActivity.java | 67 +- .../jme3androidexamples/TestActivity.java | 20 +- .../res/layout-land/test_chooser_layout.xml | 97 +++ .../src/main/res/layout/test_chooser_row.xml | 24 +- .../src/main/res/menu/menu_items.xml | 9 +- .../src/main/res/menu/test_menu_items.xml | 3 +- .../src/main/res/values/styles.xml | 8 +- jme3-android/build.gradle | 20 + .../java/androidx/fragment/app/Fragment.java | 94 +++ .../fragment/app/FragmentActivity.java | 43 ++ .../java/com/jme3/app/AndroidHarness.java | 592 ----------------- .../com/jme3/app/AndroidHarnessFragment.java | 578 +++------------- .../com/jme3/renderer/android/AndroidGL.java | 13 + .../system/android/AndroidConfigChooser.java | 602 ++++++----------- .../com/jme3/system/android/OGLESContext.java | 253 ++++++- .../jme3/environment/EnvironmentCamera.java | 46 +- .../environment/EnvironmentProbeControl.java | 5 +- .../environment/FastLightProbeFactory.java | 2 +- .../jme3/environment/LightProbeFactory.java | 7 +- .../environment/baker/GenericEnvBaker.java | 20 +- .../baker/IBLHybridEnvBakerLight.java | 2 +- .../com/jme3/post/FilterPostProcessor.java | 11 +- .../main/java/com/jme3/post/HDRRenderer.java | 4 +- .../src/main/java/com/jme3/renderer/Caps.java | 101 ++- .../main/java/com/jme3/renderer/Renderer.java | 50 +- .../java/com/jme3/renderer/opengl/GLExt.java | 23 + .../jme3/renderer/opengl/GLImageFormat.java | 54 +- .../jme3/renderer/opengl/GLImageFormats.java | 390 ++++++----- .../com/jme3/renderer/opengl/GLRenderer.java | 261 ++++++-- .../java/com/jme3/texture/FrameBuffer.java | 5 +- .../src/main/java/com/jme3/texture/Image.java | 48 +- .../com/jme3/texture/image/ImageCodec.java | 20 +- .../com/jme3/texture/image/ImageRaster.java | 21 +- .../jme3/texture/image/LastTextureState.java | 2 + .../java/com/jme3/util/MipMapGenerator.java | 621 ++++++++++++++++-- .../resources/Common/MatDefs/Blit/Blit.frag | 21 + .../resources/Common/MatDefs/Blit/Blit.j3md | 24 + .../resources/Common/MatDefs/Blit/Blit.vert | 11 + .../renderer/opengl/GLImageFormatsTest.java | 105 +++ .../bullet/debug/BulletDebugAppState.java | 30 +- .../com/jme3/bullet/debug/DebugTools.java | 30 +- .../jme3/bullet/util/DebugShapeFactory.java | 31 +- .../test/PreventBulletIssueRegressions.java | 17 +- .../com/jme3/renderer/lwjgl/LwjglGLExt.java | 12 + .../com/jme3/renderer/lwjgl/LwjglGLExt.java | 10 + 53 files changed, 2612 insertions(+), 2047 deletions(-) create mode 100644 jme3-android-examples/src/main/res/layout-land/test_chooser_layout.xml create mode 100644 jme3-android/src/androidx-stubs/java/androidx/fragment/app/Fragment.java create mode 100644 jme3-android/src/androidx-stubs/java/androidx/fragment/app/FragmentActivity.java delete mode 100644 jme3-android/src/main/java/com/jme3/app/AndroidHarness.java create mode 100644 jme3-core/src/main/resources/Common/MatDefs/Blit/Blit.frag create mode 100644 jme3-core/src/main/resources/Common/MatDefs/Blit/Blit.j3md create mode 100644 jme3-core/src/main/resources/Common/MatDefs/Blit/Blit.vert create mode 100644 jme3-core/src/test/java/com/jme3/renderer/opengl/GLImageFormatsTest.java diff --git a/build.gradle b/build.gradle index 113b992314..8dade8c48e 100644 --- a/build.gradle +++ b/build.gradle @@ -182,17 +182,56 @@ task configureAndroidNDK { ndkBuildFile = "ndk-build.cmd" } - // ndkPath is defined in the root project gradle.properties file - String ndkBuildPath = ndkPath + File.separator + ndkBuildFile - //Use the environment variable for the NDK location if defined - if (System.env.ANDROID_NDK != null) { - ndkBuildPath = System.env.ANDROID_NDK + File.separator + ndkBuildFile + def ndkCandidates = [] + if (System.env.ANDROID_NDK) { + ndkCandidates << file(System.env.ANDROID_NDK) + } + if (System.env.ANDROID_NDK_HOME) { + ndkCandidates << file(System.env.ANDROID_NDK_HOME) + } + if (project.hasProperty('ndkPath') && ndkPath) { + ndkCandidates << file(ndkPath) } - if (new File(ndkBuildPath).exists()) { + def localProperties = file('local.properties') + if (localProperties.isFile()) { + Properties properties = new Properties() + localProperties.withInputStream { properties.load(it) } + if (properties.getProperty('ndk.dir')) { + ndkCandidates << file(properties.getProperty('ndk.dir')) + } + if (properties.getProperty('sdk.dir')) { + ndkCandidates.addAll(findAndroidNdkDirs(file(properties.getProperty('sdk.dir')))) + } + } + + if (System.env.ANDROID_HOME) { + ndkCandidates.addAll(findAndroidNdkDirs(file(System.env.ANDROID_HOME))) + } + if (System.env.ANDROID_SDK_ROOT) { + ndkCandidates.addAll(findAndroidNdkDirs(file(System.env.ANDROID_SDK_ROOT))) + } + ndkCandidates.addAll(findAndroidNdkDirs(file("${System.properties['user.home']}/Android/Sdk"))) + + def ndkBuildPath = ndkCandidates.collect { new File(it, ndkBuildFile) }.find { it.isFile() } + if (ndkBuildPath != null) { ndkExists = true - ndkCommandPath = ndkBuildPath + ndkCommandPath = ndkBuildPath.absolutePath + } +} + +def findAndroidNdkDirs(File sdkDir) { + def ndkDirs = [] + def nestedSdkDir = new File(sdkDir, 'Sdk') + if (nestedSdkDir.isDirectory()) { + ndkDirs.addAll(findAndroidNdkDirs(nestedSdkDir)) + } + def sideBySideDir = new File(sdkDir, 'ndk') + if (sideBySideDir.isDirectory()) { + ndkDirs.addAll(sideBySideDir.listFiles()?.findAll { it.isDirectory() }?.sort { a, b -> b.name <=> a.name } ?: []) } + ndkDirs << new File(sdkDir, 'ndk-bundle') + return ndkDirs } gradle.rootProject.ext.set("usePrebuildNatives", buildNativeProjects!="true"); diff --git a/common-android-app.gradle b/common-android-app.gradle index 703536bd27..8670bf7e78 100644 --- a/common-android-app.gradle +++ b/common-android-app.gradle @@ -6,6 +6,6 @@ version = jmeFullVersion repositories { mavenCentral() maven { - url "http://nifty-gui.sourceforge.net/nifty-maven-repo" + url "https://nifty-gui.sourceforge.net/nifty-maven-repo" } } diff --git a/gradle/jacoco.gradle b/gradle/jacoco.gradle index f7f2e48481..5491d4eb55 100644 --- a/gradle/jacoco.gradle +++ b/gradle/jacoco.gradle @@ -61,7 +61,9 @@ reporting { def jacocoSubprojects = subprojects.findAll { p -> (p.file("src/main/java").exists() || p.file("src/main/groovy").exists()) && - (p.file("src/test/java").exists() || p.file("src/test/groovy").exists()) + (p.file("src/test/java").exists() || p.file("src/test/groovy").exists()) && + p.tasks.findByName('test') && + p.tasks.findByName('jacocoTestReport') } dependencies { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5151b44419..830a8d203a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,9 +11,11 @@ spotbugs = "4.9.8" [libraries] androidx-annotation = "androidx.annotation:annotation:1.7.1" +androidx-fragment = "androidx.fragment:fragment:1.8.9" androidx-lifecycle-common = "androidx.lifecycle:lifecycle-common:2.7.0" android-build-gradle = "com.android.tools.build:gradle:9.1.0" android-support-appcompat = "com.android.support:appcompat-v7:28.0.0" +androidx-test-runner = "androidx.test:runner:1.7.0" gradle-git = "org.ajoberstar:gradle-git:1.2.0" groovy-test = "org.apache.groovy:groovy-test:4.0.31" gson = "com.google.code.gson:gson:2.13.2" @@ -23,6 +25,7 @@ jinput = "net.java.jinput:jinput:2.0.9" jna = "net.java.dev.jna:jna:5.18.1" jnaerator-runtime = "com.nativelibs4java:jnaerator-runtime:0.12" junit-bom = "org.junit:junit-bom:5.13.4" +junit4 = "junit:junit:4.13.2" junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" } junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } lwjgl2 = "org.jmonkeyengine:lwjgl:2.9.5" diff --git a/jme3-android-examples/build.gradle b/jme3-android-examples/build.gradle index 66c591a931..2aeab98640 100644 --- a/jme3-android-examples/build.gradle +++ b/jme3-android-examples/build.gradle @@ -1,5 +1,7 @@ apply plugin: 'com.android.application' +def examplesJar = project(':jme3-examples').tasks.named('jar') + android { namespace "org.jmonkeyengine.jme3androidexamples" compileSdk 34 @@ -16,12 +18,13 @@ android { targetSdk 34 // Android 14 versionCode 1 versionName "1.0" // TODO: from settings.gradle + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -40,23 +43,106 @@ android { srcDir '../jme3-testdata/src/main/resources' srcDir '../jme3-examples/src/main/resources' } + jniLibs { + srcDir '../build/native/openalsoft' + srcDir '../build/native/decode' + srcDir '../build/native/allocator' + } } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - testImplementation libs.junit4 - implementation libs.androidx.appcompat - + testImplementation platform(libs.junit.bom) + testImplementation libs.junit.jupiter + testRuntimeOnly libs.junit.platform.launcher + androidTestImplementation libs.junit4 + androidTestImplementation libs.androidx.test.runner + implementation libs.androidx.fragment implementation project(':jme3-core') implementation project(':jme3-android') implementation project(':jme3-android-native') implementation project(':jme3-effects') implementation project(':jme3-jbullet') + implementation project(':jme3-jogg') implementation project(':jme3-networking') implementation project(':jme3-niftygui') implementation project(':jme3-plugins') + implementation project(':jme3-plugins-json') + implementation project(':jme3-plugins-json-gson') implementation project(':jme3-terrain') - implementation fileTree(dir: '../jme3-examples/build/libs', include: ['*.jar'], exclude: ['*sources*.*']) + implementation files(examplesJar.flatMap { it.archiveFile }) +} + +tasks.named('preBuild') { + dependsOn examplesJar + if (buildNativeProjects == "true") { + dependsOn ':jme3-android-native:updatePreCompiledOpenAlSoftLibs' + dependsOn ':jme3-android-native:updatePreCompiledLibs' + dependsOn ':jme3-android-native:updatePreCompiledLibsBufferAllocator' + } else if (skipPrebuildLibraries != "true") { + dependsOn ':jme3-android-native:copyPreCompiledOpenAlSoftLibs' + dependsOn ':jme3-android-native:copyPreCompiledLibs' + dependsOn ':jme3-android-native:copyPreCompiledLibsBufferAllocator' + } +} + +tasks.register('installAndroidExamples', Exec) { + group = 'application' + description = 'Install the Android examples selector on a connected emulator or device.' + + dependsOn tasks.named('assembleDebug') + + doFirst { + def adbExecutable = findAdbExecutable() + if (adbExecutable == null) { + throw new GradleException("ADB not found. Set -Pandroid.sdk.path, ANDROID_HOME, or ANDROID_SDK_ROOT.") + } + def apkFile = layout.buildDirectory.file('outputs/apk/debug/jme3-android-examples-debug.apk').get().asFile + if (!apkFile.isFile()) { + throw new GradleException("Debug APK not found at ${apkFile}.") + } + executable adbExecutable.absolutePath + args 'install', '-r', apkFile.absolutePath + } +} + +tasks.register('runAndroidExamples', Exec) { + group = 'application' + description = 'Install and launch the Android examples selector on a connected emulator or device.' + + dependsOn tasks.named('installAndroidExamples') + + doFirst { + def adbExecutable = findAdbExecutable() + if (adbExecutable == null) { + throw new GradleException("ADB not found. Set -Pandroid.sdk.path, ANDROID_HOME, or ANDROID_SDK_ROOT.") + } + executable adbExecutable.absolutePath + } + + args 'shell', 'am', 'start', + '-n', 'org.jmonkeyengine.jme3androidexamples/.MainActivity' +} + +def findAdbExecutable() { + def adbName = System.properties['os.name'].toLowerCase().contains('windows') ? 'adb.exe' : 'adb' + def sdkDirs = [] + if (project.findProperty('android.sdk.path')) { + sdkDirs << file(project.findProperty('android.sdk.path')) + } + if (System.env.ANDROID_HOME) { + sdkDirs << file(System.env.ANDROID_HOME) + } + if (System.env.ANDROID_SDK_ROOT) { + sdkDirs << file(System.env.ANDROID_SDK_ROOT) + } + sdkDirs << file("${System.properties['user.home']}/Android/Sdk") + + def expandedSdkDirs = sdkDirs.collectMany { sdkDir -> + [sdkDir, new File(sdkDir, 'Sdk')] + }.unique { it.absolutePath } + + return expandedSdkDirs.collect { new File(new File(it, 'platform-tools'), adbName) }.find { it.isFile() } } diff --git a/jme3-android-examples/src/androidTest/java/org/jmonkeyengine/jme3androidexamples/ApplicationTest.java b/jme3-android-examples/src/androidTest/java/org/jmonkeyengine/jme3androidexamples/ApplicationTest.java index dff82ddb86..b10ebf4789 100644 --- a/jme3-android-examples/src/androidTest/java/org/jmonkeyengine/jme3androidexamples/ApplicationTest.java +++ b/jme3-android-examples/src/androidTest/java/org/jmonkeyengine/jme3androidexamples/ApplicationTest.java @@ -1,13 +1,19 @@ package org.jmonkeyengine.jme3androidexamples; -import android.app.Application; -import android.test.ApplicationTestCase; +import androidx.test.platform.app.InstrumentationRegistry; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; /** * Testing Fundamentals */ -public class ApplicationTest extends ApplicationTestCase { - public ApplicationTest() { - super(Application.class); +public class ApplicationTest { + @Test + public void testApplicationPackage() { + String packageName = InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getPackageName(); + assertEquals("org.jmonkeyengine.jme3androidexamples", packageName); } -} \ No newline at end of file +} diff --git a/jme3-android-examples/src/main/AndroidManifest.xml b/jme3-android-examples/src/main/AndroidManifest.xml index 95789aa79c..541dfdc356 100644 --- a/jme3-android-examples/src/main/AndroidManifest.xml +++ b/jme3-android-examples/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ android:theme="@style/AppTheme"> @@ -25,9 +26,9 @@ - + @@ -41,6 +42,7 @@ android:normalScreens="true" android:smallScreens="true"/> + diff --git a/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/JmeFragment.java b/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/JmeFragment.java index 0e2faeea3a..3a3e399930 100644 --- a/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/JmeFragment.java +++ b/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/JmeFragment.java @@ -2,6 +2,8 @@ import android.os.Bundle; import com.jme3.app.AndroidHarnessFragment; +import com.jme3.app.LegacyApplication; +import com.jme3.system.AppSettings; import java.util.logging.Level; import java.util.logging.LogManager; @@ -9,53 +11,14 @@ * A placeholder fragment containing a jME GLSurfaceView. */ public class JmeFragment extends AndroidHarnessFragment { + private String appClass; + private boolean joystickEventsEnabled; + private boolean keyEventsEnabled = true; + private boolean mouseEventsEnabled = true; public JmeFragment() { - // Set the desired EGL configuration - eglBitsPerPixel = 24; - eglAlphaBits = 0; - eglDepthBits = 16; - eglSamples = 0; - eglStencilBits = 0; - - // Set the maximum framerate - // (default = -1 for unlimited) - frameRate = -1; - - // Set the maximum resolution dimension - // (the smaller side, height or width, is set automatically - // to maintain the original device screen aspect ratio) - // (default = -1 to match device screen resolution) - maxResolutionDimension = -1; - - /* - Skip these settings and use the settings stored in the Bundle retrieved during onCreate. - - // Set main project class (fully qualified path) - appClass = ""; - - // Set input configuration settings - joystickEventsEnabled = false; - keyEventsEnabled = true; - mouseEventsEnabled = true; - */ - - // Set application exit settings finishOnAppStop = true; - handleExitHook = true; - exitDialogTitle = "Do you want to exit?"; - exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it."; - - // Set splash screen resource id, if used - // (default = 0, no splash screen) - // For example, if the image file name is "splash"... - // splashPicID = R.drawable.splash; - splashPicID = 0; -// splashPicID = R.drawable.android_splash; - - // Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info) LogManager.getLogManager().getLogger("").setLevel(Level.INFO); - } @Override @@ -82,4 +45,25 @@ public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } + + @Override + protected LegacyApplication createApplication() throws Exception { + Class clazz = Class.forName(appClass); + return (LegacyApplication) clazz.getDeclaredConstructor().newInstance(); + } + + @Override + protected void configureSettings(AppSettings settings) { + settings.setEmulateMouse(mouseEventsEnabled); + settings.setUseJoysticks(joystickEventsEnabled); + settings.setEmulateKeyboard(keyEventsEnabled); + + settings.setBitsPerPixel(24); + settings.setAlphaBits(0); + settings.setGammaCorrection(true); + settings.setDepthBits(16); + settings.setSamples(4); + settings.setStencilBits(0); + settings.setFrameRate(-1); + } } diff --git a/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/MainActivity.java b/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/MainActivity.java index d02f7527ca..960e53bc43 100644 --- a/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/MainActivity.java +++ b/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/MainActivity.java @@ -2,8 +2,8 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; +import android.app.Activity; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.text.Editable; import android.text.TextWatcher; import android.util.Log; @@ -20,6 +20,7 @@ import dalvik.system.DexFile; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.List; @@ -30,7 +31,7 @@ * applications that are started via TestsHarness Activity. * @author iwgeric */ -public class MainActivity extends AppCompatActivity implements OnItemClickListener, View.OnClickListener, TextWatcher { +public class MainActivity extends Activity implements OnItemClickListener, View.OnClickListener, TextWatcher { private static final String TAG = "MainActivity"; /** @@ -127,13 +128,14 @@ public void onCreate(Bundle savedInstanceState) { editFilterText = (EditText) findViewById(R.id.txtFilter); - /* Define the root package to start with */ + /* Define the root package shared by the desktop and Android examples. */ rootPackage = "jme3test"; /* Create an array of Strings to define which classes to exclude */ exclusions.add("$"); // inner classes exclusions.add("TestChooser"); // Desktop test chooser class exclusions.add("awt"); // Desktop test chooser class + exclusions.add("package-info"); // mExclusions.add(""); @@ -147,24 +149,25 @@ public void onCreate(Bundle savedInstanceState) { ApplicationInfo ai = this.getApplicationInfo(); String classPath = ai.sourceDir; DexFile dex = null; - Enumeration apkClassNames = null; try { dex = new DexFile(classPath); - apkClassNames = dex.entries(); + Enumeration apkClassNames = dex.entries(); while (apkClassNames.hasMoreElements()) { String className = apkClassNames.nextElement(); - if (checkClassName(className) && checkClassType(className)) { + if (checkClassName(className) && checkClassType(className) && !classNames.contains(className)) { classNames.add(className); } -// classNames.add(className); } + Collections.sort(classNames); } catch (IOException e) { e.printStackTrace(); } finally { - try { - dex.close(); - } catch (IOException e) { - e.printStackTrace(); + if (dex != null) { + try { + dex.close(); + } catch (IOException e) { + e.printStackTrace(); + } } } @@ -286,7 +289,7 @@ private boolean checkClassName(String className) { private boolean checkClassType(String className) { boolean include = true; try { - Class clazz = Class.forName(className); + Class clazz = Class.forName(className, false, getClassLoader()); if (Application.class.isAssignableFrom(clazz)) { Log.d(TAG, "Class " + className + " is a jME Application"); } else { @@ -294,9 +297,9 @@ private boolean checkClassType(String className) { Log.d(TAG, "Skipping Class " + className + ". Not a jME Application"); } - } catch (NoClassDefFoundError ncdf) { + } catch (LinkageError ncdf) { include = false; - Log.d(TAG, "Skipping Class " + className + ". No Class Def found."); + Log.d(TAG, "Skipping Class " + className + ". Could not link class."); } catch (ClassNotFoundException cnfe) { include = false; Log.d(TAG, "Skipping Class " + className + ". Class not found."); @@ -430,29 +433,25 @@ public boolean onPrepareOptionsMenu (Menu menu) { @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.optionMouseEvents: - enableMouseEvents = !enableMouseEvents; - Log.d(TAG, "enableMouseEvents set to: " + enableMouseEvents); - break; - case R.id.optionJoystickEvents: - enableJoystickEvents = !enableJoystickEvents; - Log.d(TAG, "enableJoystickEvents set to: " + enableJoystickEvents); - break; - case R.id.optionKeyEvents: - enableKeyEvents = !enableKeyEvents; - Log.d(TAG, "enableKeyEvents set to: " + enableKeyEvents); - break; - case R.id.optionVerboseLogging: - verboseLogging = !verboseLogging; - Log.d(TAG, "verboseLogging set to: " + verboseLogging); - break; - default: - return super.onOptionsItemSelected(item); + int itemId = item.getItemId(); + if (itemId == R.id.optionMouseEvents) { + enableMouseEvents = !enableMouseEvents; + Log.d(TAG, "enableMouseEvents set to: " + enableMouseEvents); + } else if (itemId == R.id.optionJoystickEvents) { + enableJoystickEvents = !enableJoystickEvents; + Log.d(TAG, "enableJoystickEvents set to: " + enableJoystickEvents); + } else if (itemId == R.id.optionKeyEvents) { + enableKeyEvents = !enableKeyEvents; + Log.d(TAG, "enableKeyEvents set to: " + enableKeyEvents); + } else if (itemId == R.id.optionVerboseLogging) { + verboseLogging = !verboseLogging; + Log.d(TAG, "verboseLogging set to: " + verboseLogging); + } else { + return super.onOptionsItemSelected(item); } return true; } -} \ No newline at end of file +} diff --git a/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/TestActivity.java b/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/TestActivity.java index 70e7075705..1251c94118 100644 --- a/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/TestActivity.java +++ b/jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/TestActivity.java @@ -1,14 +1,14 @@ package org.jmonkeyengine.jme3androidexamples; -import android.app.FragmentTransaction; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; +import androidx.fragment.app.FragmentActivity; +import androidx.fragment.app.FragmentTransaction; import com.jme3.system.JmeSystem; -public class TestActivity extends AppCompatActivity { +public class TestActivity extends FragmentActivity { JmeFragment fragment; @Override @@ -49,7 +49,7 @@ protected void onCreate(Bundle savedInstanceState) { fragment.setArguments(args); - FragmentTransaction transaction = getFragmentManager().beginTransaction(); + FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack so the user can navigate back @@ -83,13 +83,11 @@ public boolean onPrepareOptionsMenu (Menu menu) { @Override public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.optionToggleKeyboard: - toggleKeyboard(true); -// Log.d(this.getClass().getSimpleName(), "showing soft keyboard"); - break; - default: - return super.onOptionsItemSelected(item); + if (item.getItemId() == R.id.optionToggleKeyboard) { + toggleKeyboard(true); +// Log.d(this.getClass().getSimpleName(), "showing soft keyboard"); + } else { + return super.onOptionsItemSelected(item); } return true; diff --git a/jme3-android-examples/src/main/res/layout-land/test_chooser_layout.xml b/jme3-android-examples/src/main/res/layout-land/test_chooser_layout.xml new file mode 100644 index 0000000000..4285fa3c5f --- /dev/null +++ b/jme3-android-examples/src/main/res/layout-land/test_chooser_layout.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + +