PhoneGap: Detect if running on desktop browser

I'm developing a web application that uses PhoneGap:Build for a mobile version and want to have a single codebase for the 'desktop' and mobile versions. I want to be able to detect if PhoneGap calls will work (ie, is the user on a mobile device that will support PhoneGap).

I've searched and cannot believe there is no simple way of doing this. Many people have offered suggestions;

  • http://www.sencha.com/forum/showthread.php?144127-Checking-if-running-in-PhoneGap-or-Mobile-Web-Browser
  • http://groups.google.com/group/phonegap/browse_thread/thread/322e80bd41bb1a54/a421300eb2a2029f?lnk=gst&q=detect+desktop#a421300eb2a2029f
  • http://groups.google.com/group/phonegap/browse_thread/thread/8a95dfeb0f313792/3ff10d8f35211739?lnk=gst&q=detect+desktop+browser#3ff10d8f35211739

None of which work, unless you remove the PhoneGap Javascript file from the desktop version of the app, which defeats my goal of having one codebase.

So far the only solution I have come up with is browser / user agent sniffing, but this is not robust to say the least. Any better solutions welcome!

EDIT: A marginally better solution is to try calling a PhoneGap function after some small timeout - if it doesn't work, then assume the user is on a desktop web browser.


I use this code:

if (navigator.userAgent.match(/(iPhone|iPod|iPad|Android|BlackBerry|IEMobile)/)) {
  document.addEventListener("deviceready", onDeviceReady, false);
} else {
  onDeviceReady(); //this is the browser
}

UPDATE

There are many other ways to detect if phonegap is running on a browser or not, here is another great option:

var app = document.URL.indexOf( 'http://' ) === -1 && document.URL.indexOf( 'https://' ) === -1;
if ( app ) {
    // PhoneGap application
} else {
    // Web page
}  

as seen here: Detect between a mobile browser or a PhoneGap application


I wrote a post about it a few days ago. This is the best solution you can find (until PhoneGap will release something, maybe or maybe not), it's short, simple and perfect (I've checked it in every possible way and platform).

This function will do the job for 98% of the cases.

/**
 * Determine whether the file loaded from PhoneGap or not
 */
function isPhoneGap() {
    return (window.cordova || window.PhoneGap || window.phonegap) 
    && /^file:\/{3}[^\/]/i.test(window.location.href) 
    && /ios|iphone|ipod|ipad|android/i.test(navigator.userAgent);
}

if ( isPhoneGap() ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

To complete the other 2% of the cases, follow these steps (it involves a slight change on native code):

Create a file called __phonegap_index.html, with the source:

<!-- __phonegap_index.html -->
<script type="text/javascript">
    function isPhoneGap() {
        //the function's content is as described above
    }

    //ensure the 98% that this file is called from PhoneGap.
    //in case somebody accessed this file directly from the browser.
    if ( isPhoneGap() )
        localStorage.setItem("isPhoneGap","1");

    //and redirect to the main site file.
    window.location = "index.html";
</script>

Now, on native simply change the start page from index.html to __phonegap_index.html on all your PhoneGap platforms. Let's say my project name is example, the files you need to change are (as for PhoneGap version 2.2.0):

  • iOS - CordovaLibApp/AppDelegate.m
  • Android - src/org/apache/cordova/example/cordovaExample.java
  • Windows 8 - example/package.appxmanifest
  • BlackBerry - www/config.xml
  • WebOS - framework/appinfo.json
  • Bada - src/WebForm.cpp (line 56)
  • Window Phone 7 - No idea where (somebody still developing on that platform?!)

Finally, you can use it anywhere on your site, if it's running on PhoneGap or not:

if ( localStorage.getItem("isPhoneGap") ) {
    alert("Running on PhoneGap!");
} else {
    alert("Not running on PhoneGap!");
}

Hope it helps. :-)