About a month ago I published an article which demonstrated how to create a WP7 application using static HTML pages and PhoneGap. Whilst PhoneGap makes the packaging of HTML / JavaScript / CSS and images into a breeze, one thing it doesn’t do is provide correct back-button support. Correct back-button support is a mandatory requirement for marketplace certification. Hitting the back button should navigate back through the various screens of an application. Hitting the back-button on the first screen should terminate the application.
The solution I published previously handles the WP7 back keypress in order to keep track of the back-stack depth. When the back-stack depth is just one, a back-button press exits the application. This works fine if backwards navigation is always controlled via the hardware back-button, however if your application has HTML anchor elements that navigate back to a previous page, or you use code such as javascript:history.go(-1), this back-stack handling code will not detect that a backwards navigation has occurred.
As an aside, WP7 applications really should use the hardware back-button for navigation. If you are writing a cross-platform PhoneGap application consider adapting your UI for each platform. This means removing the back-button you woudl have in your iOS version when ‘skinning’ for WP7.
In order to solve this issue I have updated the code to inspect the URL that the browser control is navigating to in order to detect backwards navigation. The class now maintains a list of URLs, which represent the navigation stack. This allows it to detect a backwards navigation.
/// <summary> /// Handles the back-button for a PhoneGap application. When the back-button /// is pressed, the browser history is navigated. If no history is present, /// the application will exit. /// </summary> public class BackButtonHandler { private WebBrowser _browser; private List<string> _backStack = new List<string>(); public BackButtonHandler(PhoneApplicationPage page, PGView phoneGapView) { // subscribe to the hardware back-button page.BackKeyPress += Page_BackKeyPress; _browser = phoneGapView.Browser; // handle navigation events _browser.Navigated += Browser_Navigated; } /// <summary> /// Handle navigation in order to update our back-stack /// </summary> private void Browser_Navigated(object sender, NavigationEventArgs e) { string url = _browser.Source.OriginalString; // ensure all slashes are the same // app\www/index.html // see: https://issues.apache.org/jira/browse/CB-184 url = url.Replace("\\", "/"); if (_backStack.Count < 2) { _backStack.Add(url); } else { // check whether the URL represents a backwards navigation string previousPage = _backStack[_backStack.Count - 2]; if (previousPage == url) { _backStack.RemoveAt(_backStack.Count - 1); } } } /// <summary> /// Handle the hardware back-button /// </summary> private void Page_BackKeyPress(object sender, CancelEventArgs e) { // if we have items in the back-stack, route this event // to the browser if (_backStack.Count > 1) { _browser.InvokeScript("eval", "history.go(-1)"); e.Cancel = true; } } }
Note: There use of url.Replace("\\", "/"), this is due to a minor issue with the PhoneGap WP7 native code, which I have raised in the Callback JIRA (CB-184).
To use this code simply create an instance of the class, passing the PGView (the PhoneGap user control) into teh constructor:
public MainPage() { InitializeComponent(); new BackButtonHandler(this, PGView); }
Because back-button handling is a mandatory requirement for WP7 applications, hopefully Nitobi will incorporate this code (or similar) into the PhoneGap Build service (which I tried earlier this week – it is pretty amazing!)
You can download a working example here: HTML5SandwichFlow.zip
(The first three recipe pages have ‘back’ anchor elements, two use the URL, one uses JavaScript)
Regards,
Colin E.


email: ceberhardt@scottlogic.co.uk



Thanks for the great post, that really helped a lot. Unfortunately it seems like navigating through multipages in jquery mobile breaks the back button.
Do you have any knowledge of what could be going wrong here?
This depends on what method of jQuery Mobile navigation you are using, see the page here:
http://jquerymobile.com/test/docs/pages/page-links.html
The default AJAX behaviour fails in PhoneGap 1.3 due to a bug, so you will need PG1.4 for that. The technique described as “Linking within a multi-page document” means that the browser does not navigate between pages, so the back button method described in this blog post will not work.
This stuff is still a bit tricky! Good luck.
[...] Read original post by Colin Eberhardt at ScottLogic [...]