ionic-team / ionic-framework

A powerful cross-platform UI toolkit for building native-quality iOS, Android, and Progressive Web Apps with HTML, CSS, and JavaScript.
https://ionicframework.com
MIT License
51.03k stars 13.51k forks source link

bug: Hardware back button closes app on Android #23200

Closed orjandh closed 3 years ago

orjandh commented 3 years ago

Bug Report

Ionic version:

[x] 5.x

Current behavior:

When pressing the hardware back button on an Ionic app before doing anything else, it will close the app. This does not happen if you interact with the app in any way first, like touching somewhere on the screen.

Expected behavior:

I would expect the app to not close?

Steps to reproduce:

  1. Create a new cordova project with ionic cli
  2. Run ionic cordova run android
  3. Press hardware back button
  4. App should now close

Related code:

Other information:

I do not know if this is an Ionic issue or if the problem lies somewhere else, but I thought I would give a heads up. Also this doesn't seem to be listed in the hardware back button consolidated list of issues.

Ionic info:

Ionic:

   Ionic CLI                     : 6.13.1 (C:\Users\<user>\AppData\Roaming\npm\node_modules\@ionic\cli)
   Ionic Framework               : @ionic/angular 5.6.4
   @angular-devkit/build-angular : 0.1102.8
   @angular-devkit/schematics    : 11.2.8
   @angular/cli                  : 11.1.4
   @ionic/angular-toolkit        : 3.1.1

Cordova:

   Cordova CLI       : 10.0.0
   Cordova Platforms : android 9.0.0
   Cordova Plugins   : not available

Utility:

   cordova-res : not installed
   native-run  : 1.3.0

System:

   Android SDK Tools : 26.1.1 (C:\AndroidSDK)
   NodeJS            : v15.11.0 (C:\Program Files\nodejs\node.exe)
   npm               : 7.6.0
   OS                : Windows 10
liamdebeasi commented 3 years ago

Thanks for the issue. What device and Android version are you testing this on?

liamdebeasi commented 3 years ago

Actually this might be the default Cordova behavior according to https://cordova.apache.org/docs/en/10.x/cordova/events/events.html#backbutton. Does it fix the issue if you do the following:

import { Platform } from '@ionic/angular';

...

constructor(private platform: Platform) {
  this.platform.backButton.subscribeWithPriority(10, () => {
    console.log('Handler was called!');
  });
}
orjandh commented 3 years ago

Sorry, I forgot to mention the Android version. This happens both on the Android emulator running Android 9 (API 28) and my Samsung device running Android 11. Adding a back button handler to the constructor of the app component does not seem to make any difference.

liamdebeasi commented 3 years ago

Thanks. Can you reproduce this in an Ionic starter app and provide a link to the repo? When I tried previously I was not seeing this on my end.

orjandh commented 3 years ago

This is basically just the starting template created from ionic start, but here's the repo. https://github.com/orjandh/ionic_bug

liamdebeasi commented 3 years ago

I can reproduce this behavior, though only on newer versions of Android. In addition, I can reproduce this in a regular Angular app without Ionic Framework, so I need to do some more digging to see what could be causing this issue.

MafiaCartel commented 3 years ago

Using this.platform.backButton.subscribe(() => { this.location.back(); }); Or this.platform.backButton.subscribeWithPriority(10000, () => { this.location.back(); });

None actually works on my Android 11 Pixel 2, no matter what i try App will just close.

liamdebeasi commented 3 years ago

The problem here is that the cordova.js file is never getting added to the built index.html file in your application. Without loading in this file, the hardware back button will not work as intended.

This file is only added if you add the Cordova Android platform via the Ionic CLI. You will need to run ionic cordova platform add android. Note that doing just cordova platform add android will not work as that is not run through the Ionic CLI.

If you have already run cordova platform add android in your application, I recommend creating a new Ionic app via the Ionic CLI and running ionic cordova platform add android. Following these steps resolved the issue on my end.

I am going to close this as this is not a bug in Ionic Framework.

edit: I know the original issue says "Run ionic cordova run android" but I was able to resolve the issue in a blank Ionic starter app, so it is possible there is something else going on in https://github.com/orjandh/ionic_bug. Either way, I recommend running ionic cordova platform add android in a fresh starter application.

mindstorm38 commented 3 years ago

I have the same issue, with Capacitor on Pixel android emulator. I've already tested some fixes using this.platform.backButton.subscribe[...] but none of these worked. The application keeps closing even if many routes are in the history.

