Navigating to http://whatsmyuseragent.com/ shows me my stock Android browser on my Galaxy Nexus running 4.2.1 has the user agent
Mozilla/5.0 (X11; Linux x86_
As of right now there is no true method to detect this. I am currently on Android 4.2.2 stock Galaxy S4 AT&T and the default browser now has Chrome in the user-agent (but still has the TouchWiz issues of position fixed)
Until Samsung can either a) fix touchwiz or b) remove chrome from the ua string, we have no true method of detecting the android default browser. I cannot say if this is the case for all 4.2x + phones but this is a big issue for developing teams requiring manufacture/browser specific queries.
I am apart of an active developing team for mobile-end web-apps and it seems TouchWiz causes a lot of issues for different aspects being developed.
Another issue is there are companies like Dolphin (great browser, terrible UA) which in all these cases would pop back as the default browser since it doesn't provide a "dolphin" string and uses AppleWebKit534x
Also regarding the U in the user-agent string it had nothing to do with what browser. Infact this has to do with the encryption method being used for each browser (usually standard based on location)
"Web browsers created in the United States, such as Netscape Navigator and Internet Explorer, use the letters U, I, and N to specify the encryption strength in the user agent string. Until 1996, when the United States government disallowed encryption with keys longer than 40 bits to be exported, vendors shipped various browser versions with different encryption strengths. "U" stands for "USA" (for the version with 128-bit encryption), "I" stands for "International" — the browser has 40-bit encryption and can be used anywhere in the world — and "N" stands (de facto) for "None" (no encryption).[10] Following the lifting of export restrictions, most vendors supported 256-bit encryption."
Source: http://en.wikipedia.org/wiki/User_agent#Encryption_strength_notations
Samsung Galaxy Note 3 running Android 4.4.2 has the following UA string for the stock 'Internet' browser (not Chrome or any other browser):
Mozilla/5.0 (Linux; Android 4.4.2; en-us; SAMSUNG SM-N900 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36
Samsung Galaxy S5 running Android 4.4.2 has the following UA string for the stock 'Internet' browser (not Chrome or any other browser):
Mozilla/5.0 (Linux; Android 4.4.2; en-gb; SAMSUNG SM-G900H Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.6 Chrome/28.0.1500.94 Mobile Safari/537.36
We cannot only check for AppleWebKit < 537 anymore.
I am currently checking if AppleWebKit < 537 OR Chrome < 29 using user efusien's method.
I need to detect Android Stock Browser to add some custom styles because it doesn't seem to handle box-sizing properly. The code I used is based on @Prakarangs answer which was not working for me. (It did not detect the stock browser on a Galaxy Note 2)
var navU = navigator.userAgent;
var isAndroidMobile = navU.indexOf('Android') > -1 && navU.indexOf('Mozilla/5.0') > -1 && navU.indexOf('AppleWebKit') > -1;
var regExAppleWebKit = new RegExp(/AppleWebKit\/([\d.]+)/);
var resultAppleWebKitRegEx = regExAppleWebKit.exec(navU);
var appleWebKitVersion = (resultAppleWebKitRegEx === null ? null : parseFloat(regExAppleWebKit.exec(navU)[1]));
var isAndroidStockBrowser = isAndroidMobile && (appleWebKitVersion !== null && appleWebKitVersion < 535);
Maybe this is helpful for someone else too.
You can tell the difference between the stock browser and the Chrome browser by looking for "Android" in the useragent, and checking the AppleWebKit/### version number.
The stock Android browser never went above 534, and Chrome is 537 or higher.
var maybeAndroid = navigator.userAgent.indexOf('Android') >= 0;
var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.appVersion)[1], 10); // also matches AppleWebKit
var isAOSP = maybeAndroid && webkitVer <= 534 && navigator.vendor.indexOf('Google') == 0;
This is 99% reliable, and very useful for an app on Android 4.x using a WebView.
==details (if you want to go into depth!)==
Edit 7: 'AudioNode' in window is probably a safe sniff for AOSP (or old Chrome) versus modern Chrome versions. Try it here. window.AudioNode was introduced as part of WebAudio support in Chrome 29 (and unlikely to be back-ported by manufacturers). Our 4.0.3 phone has Chrome 41 on it, and 'AudioNode' in window returns true for Chrome and false for AOSP. You could also sniff for other features introduced after AOSP finished development -- see this link for other potential features to sniff. Choose a feature introduced before Chrome 42 because Android 4.0 users can't upgrade past that version. As usual with Android, there are sure to be strange edge cases, but that sniff is likely about as good as you can get (especially if combined with checking that WebKit version < 537).
Edit 8:
==WebView on Android==
Checking for <= 534 is a perfect test when using a WebView within an app. The compatibility definition for Android 4.3 (the last Android version to use AOSP for WebView), says the WebView user agent MUST be: "Mozilla/5.0 (Linux; U; Android $(VERSION); $(LOCALE); $(MODEL) Build/$(BUILD)) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30".
The compatibility definition for Android 4.4 (the first Android version to use Chromium for WebView ), says the WebView user agent MUST be: "Mozilla/5.0 (Linux; Android $(VERSION); $(MODEL) Build/$(BUILD); wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 $(CHROMIUM_VER) Mobile Safari/537.36".
Less than Android 4.3 is very similar to the 4.3 definition (always AOSP). Greater than 4.4 is very similar to the 4.4 definition (always Chromium).
==AOSP on Android==
For the browser on the device (not WebView), the user agent is not proscribed by the Compatibility Definition. The actual browser version used varies a lot as documented on quirksmode and as documented for the Samsung browser version.
Edit 4: The recommended solution is to look for Android without Chrome in the user agent as per: https://developer.chrome.com/multidevice/user-agent#webview_user_agent however it may also be necessary to ensure the absence of /Windows Phone/ because Mobile-IE11-8.1-Update also has Android in the UA "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 520) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537". Edit 5: https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx shows that IE12 on Windows Phone will still have Android in the user agent.
Edit 3: As commenters have stated, there are devices out there with AOSP and >= 535, but this is the most reliable test I have found (I would love to see something better). You can but try to make sure your code is still functional if the sniff fails, and accept that Android fragmentation means that there will be odd devices that fail. Caveat Emptor. Edit 6: Looking at some data for a specific site about 1% of what look to be AOSP logins have WebKit 537, so although it seems fairly reliable, it definitely isn't 100% reliable.
Edit 2: If you are using a WebView in an App, this detection is useful for Android >= 4.0 && Android < 4.4.4, because WebView component uses AOSP even if Chrome is installed on the device.
Edit 1: Since native android is now "obsolete" it is reasonable to test for it (and use the flag to work around differences that can't be detected using feature detection).
If you need a regular expression:
/Android[\s|/].+(AppleWebKit|Nokia)(.(?!Chrome|Presto|UCBrowser))+.$/gi
Ref from Nick's and efusien's answers. This works for me with Android OS 4.4.2
// Native Android Browser
var navU = navigator.userAgent;
var isAndroidMobile = navU.indexOf('Android') > -1 && navU.indexOf('Mozilla/5.0') > -1 && navU.indexOf('AppleWebKit') > -1;
var regExAppleWebKit = new RegExp(/AppleWebKit\/([\d.]+)/);
var resultAppleWebKitRegEx = regExAppleWebKit.exec(navU);
var appleWebKitVersion = (resultAppleWebKitRegEx === null ? null : parseFloat(regExAppleWebKit.exec(navU)[1]));
var regExChrome = new RegExp(/Chrome\/([\d.]+)/);
var resultChromeRegEx = regExChrome.exec(navU);
var chromeVersion = (resultChromeRegEx === null ? null : parseFloat(regExChrome.exec(navU)[1]));
var isAndroidBrowser = isAndroidMobile && (appleWebKitVersion !== null && appleWebKitVersion >= 537) && (chromeVersion !== null && chromeVersion < 29);
because now on Kitkat, native browser on Android is using WebKit 537.36 same as Chrome when we log userAgent. By checking also chromeVersion < 29 then I can get native browser on Android 4.4.2. (Chrome version on my Samsung S4 now is 40).
See in this link WebKit table on different Android version : http://jimbergman.net/webkit-version-in-android-version/