Android Back Button on a Progressive Web Application Closes De App

Android Back Button on a Progressive Web Application closes de App

While the android back button cannot be directly hooked into from within a progressive web app context, there exists a history api which we can use to achieve your desired result.

First up, when there's no browser history for the page that the user is on, pressing the back button immediately closes the app.

We can prevent this by adding a previous history state when the app is first opens:

window.addEventListener('load', function() {
window.history.pushState({}, '')
})

The documentation for this function can be found on mdn:

pushState() takes three parameters: a state object, a title (which is currently ignored), and (optionally) a URL[...] if it isn't specified, it's set to the document's current URL.

So now the user has to press the back button twice. One press brings us back to the original history state, the next press closes the app.


Part two is we hook into the window's popstate event which is fired whenever the browser navigates backwards or forwards in history via a user action (so not when we call history.pushState).

A popstate event is dispatched to the window each time the active history entry changes between two history entries for the same document.

So now we have:

window.addEventListener('load', function() {
window.history.pushState({}, '')
})

window.addEventListener('popstate', function() {
window.history.pushState({}, '')
})

When the page is loaded, we immediately create a new history entry, and each time the user pressed 'back' to go to the first entry, we add the new entry back again!


Of course this solution is only so simple for single-page apps with no routing. It will have to be adapted for applications that already use the history api to keep the current url in sync with where the user navigates.

To do this, we will add an identifier to the history's state object. This will allow us to take advantage of the following aspect of the popstate event:

If the activated history entry was created by a call to history.pushState(), [...] the popstate event's state property contains a copy of the history entry's state object.

So now during our popstate handler we can distinguish between the history entry we are using to prevent the back-button-closes-app behaviour versus history entries used for routing within the app, and only re-push our preventative history entry when it specifically has been popped:

window.addEventListener('load', function() {
window.history.pushState({ noBackExitsApp: true }, '')
})

window.addEventListener('popstate', function(event) {
if (event.state && event.state.noBackExitsApp) {
window.history.pushState({ noBackExitsApp: true }, '')
}
})

The final observed behaviour is that when the back button is pressed, we either go back in the history of our progressive web app's router, or we remain on the first page seen when the app was opened.

Handling Ionic3 PWA back button

Solution (Code in app.components.ts)

    import { Platform, App, IonicApp, MenuController } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

constructor(
platform: Platform,
statusBar: StatusBar,
splashScreen: SplashScreen,
private app:App,
private ionicApp: IonicApp,
private menu: MenuController
) {

}

initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
this.statusBar.styleDefault();
this.splashScreen.hide();
this.setupBackButtonBehavior();
});
}

setupBackButtonBehavior () {
// If on web version (browser)
if (window.location.protocol !== "file:") {
// Register browser back button action(s)
window.onpopstate = (evt) => {
// Close menu if open
if (this.menu.isOpen()) {
this.menu.close ();
return;
}
// Close any active modals or overlays
let activePortal = this.ionicApp._loadingPortal.getActive() ||
this.ionicApp._modalPortal.getActive() ||
this.ionicApp._toastPortal.getActive() ||
this.ionicApp._overlayPortal.getActive();
if (activePortal) {
activePortal.dismiss();
return;
}
// Navigate back
if (this.app.getRootNav().canGoBack()) this.app.getRootNav().pop();
};
// Fake browser history on each view enter
this.app.viewDidEnter.subscribe((app) => {
history.pushState (null, null, "");
});
}
}

Phonegap Android Back Button - close app with back button on homepage

Update: this has stopped working with a latest Phonegap update (supposedly). Feel free to offer a working solution if you know it.


Here's how I do it:

document.addEventListener("backbutton", function(e){
if($.mobile.activePage.is('#homepage')){
/*
Event preventDefault/stopPropagation not required as adding backbutton
listener itself override the default behaviour. Refer below PhoneGap link.
*/
//e.preventDefault();
navigator.app.exitApp();
}
else {
navigator.app.backHistory()
}
}, false);

For further information, here you can find the related documentation with a full example: http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#backbutton



Related Topics



Leave a reply



Submit