Wednesday, 16 February 2011

Request.Browser.IsMobileDevice

It's known that the .Net framework's "Request.Browser.IsMobileDevice" is not entirely reliable in all cases as evidenced by the fact that our MVC2 site wasn't correctly detecting Android as a mobile, and as evidenced by some hits you can see in this search:

http://www.bing.com/search?q=request.browser.ismobiledevice&src=IE-SearchBox&FORM=IE8SRC

If we really want reliable mobile detection we need to incorporate the WURFL database (a giant XML file of every mobile device - see http://wurfl.sourceforge.net/ ) and from what I’ve seen, the preferred implementation of this for .Net appears to be “51degrees.mobi” …

http://51degrees.codeplex.com/

On the MVC2 project I’ve been working on recently, I was using 51degrees.mobi in development; it seemed very effective, and you can do incredibly granular detection with it, but was a bit heavyweight for my particular project, the requirements of which were (in the case of mobile detection) simply to detect whether it was a mobile device, and display a different view if so.  Our list of supported mobiles was quite small, and the only one that weren’t being detected correctly by the “Request.Browser.IsMobileDevice” flag were Android phones.

So I was just using “Request.Browser.IsMobileDevice” which was working fine until I heard about the Android issue. 

Anyway, the following is a bit of a hack, but I just handled that case in a specific way… I looked at the "user agent" value that comes across in the request.  I also looked (physically, not in code) at the WURFL XML file that comes with 51degress.mobi, for a generic Android phone, because I assume that’s how WURFL is doing its detection anyway.  In the WURFL database, the user agent string for a generic Android is:

Mozilla/5.0 (Linux; U; Android 0.5; en-us) AppleWebKit/522+ (KHTML, like Gecko) Safari/419.3

So it seemed safe to assume “Android” would exist in the user agent string; so now I'm just looking for the word "android" (converted to lower case in code) in the user agent string, and if it's found, I tell the app to behave just like it does with other mobile devices.

// special case; Android phones were not being detected as mobiles by Request.Browser.IsMobile;

// this is a quick & dirty solution.  The preferred solution would be to integrate the WURFL database

// and the DLLs from http://51degrees.codeplex.com/ but it's too heavyweight of a solution for this

 

var useragent = Request.UserAgent;

var isAndroid = false;

 

if (useragent != null)

{

    if (useragent.ToLower().Contains(Constants.MobileDevices.Android))

    {

        isAndroid = true;

    }           

}

 

if (Request.Browser.IsMobileDevice || isAndroid)

{

    // … do something specific for mobiles, particularly, display the mobile view

I tested it with a "user agent switcher" add-on for Firefox that I found here:

http://chrispederick.com/work/user-agent-switcher/features/

and it correctly went to the mobile version of the site as if I were running on an Android.

The add-on might not work in every case, but in this situation it did the job, and is bit easier than using a mobile emulator.

Anyway again, a bit of a hack, but turned out to be an effective quick and dirty solution to this particular problem.