Even with the following test, construct app is actually sent which means that subscribe is called, but back is never called.

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html',
    styleUrls: ['app.component.scss'],
})
export class AppComponent {

    constructor(
        private platform: Platform
    ) {
        console.log("construct app");
        this.platform.backButton.subscribeWithPriority(10, () => {
            console.log("back");
        });
    }

}
mindstorm38 commented 3 years ago

@liamdebeasi You should consider reopening this issue since the issue also happen on native Android phone (not only emulator). This is really annoying and might come from the recent capacitor version (3.0.0-rc.3, should I consider open an issue on capacitor page ?).

liamdebeasi commented 3 years ago

The problem here is related to Cordova-specific files not being loaded into your app. These files are not needed for Capacitor. If you suspect there is a bug in the latest Capacitor 3 RC I recommend opening an issue on the Capacitor repo: https://github.com/ionic-team/capacitor

mindstorm38 commented 3 years ago

I figured out that Capacitor v3 removed the event handling for backbutton event, you can find more info here, but I think this will become a problem for the compatibility with future versions of Ionic.

liamdebeasi commented 3 years ago

Thanks! I will chat with the Capacitor team and update this thread.

liamdebeasi commented 3 years ago

Are you migrating from Capacitor v2 to Capacitor v3? If so, make sure you have followed all of the migration steps: https://capacitorjs.com/docs/v3/updating/3-0

In particular, make sure you switch to automatic Android plugin loading: https://capacitorjs.com/docs/v3/updating/3-0#switch-to-automatic-android-plugin-loading

This file can be found in android/app/src/main/java/[YOUR APP BUNDLE]/MainActivity.java

mindstorm38 commented 3 years ago

Yes I followed these steps, I no longer have deprecated calls even in my internal plugin, everything looks fine.

liamdebeasi commented 3 years ago

Can you provide a GitHub link to your application?

mindstorm38 commented 3 years ago

The repository is stored on a private GitLab, so I can't, but if you have a specific request I should know how to give you the info (like structure, activity code).

liamdebeasi commented 3 years ago

Can you reproduce the specific issue in an Ionic starter application so that you do not have to share your private code? Otherwise it is going to be difficult to determine what the issue may be.

mindstorm38 commented 3 years ago

I will do that, thank you for the support!

mindstorm38 commented 3 years ago

Ok, so I detail the procedure:

> ionic start
? Framework: Angular
? Project name: ionic-backbutton-test
? Starter template: sidemenu
√ Preparing directory .\ionic-backbutton-test in 1.53ms
[...]
> cd .\ionic-backbutton-test\
> ionic build
> ionic cap add android
> ionic cap run android
[...]
[info] Opening Android project at D:\dev\projects\ionic-backbutton-test\android

image At this point, the application works fine and the back button never close the application. For exemple in when I use back button when the side menu is opened, it is closed, and if I spam back button after that nothing happen which is expected.

Note that the start application use capacitor 2.4.7 and ionic 5.5.2.

So, now I upgrade capacitor to the "next" version (currently 3.0.0-rc.3):

> npm i @capacitor/android@next @capacitor/core@next @capacitor/cli@next
added 29 packages, removed 26 packages, changed 4 packages, and audited 1706 packages in 8s
[...]
> ionic cap sync
> ionic cap run android

After that, gradle scripts are updated, and I fix the MainActivity.java file by removing this.init as intended. So I re-run the application in my emulator: the hardware back button now close the application even if the side menu is opened.

Just to see if the latest (5.6.7) ionic version fix that, I tried:

> npm i @ionic/angular@latest
> ionic cap run android

This doesn't fix the problem!

liamdebeasi commented 3 years ago

Did you add the App plugin? https://capacitorjs.com/docs/v3/updating/3-0#migrating-your-app-to-use-the-new-official-plugin-packages

For best performance with Ionic Framework, you should make sure these plugins are installed even if you don’t import them in your app:

npm install @capacitor/app @capacitor/haptics @capacitor/keyboard
mindstorm38 commented 3 years ago

Hmmmm okay, capacitor/app actually implement the backbutton event dispatch... I missed this part of the migration documentation all afternoon ... Sorry :(

liamdebeasi commented 3 years ago

No problem, glad the issue is resolved 😄

ionitron-bot[bot] commented 3 years ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.