This is an automated email from the ASF dual-hosted git repository.
GitToTheHub pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-android.git
The following commit(s) were added to refs/heads/master by this push:
new 0bfbc20b fix: overwritten backbutton not firing on first time by
hardware button and never on back gesture (#1910)
0bfbc20b is described below
commit 0bfbc20b84ce83be72a3e7dd6a5bff38f0fcbff2
Author: Manuel Beck <[email protected]>
AuthorDate: Mon Apr 20 17:48:48 2026 +0200
fix: overwritten backbutton not firing on first time by hardware button and
never on back gesture (#1910)
- When pressing the back button after the app starts nothing happens. When
navigating to another page, the back button js event starts to fire.
- On Android versions, which support the back gesture, nothing happens
- This was due to the empty `OnBackPressedCallback.handleOnBackPressed`
method, which has to forward its call to
`cordova.getActivity().getOnBackPressedDispatcher().onBackPressed()`, but has
to disable during this call the `backCallback`.
- Generated-By: GPT-5.4, GitHub Copilot Chat
- warning about back button override on the right
* chore: resolve methods `registerBackPressedCallback` and
`unregisterBackPressedCallback``
- The code moved to inline code
---
framework/src/org/apache/cordova/CoreAndroid.java | 55 +++++++++++++----------
1 file changed, 32 insertions(+), 23 deletions(-)
diff --git a/framework/src/org/apache/cordova/CoreAndroid.java
b/framework/src/org/apache/cordova/CoreAndroid.java
index a41b85db..969cc296 100755
--- a/framework/src/org/apache/cordova/CoreAndroid.java
+++ b/framework/src/org/apache/cordova/CoreAndroid.java
@@ -29,6 +29,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
+import android.os.SystemClock;
import android.content.IntentFilter;
import android.telephony.TelephonyManager;
import android.view.KeyEvent;
@@ -253,7 +254,6 @@ public class CoreAndroid extends CordovaPlugin {
* @param override T=override, F=cancel override
*/
public void overrideBackbutton(boolean override) {
- LOG.i("App", "WARNING: Back Button Default Behavior will be
overridden. The backbutton event will be fired!");
if (cordova.getActivity() == null) {
return;
}
@@ -263,15 +263,24 @@ public class CoreAndroid extends CordovaPlugin {
@Override
public void run() {
if (shouldOverride) {
+ LOG.i("App", "WARNING: Back Button Default Behavior will
be overridden. The backbutton event will be fired!");
synchronized (backButtonHandlerLock) {
if (backCallback == null) {
- registerBackPressedCallback();
+ backCallback = new OnBackPressedCallback(true) {
+ @Override
+ public void handleOnBackPressed() {
+ dispatchBackKeyEvent();
+ }
+ };
+ OnBackPressedDispatcherOwner
backPressedDispatcherOwner = cordova.getActivity();
+
backPressedDispatcherOwner.getOnBackPressedDispatcher().addCallback(backPressedDispatcherOwner,
backCallback);
}
}
} else {
synchronized (backButtonHandlerLock) {
if (backCallback != null) {
- unregisterBackPressedCallback();
+ backCallback.remove();
+ backCallback = null;
}
}
}
@@ -281,29 +290,29 @@ public class CoreAndroid extends CordovaPlugin {
});
}
- /**
- * Registers an AndroidX back callback so Cordova can keep routing back
presses through its
- * existing key dispatch path across Android versions without directly
referencing newer
- * platform-only back APIs.
- */
- private void registerBackPressedCallback() {
- final OnBackPressedDispatcherOwner backPressedDispatcherOwner =
this.cordova.getActivity();
+ private void dispatchBackKeyEvent() {
+ // Build a synthetic BACK key press (DOWN + UP) and route it through
the WebView.
+ // This lets Cordova's existing key handling fire the JS "backbutton"
event.
+ final long eventTime = SystemClock.uptimeMillis();
+ final KeyEvent downEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0);
+ final KeyEvent upEvent = new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK, 0);
- backCallback = new OnBackPressedCallback(true) {
- @Override
- public void handleOnBackPressed() {
- // Intentionally empty.
- // On modern Android versions, registering a callback keeps
back handling
- // routed through Cordova's existing key dispatch path.
- }
- };
+ final boolean handledDown =
webView.getView().dispatchKeyEvent(downEvent);
+ final boolean handledUp = webView.getView().dispatchKeyEvent(upEvent);
-
backPressedDispatcherOwner.getOnBackPressedDispatcher().addCallback(backPressedDispatcherOwner,
backCallback);
- }
+ // If either event was consumed, Cordova/WebView already handled back
behavior.
+ if (handledDown || handledUp) {
+ return;
+ }
- private void unregisterBackPressedCallback() {
- backCallback.remove();
- backCallback = null;
+ // Otherwise, delegate to Android's default back dispatcher.
+ // Temporarily disable this callback to avoid recursive re-entry.
+ backCallback.setEnabled(false);
+ try {
+ cordova.getActivity().getOnBackPressedDispatcher().onBackPressed();
+ } finally {
+ backCallback.setEnabled(true);
+ }
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]