[Android] Fix handling of back navigation when targeting API level 36

This commit is contained in:
Fredia Huya-Kouadio
2026-03-19 13:35:54 -07:00
parent 06c3946e35
commit ea070aceec
7 changed files with 118 additions and 13 deletions
@@ -122,6 +122,15 @@ class Godot private constructor(val context: Context) {
internal fun isEditorBuild() = BuildConfig.FLAVOR == EDITOR_FLAVOR
}
/**
* Describes the engine current run status.
*/
enum class RunStatus {
INITIALIZING,
STARTED,
TERMINATING
}
private val mSensorManager: SensorManager? by lazy { context.getSystemService(Context.SENSOR_SERVICE) as? SensorManager }
private val mClipboard: ClipboardManager? by lazy { context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager }
private val vibratorService: Vibrator? by lazy { context.getSystemService(Context.VIBRATOR_SERVICE) as? Vibrator }
@@ -185,9 +194,11 @@ class Godot private constructor(val context: Context) {
private var resumed = false
/**
* Tracks whether [onGodotSetupCompleted] fired.
* Tracks the engine's run status.
*/
private val godotMainLoopStarted = AtomicBoolean(false)
private val _runStatus = AtomicReference<RunStatus>(RunStatus.INITIALIZING)
val runStatus: RunStatus
get() = _runStatus.get()
val io = GodotIO(this)
@@ -697,7 +708,7 @@ class Godot private constructor(val context: Context) {
}
private fun registerSensorsIfNeeded() {
if (!resumed || !godotMainLoopStarted.get()) {
if (!resumed || runStatus != RunStatus.STARTED) {
return
}
@@ -858,7 +869,7 @@ class Godot private constructor(val context: Context) {
*/
private fun onGodotMainLoopStarted() {
Log.v(TAG, "OnGodotMainLoopStarted")
godotMainLoopStarted.set(true)
_runStatus.set(RunStatus.STARTED)
accelerometerEnabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_accelerometer")))
gravityEnabled.set(java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/sensors/enable_gravity")))
@@ -881,6 +892,11 @@ class Godot private constructor(val context: Context) {
@Keep
private fun onGodotTerminating() {
Log.v(TAG, "OnGodotTerminating")
_runStatus.set(RunStatus.TERMINATING)
for (plugin in pluginRegistry.allPlugins) {
plugin.onGodotTerminating()
}
runOnTerminate.get()?.run()
}
@@ -41,6 +41,7 @@ import android.os.Bundle
import android.util.Log
import android.util.Rational
import android.view.View
import androidx.activity.addCallback
import androidx.annotation.CallSuper
import androidx.annotation.LayoutRes
import androidx.fragment.app.FragmentActivity
@@ -54,7 +55,7 @@ import java.util.concurrent.atomic.AtomicReference
/**
* Base abstract activity for Android apps intending to use Godot as the primary screen.
*
* Also a reference implementation for how to setup and use the [GodotFragment] fragment
* Also a reference implementation for how to set up and use the [GodotFragment] fragment
* within an Android app.
*/
abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPictureProvider {
@@ -133,6 +134,9 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
setContentView(getGodotAppLayout())
// Register `OnBackPressedCallback` for the Godot fragment.
onBackPressedDispatcher.addCallback { godotFragment?.onBackPressed() }
handleStartIntent(intent, true)
val currentFragment = supportFragmentManager.findFragmentById(R.id.godot_fragment_container)
@@ -283,10 +287,6 @@ abstract class GodotActivity : FragmentActivity(), GodotHost, PictureInPicturePr
}
}
override fun onBackPressed() {
godotFragment?.onBackPressed() ?: super.onBackPressed()
}
override fun getActivity(): Activity? {
return this
}
@@ -235,6 +235,11 @@ public abstract class GodotPlugin {
*/
public void onGodotMainLoopStarted() {}
/**
* Invoked on the render thread when the Godot engine is terminating.
*/
public void onGodotTerminating() {}
/**
* When using the OpenGL renderer, this is invoked once per frame on the GL thread after the
* frame is drawn.
@@ -414,7 +419,7 @@ public abstract class GodotPlugin {
Object signalArg = signalArgs[i];
if (signalArg != null && !signalParamTypes[i].isInstance(signalArg)) {
throw new IllegalArgumentException(
"Invalid type for argument #" + i + ". Should be of type " + signalParamTypes[i].getName());
"Invalid type for argument #" + i + ". Should be of type '" + signalParamTypes[i].getName() + "' but is of type '" + signalArg.getClass().getName() + "'.");
}
}