Hardware Backbutton Service

Hi, im trying to implement a service for the hardware backbutton to get something like fintonic “double press to exit”.

This register my action:

    registerAction(fn, p) {
        this._deregisterFn = this._platform.registerBackButtonAction(() => {
            fn();
        }, p);
    }

Cause this returns a function to unregister the action i store it, so when i try to unregister my action its just:

deregisterAction() {
    this._deregisterFn && this._deregisterFn();
}

And i have a function to handle two taps:

    doubleBackToExit() {
        if (!this._didBackAlready) {
            this._didBackAlready = true;
            this._presentToast("Press back button again to exit");
            setTimeout(() => this._didBackAlready = false, 2000);
            return;
        }
        this._platform.exitApp();
    }

But when i call this functions:

    ionViewDidEnter() {
        this._backBtn.registerAction(() => {
          this._backBtn.doubleBackToExit();
        }, 101);
    }

    ionViewWillLeave() {
        this._backBtn.deregisterAction();
    }

I use priority 101 cause following ionic 1 priorities but i also tried to use the default value (0) but it seems like it overrides all priorities ( dont close the sidemenu or a modal).

What i am doing wrong?

Well you were so fast! Ill made my own answer with the reason.

i was dealing with hardware backbuttons few days and now, after asing mike (from ionic) i know whats the problem.

The problem is that they dont have priorities hierachy. By default there is only one action with default priority value (0) and that action handle everything.

So if you want to add custom actions you need to add the default code action in your action if not you will be overriding and will not close sidemenu for example.

I have a demo (https://github.com/Fdom92/ionic2-hardware-backbutton) on github with a backbutton service and a sidemenu with two pages. In page 1 i have a double click to exit app and on page 2 the default, on both pages i handle the sidemenu to close instead of show the toast.

For the moment not handle modals but i want to add it asap.

hope this can help you.

Maybe this can be of help

oooh so thats how you get approot to see if there is modals:

this.app._appRoot

Your answer helps me, ill try that to close modals too.

Sweeeeeet thanks :slight_smile:

I tried that, now i have this:

    const overlay = this._app._appRoot._overlayPortal.getActive();
    const nav = this._app.getActiveNav();

    // If there is some modal/dialog open we call to dismiss
    if(overlay && overlay.dismiss) {
	    return overlay.dismiss();

    // If we can go back on the stack navigaton
    } else if(nav.canGoBack()){
        return nav.pop();

    // If sidemenu is open we close it instead of show the toast
    } else if (this._menuCtrl && this._menuCtrl.isOpen()) {
        return this._menuCtrl.close();
    }

    // No sidemenu open lets handle double back to exit
    if (!this._didBackAlready) {
        this._didBackAlready = true;
        this._presentToast("Press back button again to exit");
        setTimeout(() => this._didBackAlready = false, 2000);
        return;
    }
    this._plt.exitApp();

But when i open a modal and i press the back button it shows the toast and dont close the modal.

Same here,
I can’t find getActive() from _overlayPortal.

Did you find the solution for this?