We've successfully used the following asp.net regex to carry out server side detection of mobile browsers visiting our site (taken from http://detectmobilebrowsers.com/
Public Shared Function IsMobileBrowser(httpUserAgentString As String) As Boolean
' set up user agent sniffing (http://detectmobilebrowsers.com/)
Dim b As New Regex("(android|ipad|playbook|silk|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|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", RegexOptions.IgnoreCase)
Dim v As New Regex("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\-", RegexOptions.IgnoreCase)
If (b.IsMatch(httpUserAgentString) Or v.IsMatch(Left(httpUserAgentString, 4))) Then
Return True
Else
Return False
End If
End Function
However, we've had reports back of this failing when users opened the site from QR reading apps (Qrafter). This seems to be because of the app (in the case of Qrafter on iOS at least) 'testing' the site by loading a page in code, inside the app. The User Agent string passed when doing this didn't match the mobile browser test, and so we set a session variable storing the site mode as desktop/non-mobile, and then when the full load of the site occurred on the via the app, it started in its desktop mode rather than mobile.
The User Agent string the app presented to our ASP.net code was:
Qrafter/6.3+CFNetwork/609+Darwin/13.0.0 200 0 0 178
So, we worked around this with the following regex method to detect and ignore these 'in-app' loads of the site
Public Shared Function IsAppSniffer(httpUserAgentString As String) As Boolean
Dim b As New Regex("\bCFNetwork\b.+\bDarwin\b", RegexOptions.IgnoreCase)
If (b.Matches(httpUserAgentString).Count > 0) Then
Return True
Else
Return False
End If
End Function
Basically, I wondered if this was a reliable way to carry out this test, and what we'd have to look for to detect similar issues on Android / Windows / other phones running QRafter equivalents? What would be their app based User Agent strings? Or, is this possibly an issue specific to the QRafter app on iOS due to its 'URL test' feature?
Feel free to (constructively if poss!) criticise our method of storing the mobile / desktop site mode in the session object, but it's probably a little late for us to re-engineer that on this project.
Apologies for the long windedness of this question, hopefully it is still just about a Q&A fit & thanks very much in advance for any useful info.
Edit: As pointed out by Stephen below, in a nutshell my question is essentially, 'Is there a practical way to detect user agent strings sent directly from mobile devices (of any flavour) along with the ones from their mobile browsers?'
e.g. (for an iOS / Safari pairing) direct from an app
AppName/CFNetwork/609+Darwin/13.0.0 200 0 0 178
the Safari user agent string
Mozilla/5.0+(iPhone;+CPU+iPhone+OS+6_0_1+like+Mac+OS+X)+AppleWebKit/536.26+(KHTML,+like+Gecko)+Mobile/10A523 200 0 0 20