215

I've done some research, and this question has come up, but not in the way I intend. I'm building a page for a client that is a QR code landing, which is a place to download an application. So he doesn't have to print out 2 QR codes on a page, I'd like to detect the current operating system (Apple/Android/Other[not supported]) and modify my elements based on that value.

I've looked at the script "detectmobilebrowsers" and that is just aimed at telling whether or not the user is mobile at all, whereas I would like to figure out what operating system the user is running and suggest the best application version.

Other answers I found similar to this question seemed either outdated or unreliable (has no detection for Android tablet browsers), so I'm in search of something new. How can I achieve this? (Preferably using jQuery - Javascript - PHP in that order).

Alexander Lozada
  • 3,469
  • 3
  • 15
  • 39
  • 2
    The user agent doesn't tell you what you need to know? – Babak Naffas Feb 12 '14 at 23:07
  • 2
    This issue has already been resolved here : http://stackoverflow.com/questions/3514784/what-is-the-best-way-to-detect-a-handheld-device-in-jquery – gretro Feb 12 '14 at 23:09
  • 1
    @gretro, that describes *if* the user is mobile, not the operating system they are running. Babak, would something like navigator.platform be the solution? I'm unfamiliar with user agents. How can I make sure that it will work for ALL android devices regardless of version? – Alexander Lozada Feb 12 '14 at 23:11
  • There's no guaranteed way to detect it, since the user agent *is* the only thing you can go on. Check here for more info... http://whatsmyos.com/ – Reinstate Monica Cellio Feb 12 '14 at 23:12
  • 2
    @Alexander Lozada : On the accepted answer, they basically test if it's an iPhone, an iPod, an Android device or whatever to return true. Just keep the ones you want for instance `if( /Android/i.test(navigator.userAgent) ) { // some code.. }` will return true only for Android user-agents. – gretro Feb 12 '14 at 23:16
  • @gretro, thanks. I believe this is enough of a different situation to have a separate answer, especially to folks like me who aren't very good at understanding regexes/light on javascript knowledge. If you'd like to make your comment an answer I'd accept it as the answer. Anyway, from reading it doesn't sound like userAgents are the most reliable things - but I guess this is the best course of action, right? – Alexander Lozada Feb 12 '14 at 23:21
  • @AlexanderLozada [Here's a list of user agents](http://www.useragentstring.com/pages/useragentstring.php) for you to make sure you cover all your target mobile browsers – Juan Mendes Feb 13 '14 at 01:14
  • possible duplicate of [Detect if browser is running on an Android or iOS device](http://stackoverflow.com/questions/12606245/detect-if-browser-is-running-on-an-android-or-ios-device) – kiranpradeep May 23 '15 at 12:50

9 Answers9

434

You can test the user agent string:

/**
 * Determine the mobile operating system.
 * This function returns one of 'iOS', 'Android', 'Windows Phone', or 'unknown'.
 *
 * @returns {String}
 */
function getMobileOperatingSystem() {
  var userAgent = navigator.userAgent || navigator.vendor || window.opera;

      // Windows Phone must come first because its UA also contains "Android"
    if (/windows phone/i.test(userAgent)) {
        return "Windows Phone";
    }

    if (/android/i.test(userAgent)) {
        return "Android";
    }

    // iOS detection from: http://stackoverflow.com/a/9039885/177710
    if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
        return "iOS";
    }

    return "unknown";
}
Oliver
  • 8,258
  • 7
  • 64
  • 94
feeela
  • 26,359
  • 6
  • 56
  • 68
  • And [the OP can look at this list](http://www.useragentstring.com/pages/useragentstring.php) in case your test needs tweaking – Juan Mendes Feb 13 '14 at 01:13
  • 7
    Awesome. Using Chrome's mobile mode u can test it on desktop browsers. – DaFunkyAlex Jul 13 '15 at 08:47
  • Microsoft has unfortunately added `Android` to their Edge browser's userAgent string so this test won't work for many Windows Phones: https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx – torno Feb 22 '16 at 11:48
  • @torno That is why one should not rely on Client detection, but on feature detection. – feeela Feb 23 '16 at 13:40
  • 4
    @feeela sometimes the feature is something like being able to install apks, which isn't possible to detect. – Daniel Lubarov Mar 07 '16 at 21:11
  • 2
    I've added `else if (userAgent.match(/Windows Phone/i)) { return 'WindowsPhone'; }` _before_ the Android else if to detect Windows Phone. So far seems to be working fine. – Arthur Jun 07 '16 at 05:44
  • 4
    From http://stackoverflow.com/a/9039885/177710: in the check for `iOS` we need to also verify `!window.MSStream` to avoid IE11 being counted as `iOS` ;-) – Oliver Jul 26 '16 at 08:40
  • 2
    Not working iPAD Pro: return this: `Safari: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15` – Ivan Ferrer Jun 09 '20 at 18:24
15

Solution 1: User Agent Sniffing

For Android and iPhone:

if( /Android|webOS|iPhone|iPad|iPod|Opera Mini/i.test(navigator.userAgent) ) {
 // run your code here
}

If you wanna detect all mobile devices including blackberry and Windows phone then you can use this comprehensive version:

var deviceIsMobile = false; //At the beginning we set this flag as false. If we can detect the device is a mobile device in the next line, then we set it as true.


if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) 
    || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4))) {
   deviceIsMobile = true;
}

