Skip to content

Commit 4313238

Browse files
riccardoblCopilot
andcommitted
android fixup
Co-authored-by: Copilot <copilot@github.com>
1 parent 5af1548 commit 4313238

53 files changed

Lines changed: 2612 additions & 2047 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,56 @@ task configureAndroidNDK {
182182
ndkBuildFile = "ndk-build.cmd"
183183
}
184184

185-
// ndkPath is defined in the root project gradle.properties file
186-
String ndkBuildPath = ndkPath + File.separator + ndkBuildFile
187-
//Use the environment variable for the NDK location if defined
188-
if (System.env.ANDROID_NDK != null) {
189-
ndkBuildPath = System.env.ANDROID_NDK + File.separator + ndkBuildFile
185+
def ndkCandidates = []
186+
if (System.env.ANDROID_NDK) {
187+
ndkCandidates << file(System.env.ANDROID_NDK)
188+
}
189+
if (System.env.ANDROID_NDK_HOME) {
190+
ndkCandidates << file(System.env.ANDROID_NDK_HOME)
191+
}
192+
if (project.hasProperty('ndkPath') && ndkPath) {
193+
ndkCandidates << file(ndkPath)
190194
}
191195

192-
if (new File(ndkBuildPath).exists()) {
196+
def localProperties = file('local.properties')
197+
if (localProperties.isFile()) {
198+
Properties properties = new Properties()
199+
localProperties.withInputStream { properties.load(it) }
200+
if (properties.getProperty('ndk.dir')) {
201+
ndkCandidates << file(properties.getProperty('ndk.dir'))
202+
}
203+
if (properties.getProperty('sdk.dir')) {
204+
ndkCandidates.addAll(findAndroidNdkDirs(file(properties.getProperty('sdk.dir'))))
205+
}
206+
}
207+
208+
if (System.env.ANDROID_HOME) {
209+
ndkCandidates.addAll(findAndroidNdkDirs(file(System.env.ANDROID_HOME)))
210+
}
211+
if (System.env.ANDROID_SDK_ROOT) {
212+
ndkCandidates.addAll(findAndroidNdkDirs(file(System.env.ANDROID_SDK_ROOT)))
213+
}
214+
ndkCandidates.addAll(findAndroidNdkDirs(file("${System.properties['user.home']}/Android/Sdk")))
215+
216+
def ndkBuildPath = ndkCandidates.collect { new File(it, ndkBuildFile) }.find { it.isFile() }
217+
if (ndkBuildPath != null) {
193218
ndkExists = true
194-
ndkCommandPath = ndkBuildPath
219+
ndkCommandPath = ndkBuildPath.absolutePath
220+
}
221+
}
222+
223+
def findAndroidNdkDirs(File sdkDir) {
224+
def ndkDirs = []
225+
def nestedSdkDir = new File(sdkDir, 'Sdk')
226+
if (nestedSdkDir.isDirectory()) {
227+
ndkDirs.addAll(findAndroidNdkDirs(nestedSdkDir))
228+
}
229+
def sideBySideDir = new File(sdkDir, 'ndk')
230+
if (sideBySideDir.isDirectory()) {
231+
ndkDirs.addAll(sideBySideDir.listFiles()?.findAll { it.isDirectory() }?.sort { a, b -> b.name <=> a.name } ?: [])
195232
}
233+
ndkDirs << new File(sdkDir, 'ndk-bundle')
234+
return ndkDirs
196235
}
197236

198237
gradle.rootProject.ext.set("usePrebuildNatives", buildNativeProjects!="true");

common-android-app.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ version = jmeFullVersion
66
repositories {
77
mavenCentral()
88
maven {
9-
url "http://nifty-gui.sourceforge.net/nifty-maven-repo"
9+
url "https://nifty-gui.sourceforge.net/nifty-maven-repo"
1010
}
1111
}

gradle/jacoco.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ reporting {
6161

6262
def jacocoSubprojects = subprojects.findAll { p ->
6363
(p.file("src/main/java").exists() || p.file("src/main/groovy").exists()) &&
64-
(p.file("src/test/java").exists() || p.file("src/test/groovy").exists())
64+
(p.file("src/test/java").exists() || p.file("src/test/groovy").exists()) &&
65+
p.tasks.findByName('test') &&
66+
p.tasks.findByName('jacocoTestReport')
6567
}
6668

6769
dependencies {

gradle/libs.versions.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ spotbugs = "4.9.8"
1111
[libraries]
1212

1313
androidx-annotation = "androidx.annotation:annotation:1.7.1"
14+
androidx-fragment = "androidx.fragment:fragment:1.8.9"
1415
androidx-lifecycle-common = "androidx.lifecycle:lifecycle-common:2.7.0"
1516
android-build-gradle = "com.android.tools.build:gradle:9.1.0"
1617
android-support-appcompat = "com.android.support:appcompat-v7:28.0.0"
18+
androidx-test-runner = "androidx.test:runner:1.7.0"
1719
gradle-git = "org.ajoberstar:gradle-git:1.2.0"
1820
groovy-test = "org.apache.groovy:groovy-test:4.0.31"
1921
gson = "com.google.code.gson:gson:2.13.2"
@@ -23,6 +25,7 @@ jinput = "net.java.jinput:jinput:2.0.9"
2325
jna = "net.java.dev.jna:jna:5.18.1"
2426
jnaerator-runtime = "com.nativelibs4java:jnaerator-runtime:0.12"
2527
junit-bom = "org.junit:junit-bom:5.13.4"
28+
junit4 = "junit:junit:4.13.2"
2629
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" }
2730
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" }
2831
lwjgl2 = "org.jmonkeyengine:lwjgl:2.9.5"

jme3-android-examples/build.gradle

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
apply plugin: 'com.android.application'
22

3+
def examplesJar = project(':jme3-examples').tasks.named('jar')
4+
35
android {
46
namespace "org.jmonkeyengine.jme3androidexamples"
57
compileSdk 34
@@ -16,12 +18,13 @@ android {
1618
targetSdk 34 // Android 14
1719
versionCode 1
1820
versionName "1.0" // TODO: from settings.gradle
21+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1922
}
2023

2124
buildTypes {
2225
release {
2326
minifyEnabled false
24-
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
27+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
2528
}
2629
}
2730

@@ -40,23 +43,106 @@ android {
4043
srcDir '../jme3-testdata/src/main/resources'
4144
srcDir '../jme3-examples/src/main/resources'
4245
}
46+
jniLibs {
47+
srcDir '../build/native/openalsoft'
48+
srcDir '../build/native/decode'
49+
srcDir '../build/native/allocator'
50+
}
4351
}
4452
}
4553
}
4654

4755
dependencies {
4856
implementation fileTree(dir: 'libs', include: ['*.jar'])
49-
testImplementation libs.junit4
50-
implementation libs.androidx.appcompat
51-
57+
testImplementation platform(libs.junit.bom)
58+
testImplementation libs.junit.jupiter
59+
testRuntimeOnly libs.junit.platform.launcher
60+
androidTestImplementation libs.junit4
61+
androidTestImplementation libs.androidx.test.runner
62+
implementation libs.androidx.fragment
5263
implementation project(':jme3-core')
5364
implementation project(':jme3-android')
5465
implementation project(':jme3-android-native')
5566
implementation project(':jme3-effects')
5667
implementation project(':jme3-jbullet')
68+
implementation project(':jme3-jogg')
5769
implementation project(':jme3-networking')
5870
implementation project(':jme3-niftygui')
5971
implementation project(':jme3-plugins')
72+
implementation project(':jme3-plugins-json')
73+
implementation project(':jme3-plugins-json-gson')
6074
implementation project(':jme3-terrain')
61-
implementation fileTree(dir: '../jme3-examples/build/libs', include: ['*.jar'], exclude: ['*sources*.*'])
75+
implementation files(examplesJar.flatMap { it.archiveFile })
76+
}
77+
78+
tasks.named('preBuild') {
79+
dependsOn examplesJar
80+
if (buildNativeProjects == "true") {
81+
dependsOn ':jme3-android-native:updatePreCompiledOpenAlSoftLibs'
82+
dependsOn ':jme3-android-native:updatePreCompiledLibs'
83+
dependsOn ':jme3-android-native:updatePreCompiledLibsBufferAllocator'
84+
} else if (skipPrebuildLibraries != "true") {
85+
dependsOn ':jme3-android-native:copyPreCompiledOpenAlSoftLibs'
86+
dependsOn ':jme3-android-native:copyPreCompiledLibs'
87+
dependsOn ':jme3-android-native:copyPreCompiledLibsBufferAllocator'
88+
}
89+
}
90+
91+
tasks.register('installAndroidExamples', Exec) {
92+
group = 'application'
93+
description = 'Install the Android examples selector on a connected emulator or device.'
94+
95+
dependsOn tasks.named('assembleDebug')
96+
97+
doFirst {
98+
def adbExecutable = findAdbExecutable()
99+
if (adbExecutable == null) {
100+
throw new GradleException("ADB not found. Set -Pandroid.sdk.path, ANDROID_HOME, or ANDROID_SDK_ROOT.")
101+
}
102+
def apkFile = layout.buildDirectory.file('outputs/apk/debug/jme3-android-examples-debug.apk').get().asFile
103+
if (!apkFile.isFile()) {
104+
throw new GradleException("Debug APK not found at ${apkFile}.")
105+
}
106+
executable adbExecutable.absolutePath
107+
args 'install', '-r', apkFile.absolutePath
108+
}
109+
}
110+
111+
tasks.register('runAndroidExamples', Exec) {
112+
group = 'application'
113+
description = 'Install and launch the Android examples selector on a connected emulator or device.'
114+
115+
dependsOn tasks.named('installAndroidExamples')
116+
117+
doFirst {
118+
def adbExecutable = findAdbExecutable()
119+
if (adbExecutable == null) {
120+
throw new GradleException("ADB not found. Set -Pandroid.sdk.path, ANDROID_HOME, or ANDROID_SDK_ROOT.")
121+
}
122+
executable adbExecutable.absolutePath
123+
}
124+
125+
args 'shell', 'am', 'start',
126+
'-n', 'org.jmonkeyengine.jme3androidexamples/.MainActivity'
127+
}
128+
129+
def findAdbExecutable() {
130+
def adbName = System.properties['os.name'].toLowerCase().contains('windows') ? 'adb.exe' : 'adb'
131+
def sdkDirs = []
132+
if (project.findProperty('android.sdk.path')) {
133+
sdkDirs << file(project.findProperty('android.sdk.path'))
134+
}
135+
if (System.env.ANDROID_HOME) {
136+
sdkDirs << file(System.env.ANDROID_HOME)
137+
}
138+
if (System.env.ANDROID_SDK_ROOT) {
139+
sdkDirs << file(System.env.ANDROID_SDK_ROOT)
140+
}
141+
sdkDirs << file("${System.properties['user.home']}/Android/Sdk")
142+
143+
def expandedSdkDirs = sdkDirs.collectMany { sdkDir ->
144+
[sdkDir, new File(sdkDir, 'Sdk')]
145+
}.unique { it.absolutePath }
146+
147+
return expandedSdkDirs.collect { new File(new File(it, 'platform-tools'), adbName) }.find { it.isFile() }
62148
}
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package org.jmonkeyengine.jme3androidexamples;
22

3-
import android.app.Application;
4-
import android.test.ApplicationTestCase;
3+
import androidx.test.platform.app.InstrumentationRegistry;
4+
import org.junit.Test;
5+
6+
import static org.junit.Assert.assertEquals;
57

68
/**
79
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
810
*/
9-
public class ApplicationTest extends ApplicationTestCase<Application> {
10-
public ApplicationTest() {
11-
super(Application.class);
11+
public class ApplicationTest {
12+
@Test
13+
public void testApplicationPackage() {
14+
String packageName = InstrumentationRegistry.getInstrumentation()
15+
.getTargetContext()
16+
.getPackageName();
17+
assertEquals("org.jmonkeyengine.jme3androidexamples", packageName);
1218
}
13-
}
19+
}

jme3-android-examples/src/main/AndroidManifest.xml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
android:theme="@style/AppTheme">
1010
<activity
1111
android:name=".MainActivity"
12+
android:exported="true"
1213
android:label="@string/app_name"
1314
android:launchMode="singleTask">
1415
<intent-filter>
@@ -25,9 +26,9 @@
2526
</activity>
2627
</application>
2728

28-
<!-- Tell the system that you need ES 2.0. -->
29+
<!-- Tell the system that you need ES 3.0. -->
2930
<uses-feature
30-
android:glEsVersion="0x00020000"
31+
android:glEsVersion="0x00030000"
3132
android:required="true"/>
3233

3334
<!-- Tell the system that you need distinct touches (for the zoom gesture). -->
@@ -41,6 +42,7 @@
4142
android:normalScreens="true"
4243
android:smallScreens="true"/>
4344

45+
<uses-permission android:name="android.permission.INTERNET"/>
4446
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
4547
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
4648
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

jme3-android-examples/src/main/java/org/jmonkeyengine/jme3androidexamples/JmeFragment.java

Lines changed: 27 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,23 @@
22

33
import android.os.Bundle;
44
import com.jme3.app.AndroidHarnessFragment;
5+
import com.jme3.app.LegacyApplication;
6+
import com.jme3.system.AppSettings;
57
import java.util.logging.Level;
68
import java.util.logging.LogManager;
79

810
/**
911
* A placeholder fragment containing a jME GLSurfaceView.
1012
*/
1113
public class JmeFragment extends AndroidHarnessFragment {
14+
private String appClass;
15+
private boolean joystickEventsEnabled;
16+
private boolean keyEventsEnabled = true;
17+
private boolean mouseEventsEnabled = true;
1218

1319
public JmeFragment() {
14-
// Set the desired EGL configuration
15-
eglBitsPerPixel = 24;
16-
eglAlphaBits = 0;
17-
eglDepthBits = 16;
18-
eglSamples = 0;
19-
eglStencilBits = 0;
20-
21-
// Set the maximum framerate
22-
// (default = -1 for unlimited)
23-
frameRate = -1;
24-
25-
// Set the maximum resolution dimension
26-
// (the smaller side, height or width, is set automatically
27-
// to maintain the original device screen aspect ratio)
28-
// (default = -1 to match device screen resolution)
29-
maxResolutionDimension = -1;
30-
31-
/*
32-
Skip these settings and use the settings stored in the Bundle retrieved during onCreate.
33-
34-
// Set main project class (fully qualified path)
35-
appClass = "";
36-
37-
// Set input configuration settings
38-
joystickEventsEnabled = false;
39-
keyEventsEnabled = true;
40-
mouseEventsEnabled = true;
41-
*/
42-
43-
// Set application exit settings
4420
finishOnAppStop = true;
45-
handleExitHook = true;
46-
exitDialogTitle = "Do you want to exit?";
47-
exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it.";
48-
49-
// Set splash screen resource id, if used
50-
// (default = 0, no splash screen)
51-
// For example, if the image file name is "splash"...
52-
// splashPicID = R.drawable.splash;
53-
splashPicID = 0;
54-
// splashPicID = R.drawable.android_splash;
55-
56-
// Set the default logging level (default=Level.INFO, Level.ALL=All Debug Info)
5721
LogManager.getLogManager().getLogger("").setLevel(Level.INFO);
58-
5922
}
6023

6124
@Override
@@ -82,4 +45,25 @@ public void onCreate(Bundle savedInstanceState) {
8245

8346
super.onCreate(savedInstanceState);
8447
}
48+
49+
@Override
50+
protected LegacyApplication createApplication() throws Exception {
51+
Class<?> clazz = Class.forName(appClass);
52+
return (LegacyApplication) clazz.getDeclaredConstructor().newInstance();
53+
}
54+
55+
@Override
56+
protected void configureSettings(AppSettings settings) {
57+
settings.setEmulateMouse(mouseEventsEnabled);
58+
settings.setUseJoysticks(joystickEventsEnabled);
59+
settings.setEmulateKeyboard(keyEventsEnabled);
60+
61+
settings.setBitsPerPixel(24);
62+
settings.setAlphaBits(0);
63+
settings.setGammaCorrection(true);
64+
settings.setDepthBits(16);
65+
settings.setSamples(4);
66+
settings.setStencilBits(0);
67+
settings.setFrameRate(-1);
68+
}
8569
}

0 commit comments

Comments
 (0)