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]

Reply via email to