if(deviceIsMobile){
    // run your code here
}

Cons: User agent strings are changing and getting updated as new phones and brands are coming day by day. So you need to keep this list updated if you wanna support all mobile devices.

Solution 2: mobile detect JS library

You can use the mobile detect JS library to do this.

Cons: These JavaScript-based device detection features may ONLY work for the newest generation of smartphones, such as the iPhone, Android and Palm WebOS devices. These device detection features may NOT work for older smartphones which had poor support for JavaScript, including older BlackBerry, PalmOS, and Windows Mobile devices.

Iman Sedighi
  • 6,062
  • 4
  • 43
  • 52
6

One can use navigator.platform to get the operating system on which browser is installed.

function getPlatform() {
   var platform = ["Win32", "Android", "iOS"];

   for (var i = 0; i < platform.length; i++) {

       if (navigator.platform.indexOf(platform[i]) >- 1) {

           return platform[i];
       }
   }
}

getPlatform();
Pankaj Bisht
  • 870
  • 8
  • 26
AKASH KHATRI
  • 61
  • 1
  • 3
  • 14
    On a Samsung Galaxy Grand Prime I am testing now, navigator.platform returns ''Linux armv7l'' – mico Nov 27 '15 at 10:21
3

This issue has already been resolved here : What is the best way to detect a mobile device in jQuery?.

On the accepted answer, they basically test if it's an iPhone, an iPod, an Android device or whatever to return true. Just keep the ones you want for instance if( /Android/i.test(navigator.userAgent) ) { // some code.. } will return true only for Android user-agents.

However, user-agents are not really reliable since they can be changed. The best thing is still to develop something universal for all mobile platforms.

Community
  • 1
  • 1
gretro
  • 1,843
  • 16
  • 24
3

If you're using React Js for your website, use https://www.npmjs.com/package/react-device-detect

Kira
  • 335
  • 1
  • 14
  • 5
    Note that this is a bit of a heavy import (~23kb) for just checking iOS vs. Android. – jessepinho Mar 18 '19 at 16:40
  • @jessepinho: true. In hindsight I wouldn't do so to keep my build light. But it did help to get things working. – Kira May 10 '19 at 04:37
2

You can also Achieve this with user agent on php:

$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);

if(stripos($userAgent,'android') !== false) { // && stripos($userAgent,'mobile') !== false) {
  header('Location: http://oursite.com/download/yourApp.apk');

exit();

}

Hamed Yarandi
  • 626
  • 8
  • 19
1

You also can create Firbase Dynamic links which will work as per your requirement. It supports multiple platforms. This link can be created, manually as well as via programming. You can then embed this link in QR code.

If the target app is installed, the link will redirect user to app. If its not installed it will redirect to Play Store/App store/Any other configured website.

Sagar
  • 20,467
  • 4
  • 50
  • 56
0

Using the cordova-device-plugin, you can detect

device.platform

will be "Android" for android, and "windows" for windows. Works on device, and when simulating on browser. Here is a toast that will display the device values:

    window.plugins.toast.showLongTop(
    'Cordova:     ' + device.cordova + '\n' +
    'Model:       ' + device.model + '\n' +
    'Platform:    ' + device.platform + '\n' +
    'UUID:        ' + '\n' +
                      device.uuid + '\n' +
    'Version:     ' + device.version + '\n' +
    'Manufacturer ' + device.manufacturer + '\n' +
    'isVirtual    ' + device.isVirtual + '\n' +
    'Serial       ' + device.serial);
pollaris
  • 1,058
  • 14
  • 18
0

For this and other kind of client detections I suggest this js library: http://hictech.github.io/navJs/tester/index.html

For your specific answer use:

navJS.isIOS() || navJS.isAndroid()
Marco Allori
  • 2,874
  • 29
  • 24