Uploaded image for project: 'Apache Cordova'
  1. Apache Cordova
  2. CB-1146

Application exits if back button is pressed after a soft keyboard hide.

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.0.0
    • Fix Version/s: 2.1.0
    • Component/s: cordova-android
    • Labels:
      None
    • Environment:

      phonegap 2.0.0 on android 2.2 on an olive pad VT-100

      Description

      The back button normally cause CordovaWebView.onKeyUp to be called which typically either dispatches the event to javascript or calls backHistory().

      However if the softkeyboard is displayed and then hidden, and the android back button is then pressed onKeyUp is never called, and the application exits instead.
      (In this case i click on a html text input and either click on the page or press android back button to hide the keyboard.Then i press the android back button to go to the previous page.)

      ----------EDIT FOR CLARITY-----------------
      Just to state the obvious , the current page when i am doing the above is not the first page in history.
      If i don't show/hide the softkeyboard, the back button works perfectly and it goes back in history.
      ----------EDIT FOR CLARITY-----------------

      The log is as follows:
      07-27 10:16:51.627: V/SoftKeyboardDetect(11190): We are in our onMeasure method
      07-27 10:16:51.627: V/SoftKeyboardDetect(11190): Old Height = 455
      07-27 10:16:51.627: V/SoftKeyboardDetect(11190): Height = 173
      07-27 10:16:51.627: V/SoftKeyboardDetect(11190): Old Width = 800
      07-27 10:16:51.627: V/SoftKeyboardDetect(11190): Width = 800
      --keyboard shown event---
      07-27 10:16:52.207: V/SoftKeyboardDetect(11190): We are in our onMeasure method
      07-27 10:16:52.207: V/SoftKeyboardDetect(11190): Old Height = 173
      07-27 10:16:52.207: V/SoftKeyboardDetect(11190): Height = 173
      07-27 10:16:52.207: V/SoftKeyboardDetect(11190): Old Width = 800
      07-27 10:16:52.207: V/SoftKeyboardDetect(11190): Width = 800
      07-27 10:16:52.207: D/SoftKeyboardDetect(11190): Ignore this event
      07-27 10:16:53.357: V/SoftKeyboardDetect(11190): We are in our onMeasure method
      07-27 10:16:53.357: V/SoftKeyboardDetect(11190): Old Height = 173
      07-27 10:16:53.357: V/SoftKeyboardDetect(11190): Height = 173
      07-27 10:16:53.357: V/SoftKeyboardDetect(11190): Old Width = 800
      07-27 10:16:53.357: V/SoftKeyboardDetect(11190): Width = 800
      07-27 10:16:53.357: D/SoftKeyboardDetect(11190): Ignore this event
      07-27 10:16:53.517: V/SoftKeyboardDetect(11190): We are in our onMeasure method
      07-27 10:16:53.527: V/SoftKeyboardDetect(11190): Old Height = 173
      07-27 10:16:53.527: V/SoftKeyboardDetect(11190): Height = 455
      07-27 10:16:53.527: V/SoftKeyboardDetect(11190): Old Width = 800
      07-27 10:16:53.527: V/SoftKeyboardDetect(11190): Width = 800
      -keyboard hide event--
      07-27 10:16:54.297: V/SoftKeyboardDetect(11190): We are in our onMeasure method
      07-27 10:16:54.297: V/SoftKeyboardDetect(11190): Old Height = 455
      07-27 10:16:54.297: V/SoftKeyboardDetect(11190): Height = 455
      07-27 10:16:54.297: V/SoftKeyboardDetect(11190): Old Width = 800
      07-27 10:16:54.297: V/SoftKeyboardDetect(11190): Width = 800
      07-27 10:16:54.297: D/SoftKeyboardDetect(11190): Ignore this event
      07-27 10:16:55.357: W/KeyCharacterMap(11190): Can't open keycharmap file
      07-27 10:16:55.357: W/KeyCharacterMap(11190): Error loading keycharmap file '/system/usr/keychars/PANJIT_Touchscreen.kcm.bin'. hw.keyboards.65537.devname='PANJIT Touchscreen'
      07-27 10:16:55.357: W/KeyCharacterMap(11190): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
      07-27 10:16:55.487: D/CordovaWebView(11190): >>> loadUrlNow()
      07-27 10:16:55.547: V/SoftKeyboardDetect(11190): We are in our onMeasure method
      07-27 10:16:55.547: V/SoftKeyboardDetect(11190): Old Height = 455
      07-27 10:16:55.547: V/SoftKeyboardDetect(11190): Height = 455
      07-27 10:16:55.547: V/SoftKeyboardDetect(11190): Old Width = 800
      07-27 10:16:55.547: V/SoftKeyboardDetect(11190): Width = 800
      07-27 10:16:55.547: D/SoftKeyboardDetect(11190): Ignore this event
      07-27 10:16:55.787: W/IInputConnectionWrapper(11190): showStatusIcon on inactive InputConnection
      ---android back button pressed application exits----
      07-27 10:16:56.157: D/DroidGap(11190): onDestroy()
      07-27 10:16:56.157: D/CordovaWebView(11190): >>> loadUrlNow()
      07-27 10:16:56.157: D/CordovaWebView(11190): >>> loadUrlNow()
      07-27 10:16:56.197: D/DroidGap(11190): onMessage(onPageStarted,about:blank)
      07-27 10:16:56.287: D/Cordova(11190): onPageFinished(about:blank)
      07-27 10:16:56.287: D/DroidGap(11190): onMessage(onPageFinished,about:blank)
      07-27 10:16:56.287: D/DroidGap(11190): onMessage(exit,null)

        Issue Links

          Activity

          Hide
          ajitaranha Ajit Aranha added a comment -

          Just wanted to add that the log in CordovaWebview.java is non-intutive
          // Perhaps the log message should say KeyUp has been triggered
          public boolean onKeyUp(int keyCode, KeyEvent event)
          {

          Log.d(TAG, "KeyDown has been triggered on the view");

          Show
          ajitaranha Ajit Aranha added a comment - Just wanted to add that the log in CordovaWebview.java is non-intutive // Perhaps the log message should say KeyUp has been triggered public boolean onKeyUp(int keyCode, KeyEvent event) { Log.d(TAG, "KeyDown has been triggered on the view");
          Hide
          ajitaranha Ajit Aranha added a comment - - edited

          From my deugging i believe in CordovaWebView.java in the method public boolean onKeyDown(int keyCode, KeyEvent event) the call to super.onKeyDown(keyCode, event) triggers the application exit.

          workaround without modifying phonegap:
          Override onKeyDown/onKeyUp in the app activity class which extends DroidGap.In my scenario i trigger javascript events, and do not delegate anything to super.onKeyXX methods. Hope the workaround does not cause any unexpected behaviour further down the road.

          Show
          ajitaranha Ajit Aranha added a comment - - edited From my deugging i believe in CordovaWebView.java in the method public boolean onKeyDown(int keyCode, KeyEvent event) the call to super.onKeyDown(keyCode, event) triggers the application exit. workaround without modifying phonegap: Override onKeyDown/onKeyUp in the app activity class which extends DroidGap.In my scenario i trigger javascript events, and do not delegate anything to super.onKeyXX methods. Hope the workaround does not cause any unexpected behaviour further down the road.
          Hide
          bowserj Joe Bowser added a comment -

          Unable to reproduce on 4.1.1, moving down Android versions now.

          Show
          bowserj Joe Bowser added a comment - Unable to reproduce on 4.1.1, moving down Android versions now.
          Hide
          bowserj Joe Bowser added a comment -

          Reproducible on Android 4.0.3 on Samsung Galaxy S2

          Show
          bowserj Joe Bowser added a comment - Reproducible on Android 4.0.3 on Samsung Galaxy S2
          Hide
          bowserj Joe Bowser added a comment -

          Added tiny onKeyUp handler that routes all non-back button keypresses to CordovaWebView. The back button is moved there if there's a history, otherwise it does the default action.

          Show
          bowserj Joe Bowser added a comment - Added tiny onKeyUp handler that routes all non-back button keypresses to CordovaWebView. The back button is moved there if there's a history, otherwise it does the default action.
          Hide
          ajitaranha Ajit Aranha added a comment -

          Sharing my workaround, in case it's of any help

          This goes in the activity extends DroidGap class, and should probably have the backHistory() call integrated to be a more generic fix.

          @Override
          public boolean onKeyDown(int keyCode, KeyEvent event)
          {
          LOG.d(TAG, "KeyDown has been triggered on the view"+keyCode);
          //If volumedown key
          if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)

          { // only override default behaviour is event bound LOG.d(TAG, "Down Key Hit"); this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');"); return true; }

          // If volumeup key
          else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)

          { LOG.d(TAG, "Up Key Hit"); this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');"); return true; }

          else

          { //return super.onKeyDown(keyCode, event); }

          //return super.onKeyDown(keyCode, event);
          return true;
          }

          @Override
          public boolean onKeyUp(int keyCode, KeyEvent event)
          {

          LOG.d(TAG, "KeyUp has been triggered on the view"+keyCode);

          // If back key
          if (keyCode == KeyEvent.KEYCODE_BACK)

          { this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');"); return true; }

          // Legacy
          else if (keyCode == KeyEvent.KEYCODE_MENU)

          { this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');"); return true; }

          // If search key
          else if (keyCode == KeyEvent.KEYCODE_SEARCH)

          { this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');"); return true; }

          return false;
          }

          Show
          ajitaranha Ajit Aranha added a comment - Sharing my workaround, in case it's of any help This goes in the activity extends DroidGap class, and should probably have the backHistory() call integrated to be a more generic fix. @Override public boolean onKeyDown(int keyCode, KeyEvent event) { LOG.d(TAG, "KeyDown has been triggered on the view"+keyCode); //If volumedown key if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { // only override default behaviour is event bound LOG.d(TAG, "Down Key Hit"); this.loadUrl("javascript:cordova.fireDocumentEvent('volumedownbutton');"); return true; } // If volumeup key else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { LOG.d(TAG, "Up Key Hit"); this.loadUrl("javascript:cordova.fireDocumentEvent('volumeupbutton');"); return true; } else { //return super.onKeyDown(keyCode, event); } //return super.onKeyDown(keyCode, event); return true; } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { LOG.d(TAG, "KeyUp has been triggered on the view"+keyCode); // If back key if (keyCode == KeyEvent.KEYCODE_BACK) { this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');"); return true; } // Legacy else if (keyCode == KeyEvent.KEYCODE_MENU) { this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');"); return true; } // If search key else if (keyCode == KeyEvent.KEYCODE_SEARCH) { this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');"); return true; } return false; }
          Hide
          ajitaranha Ajit Aranha added a comment -

          Joe, would appreciate it if you could tell me , if i have broken any phonegap functionality by removing the super.onKeyXX delegation.

          Show
          ajitaranha Ajit Aranha added a comment - Joe, would appreciate it if you could tell me , if i have broken any phonegap functionality by removing the super.onKeyXX delegation.
          Hide
          bowserj Joe Bowser added a comment -

          This has been broken again by the removal of onKeyUp

          Show
          bowserj Joe Bowser added a comment - This has been broken again by the removal of onKeyUp
          Hide
          macdonst Simon MacDonald added a comment -

          Joe, this problem is more severe than the double menubutton event. Maybe you should put the code back in and we'll live with the menu button issue until 2.2. Just a thought.

          Show
          macdonst Simon MacDonald added a comment - Joe, this problem is more severe than the double menubutton event. Maybe you should put the code back in and we'll live with the menu button issue until 2.2. Just a thought.
          Hide
          bowserj Joe Bowser added a comment -

          Or I could fix it and we can have both fixed.

          The issue here is the fact that while we are focused on a text area, we are no longer on the WebView, but some crap overlayed on top of the WebView (usually a Text Field). Using HitTestResult, I managed to get the back button working again. The Menu Button is still unresponsive, but since ICS apps aren't even supposed to have that type of menu, that's not as big of a problem. If Android views were less janky, I could do more, but this will have to do for now.

          Show
          bowserj Joe Bowser added a comment - Or I could fix it and we can have both fixed. The issue here is the fact that while we are focused on a text area, we are no longer on the WebView, but some crap overlayed on top of the WebView (usually a Text Field). Using HitTestResult, I managed to get the back button working again. The Menu Button is still unresponsive, but since ICS apps aren't even supposed to have that type of menu, that's not as big of a problem. If Android views were less janky, I could do more, but this will have to do for now.
          Hide
          bowserj Joe Bowser added a comment -

          Added code to handle this back into 2.1.0rc2

          Show
          bowserj Joe Bowser added a comment - Added code to handle this back into 2.1.0rc2
          Hide
          macdonst Simon MacDonald added a comment -

          You da man. We definitely want this in for 2.1.

          Show
          macdonst Simon MacDonald added a comment - You da man. We definitely want this in for 2.1.
          Hide
          zzeepo Serhiy Solonko added a comment -

          This problem wasn't solved. I can reproduce it on 2.3.* devices and on Cordova 2.2 version.

          Show
          zzeepo Serhiy Solonko added a comment - This problem wasn't solved. I can reproduce it on 2.3.* devices and on Cordova 2.2 version.
          Hide
          zzeepo Serhiy Solonko added a comment - - edited

          Create project with input, button. Press on input -> type anything -> press backbutton (close softkeyboard) -> then press button -> and again quickly press backbutton -> application will be closed unexpectedly

          Show
          zzeepo Serhiy Solonko added a comment - - edited Create project with input, button. Press on input -> type anything -> press backbutton (close softkeyboard) -> then press button -> and again quickly press backbutton -> application will be closed unexpectedly

            People

            • Assignee:
              bowserj Joe Bowser
              Reporter:
              ajitaranha Ajit Aranha
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development