Archive for January 25th, 2008

Device detection with DetectRight

Recently, I read about DetectRight over at Jason Delport’s Mobile Observations. DetectRight is a web service for device detection; their API allows you to supply HTTP headers (or a user agent string), and query which device your mobile visitor is using.

Device detection is something we tried to tackle early on. Our first approach was to use the open source effort WURFL. Our use of WURFL didn’t last long when we noticed data for a few popular handsets was either incomplete or just wrong. (Note: this was almost a year ago, so things may have improved.)

In the end, we chose to prompt the user to select their device from a list when downloading. It’s an extra step, but it still allows us to deliver applications optimized for whichever handset you use.

Our evaluation of DetectRight is underway, and I thought I’d share our experiences.

DetectRight offers both php and SOAP APIs. Since Gleemy is written with Java on the server side, we started with the SOAP API.

To consume a web service with Java, you start by generating a client stub from the WSDL file describing the web service.

The Java API for Web Services sounded like a good place to start, but alas no luck. (What does “[ERROR] undefined simple or complex type 'SOAP-ENC:Array'” mean?)

WSDL2Java (part of the Apache Web Services project) turned out to be a lot friendlier. Running:

java -cp axis.jar;commons-discovery.jar;commons-logging.jar;jaxrpc.jar;saaj.jar;wsdl4j.jar org.apache.axis.wsdl.WSDL2Java http://www.mpwservices.net/MPWServices/soap.php?wsdl

produces a Java callable interface to the DetectRight web service, in the form of 5 java files. Awesome. Here are a few good methods from the stub:

public Hashtable getProfile(

String licence,

String manufacturer,

String model,

String schemaName

)

public Hashtable getProfileFromUA(

String licence,

String HTTPUserAgent,

String HTTPAccept

)

public Hashtable getProfileFromHeaders(

String licence,

Hashtable serverVars

)

This enables you to do things like:

profile = getProfile(myLicenseKey, userAgentString, null);

where profile is a hash table containing all known properties of the client device. Each call is marshaled across the Internet to the DetectRight servers.

You can print the profile like this:

private static void dumpHashtable(Hashtable h)
{
String[] keys = h.getKeys();
String[] values = h.getValues();
int i;


System.out.println(keys.length + " keys, " + values.length + " values");
for (i = 0; i < keys.length; i++)
{
System.out.println(keys[i] + ": " + values[i]);
}
}

I tested with popular user agents we’ve seen, and every time the API worked as expected.

We’re still playing with it. As part of any evaluation, you need to consider things like cost (DetectRight is a commercial service), license terms, level of service and so on.