4. Device Libraries

Just looking at the HTTP headers and
the UAProf will not give us enough useful information about the mobile
devices that are accessing our websites. This is where device libraries
come to our help. Device libraries are offline databases (or online web
services) that take a user-agent string (or all of the request headers)
and return to us dozens of properties about the detected device, from
screen size, to Java ME compatibility, to Ajax support and video codec
compatibility.

4.1. WURFL

Wireless Universal Resource File (known as WURFL) is a
community-based, open source device capabilities repository created
and maintained by the developer Luca Passani (http://passani.it),
a fellow member of the Forum Nokia Champion program and author of the
preceding section on transcoders.

The library is available in the form of an XML file. While
updates to WURFL data happen every day on the WURFL DB, a publicly
available “snapshot” of the DB is produced and published about once
per month on the WURFL website.

Note:

If you are having doubts about how to pronounce WURFL, you can
find a WURFL pronunciation link on the library’s home page, where
you can listen to the word in English and Italian.

The sources of information include official technical
information published by manufacturers, UAProf files, and data
collected by the community after testing on real devices. Today, the
WURFL database contains thousands of devices (11,000 profiles, 7,000
of which have a unique brand and model), with information on
subversions, operating systems, firmware and hardware variations, and
hundreds of attributes that we can query for each one.

4.1.1. Architecture

WURFL groups the devices into a hierarchy of devices and
attributes. Some devices are equivalent to other devices from the
same series, possibly with some new features, so there is a fallback mechanism in WURFL allowing a
device to extend the features of another one. The same applies for
different models in the same brand or even different brands with the
same operating system.

Also, there is a feature called “actual device root” that
manages multiple subversions (different firmware) of the same
device, so the information is not duplicated in two records; the
subversion will be based on the main record with any added or
different abilities noted.

The WURFL database has a root fallback device called “generic
device” that is matched when the device, the brand, and the series
can’t be determined.

4.1.2. Patch file

What should you do if you need to make changes to the WURFL
XML, whether to identify new devices or bugs that you’ve found or to
add new private or public capabilities to be queried? Changing the
original WURFL XML would be impractical, because you would have
problems in the future when you wanted to download updates from the
site.

That is why a patch file is included in
the WURFL architecture. A patch is like a mini-WURFL (similar
syntax, but typically a lot smaller in size). The WURFL API will
merge the patch information with the information in the WURFL
database when the service starts.

Note:

If you find a bug, new devices, or capabilities that aren’t
private to your development, report them to the WURFL team or
apply to become a WURFL contributor.

Remember, this is a community project, and we are all part
of the community.

WURFL is intended for use on mobile websites; that is why this
library does not detect desktop browsers, or if they are detected
misidentifies them as some fallback mobile. If users may access your
mobile website from their desktops and you want to be able to detect
that using WURFL, you can download a web patch
that will detect desktop web browsers like Firefox and Internet
Explorer. You’ll need to merge this patch with the main XML.

Note:

If you find a generic_device, this is a device that is
not included in the WURFL database. It’s good practice to log and
report this information and the user agent received so it can be
investigated and recognized in the future.

4.1.3. Capabilities

Every ability, property, or attribute is called a
capability in the WURFL world. Capabilities are
organized into groups. Each capability for each device has an
optional string value (taken from the device itself, or from the
fallback mechanism). That value can be converted to a Boolean, a
number, a string, or an empty string.

The most useful groups at the time of this writing are shown
in Table 3.

Table 3. Most useful WURFL capability groups

Group
name

Capabilities
related to

product_info

Device information,
such as the brand, model, operating system, and
browser

chtml_ui

cHTML
rendering

xhtml_ui

ajax

Ajax and DOM support,
including support for getElementById, innerHTML, and CSS
manipulation

markup

Markup
compatibility

cache

Cache
support

display

The screen and
display (physical dimensions, resolution, line rows,
etc.)

image_format

Image formats,
including support for Animated GIF and SVG

wta

WTAI, including voice
call support

security

Encryption, including
HTTPS support

bearer

Networks, including
WiFi and VPN support

storage

Limits (e.g., max URL
length)

object_download

Formats and object
downloading support for each typical format

streaming

Audio and video
streaming per format and codec

wap_push

WAP Push attribute
support

j2me

Java ME configuration
and profile versions and API compatibility

mms

MMS
support

sms

SMS
support

sound_format

Support for audio
codecs and formats

flash_lite

Flash support on the
browser, for standalone applications, and for wallpaper or
screensavers

css

CSS
properties

transcoding

Whether the client is
detected as a transcoder

rss

RSS
support

pdf

PDF viewing
support

playback

Formats that can be
played by the device

As you can see, the information that the XML provides is
really complete. If you want to browse all the capabilities, you can
browse the XML with any reader or use the tools that come with the
Java API. You can check the first device definition, as the generic
device and fallback for all devices. If any property is not defined
in the generic device, there will be no fallback value to use if the
device does not define it.

Table 4 shows the
most important capabilities we can query. Remember that there are
dozens of other properties that you can query; take a look at the
library so you’ll have an idea of all the possibilities.

Table 4. Most useful WURFL capabilities

Capability
name

Type

Indicates...

brand_name

String

The device’s brand
name (e.g., Apple, Nokia, or HTC)

model_name

String

The device’s model
name (e.g., iPhone, N97, Nexus One)

marketing_name

String

The device’s
marketing name, including the brand, model, and possibly
another part of the name (e.g., Pearl, Touch)

is_wireless_device

Boolean

Whether the device is
a mobile device (true) or
a desktop/notebook

pointing_method

String

Which pointing method
is accepted (joystick, stylus, touchscreen, clickwheel, or
the empty string)

has_qwerty_keyboard

Boolean

Whether the device
has a QWERTY keyboard (virtual or physical)

nokia_series

Integer

The series (40, 60),
for Nokia devices

nokia_edition

Integer

The edition of the
series, for Nokia devices

nokia_feature_pack

Integer

The feature pack of
the series, for Nokia devices

device_os

String

The name of the
operating system

device_os_version

String

The version of the
OS

mobile_browser

String

The name of the
browser

mobile_browser_version

String

The version of the
browser

resolution_width

Integer

The screen width in
pixels

resolution_height

Integer

The screen height in
pixels

max_image_width

Integer

The display’s usable
width in pixels

max_image_height

Integer

The display’s usable
height in pixels

xhtml_support_level

Integer

The level of XHTML
compatibility, from −1 to
4:

−1: No
support

0: Basic
support (poor or no CSS support, basic form support,
basic or no table support)

1 and
2: Advanced basic
support (basic CSS and table support)

3: Medium
support, including excellent CSS support)

4: Advanced
support, including Ajax support

preferred_markup

String

The markup best
supported by the device (even if it supports a newer
one)

xhtml_format_as_css_property

Boolean

Whether -wap-input-format is
available

xhtml_make_phone_call_string

String

The prefix preferred
for making phone calls in a URL

xhtml_send_sms_string

String

Whether and how the
device supports triggering the SMS client from a link (can
be sms:, smsto:, or the empty string,
meaning not supported)

ajax_supports_getelementbyid

Boolean

Whether document.getElementById works on
the device

ajax_xhr_type

String

Which syntax to use
when creating an XMLHTTPRequest object (none, standard for the native XHR
object, msxml2 for the
normal Microsoft ActiveX object, and legacy_microsoft for the older
one)

ajax_support_inner_html

Boolean

Whether we can change
the innerHTML property
dynamically

ajax_manipulate_dom

Boolean

Whether typical DOM
methods are available

ajax_support_event_listener

Boolean

Whether the browser
allows event registration through event
listeners

html_wi_oma_xhtmlmp_1_0

Boolean

Whether the browser
supports XHTML MP 1.0

html_web_3_0

Boolean

Whether the browser
supports HTML 3

html_web_4_0

Boolean

Whether the browser
supports HTML 4

gif_animated

Boolean

Whether Animated GIF
is supported

svgt_1_1

Boolean

Whether SVG 1.1 is
supported

svgt_1_1_plus

Boolean

Whether SVG 1.1+ is
supported

flash_lite_version

String

Which version of
Flash is supported

fl_browser

Boolean

Whether the browser
supports Flash content

is_transcoder

Boolean

Whether a transcoder
was detected as a proxy from the real device

transcoder_ua_header

String

Which header we can
find the original device’s user-agent string in, if a
transcoder was detected

multipart_support

Boolean

Whether the browser
supports multipart documents

4.2. WURFL usage

You can use WURFL by browsing the file as you would any other
XML file and matching user-agent strings, but the wheel has already
been invented, and on the same website where you can download the XML
you will find APIs for the most common server platforms: Java, PHP,
and .NET (in beta at the time of this writing). Generally speaking you
should use the new APIs available on the website, but for
compatibility purposes you can still find old APIs to download.

These APIs allow us to use WURFL in a couple of lines, with many
advantages:

Automatic device detection using the header
information

Detection of transcoders and proxies, and matching of the
correct user agent and device information

Merging of the static XML provided by WURFL with patches
(the web patch or your own), providing a simple and unique way to
query capabilities

Caching of the XML parsing for the best performance on every
request

4.2.1. PHP API installation

To use WURFL in PHP, you should download the PHP API from
http://wurfl.sourceforge.net/nphp and extract
the contents of the GZIP file. The package contains documentation,
examples, resources, unit tests, and a WURFL folder where the API
resides.

Note:

The PHP WURFL API allows us to save persistence and cache
information using memcache instead of using the filesystem.

To make it work, follow these steps:

Copy the WURFL folder
into your web server root folder.

Download the latest wurfl-<version>.zip file from
the website and copy it to the new resources folder (along with the
web_browsers_patch.xml
file, if you need it).

Create a cache folder
inside the resources folder
(or in another place, with a different name if you like) and
verify that it PHP scripts have write permissions for this
folder.

Edit the resources/wurfl-config.xml file and
check that the <main-file> tag matches the name
of the ZIP file containing the main XML repository. It can also
be a decompressed XML file.

Edit the resources/wurfl-config.xml file, go
to the persistence node, and check that the <params> tag matches the name of
the cache folder, as in
<params>dir=cache</params>.
The path needs to be relative to the config XML folder.

Once WURFL is installed, we can create our first PHP script
that uses the repository. Using version 1.0 of the API, the code
will be:

$wurflManager=$wurflManagerFactory->create();

$device=$wurflManager->getDeviceForHttpRequest($_SERVER);

?>

If you run this file on your web server (local or remote), you
will need to wait 1 or 2 minutes the first time while it creates the
cache folder to enable quick detection in future requests. If you
receive a blank page, great! If you get an error, you need to check
all the steps again.

Warning:

If you’re working on a local server and are going to upload
your website to another server using FTP or some other protocol,
it will be better to not upload the cache folder because it will
contain thousands of files. It is better to leave the server to
recreate them locally.

4.2.2. Using the PHP API

The PHP API is an object-oriented API. Once you have the
WURFLManager object, regardless of whether you
are using version 1.0 or 1.1 of the API, you can use it.

Warning:

If your server is too loaded, you may get a timeout error
when processing WURFL the first time. If this happens, ask your
server provider how to increase the maximum script time limit or
change the PHP.ini
file.

A typical usage is getting a device object using the manager’s
methods:

getDeviceForHttpRequest($_SERVER)

getDeviceForUserAgent($user_agent)

getDevice($deviceId)

If you want to access the capabilities of the current device
accessing your website, the first option is the best one. If you
want to get properties for other devices, you can use the user_agent method or the deviceId method. Every device in WURFL has
an ID that we can store in our databases for statistics or logs. We
can then look for its capabilities later, after the mobile
request.

A great option if you are offering content is to explicitly
display to the user his phone model in the marketing
information:

Note:

If you want to test whether your WURFL code is working on
your desktop browser, you can use Firefox and the free plug-in
User Agent Switcher that allows Firefox to change its user-agent
string to that of any other device of your liking.

Tera-WURFL (a PHP and MySQL implementation of the WURFL
repository)

GAIA Image Transcoder

PHP Image Rendering Library (works with an old version of
the PHP API)

Apache Mobile Filter

Note:

The Apache Mobile Filter is an open source solution for
redirecting users to different versions using filters in an Apache
module that looks into the WURFL database. It also supports image
resizing. The project is available at http://sourceforge.net/projects/mobilefilter.

4.3. DeviceAtlas

In February 2008 (many years later than WURFL), the
dotMobi company, which owns the .mobi top-level
domain, launched its own device database that is similar in many ways
to WURFL.

DeviceAtlas is a commercial product (with a free testing version
for developers) available at http://deviceatlas.com that has partnerships with many
data providers. According to dotMobi, this is not only the largest but
also the most accurate device database on the market.

The main features are:

Monthly, weekly, daily, or constant updates to the database,
depending on your license

A data explorer to browse the database from the Web

JSON data format support

APIs for PHP, Java, .NET, Python, and Ruby

Apache server module (with the enterprise license)

At the time of this writing, the basic license costs $99 per
server per year and includes monthly updates but excludes the
possibility to merge private data and other options available in
higher license options.

4.3.1. Installation

You can apply for a free developer evaluation version at the
website or buy a commercial version and then download the data and
API from http://deviceatlas.com/downloads. You
will receive by email the license key, which is valid for one year.
You will also receive the direct links to download the data file (in
JSON format) in ZIP format.

Note:

The W3C is trying to standardize the device database
repositories in the Device Descriptions Working Group, currently
in draft at http://www.w3.org/TR/DDR-Simple-API. DeviceAtlas is
offering its database in this new format as a preview.

You can get an automatic update of the JSON file using the URL
https://deviceatlas.com/getJSON.php?licencekey=<license>&format=zip
(inserting your license key in the URL).

4.3.2. Properties

The data available in DeviceAtlas is segmented into
categories. The most important properties per category are:

VideoPlayer: 3gp.h263,
3gp.h264.level1, mp4.aac.lc, wmv

Warning:

Remember that if you have a developer account your database
file will not be updated if you download it again, and if you have
a basic license with monthly downloads a new file will not be
available until 30 days from when you downloaded the previous
version.

4.3.3. PHP API

Inside the PHP API package you will find a doc folder containing PHPDoc
documentation, a sample folder
containing examples of usage, and a Mobi folder containing the API. The PHP
API requires PHP version 5.2.3 with JSON support.

You need to copy the Mobi
folder with all of its content into your website root, but you can
put the JSON data file in any place you want. In your PHP file, you
must include the file Mobi/Mtld/DA/Api.php.

A typical project will look like the following:

<?phpinclude('Mobi/Mtld/DA/Api.php');// We get a tree object loading the JSON$tree = Mobi_Mtld_DA_Api::getTreeFromFile("deviceatlas.json");// We get all the properties for the User Agent$properties = Mobi_Mtld_DA_Api::getProperties($tree, $_SERVER['HTTP_USER_AGENT']);// Or we can get one property at a time using$value = Mobi_Mtld_DA_Api::getProperty($tree, $ua, 'some-property');?>

If you want a cache implementation, you’ll need to do it
yourself or have memcache installed on the server and save the
entire tree as the sample provided by the API. The Java and .NET
APIs have better support for caching techniques.

4.4. The ASP.NET Mobile Device Browser File

If you work with the ASP.NET platform, you can find an
open source mobile browser database at http://mdbf.codeplex.com, released by the Mobile Browse
Platform Team at Microsoft. This file is attached to the current
ASP.NET browser detection mechanism and is updated frequently. The
sources of the information include WURFL, UAProf files, contributions
from the community, and others.

To use it, all you need to do is download the mobile.browser file from the website,
create a folder called App_Browsers (if you don’t already have
one) with a mobile subfolder, and
copy the downloaded file into that folder. That’s it!

Warning:

The ASP.NET Mobile Device Browser File is only compatible with
.NET Framework 2.0 and newer versions.

You can use the existing Request.Browser object in ASP to get
information about the requesting
device. IsMobileDevice will tell
you whether or not it is a mobile browser, Platform will tell you the operating system,
ScreenPixelsWidth and ScreenPixelsHeight will
tell you the screen dimensions, and you can query any other property
using Request.Browser as a Collection.

Here is an example in C#:

if (Request.Browser.IsMobileDevice) { Response.Write("This is a " + Request.Browser.Platform + " device"); if (Request.Browser["SupportsTouchScreen"]) { // It is a touch-based device }}

Whether we can use
full DOM methods

AjaxSupportsGetElementByID

Boolean

Whether we can use
getElementById from
JavaScript

AjaxSupportsInnerHtml

Boolean

Whether we can use
innerHTML without
problems

AjaxXmlHttpRequestConstructorSyntax

String

Which syntax to use
when creating an XMLHTTPRequest object (none for no Ajax support, standard for the native XHR
object, or msxml2 for IE
syntax)

InputType

String

Which input type is
supported (keyboard,
telephoneKeypad, or
virtualKeyboard)

IsMobileDevice

Boolean

Whether or not the
current device is a mobile device

JavaScript

Boolean

Whether the device
supports JavaScript

MobileDeviceManufacturer

String

The device’s brand
name

MobileDeviceModel

String

The device’s model
name

PreferredRenderingMime

String

The preferred MIME
type for XHTML content

SupportedFlashVersion

String

Which Flash version
is supported (none or the
version number)

SupportsAccesskeyAttribute

Boolean

Whether the device
supports the accesskey
value

SupportsCssBackgroundImage

Boolean

Whether the device
supports defining background images

SupportsEmbeddedFlashInWebPages

Boolean

Whether the device
supports embedding a SWF file

SupportsTouchScreen

Boolean

Whether the device is
touch-based

SupportsWapPush

Boolean

Whether the device
supports WAP Push

SupportsXhtmlRendering

Boolean

Whether the device
supports XHTML

4.5. Service-based solutions

You may not want to write all this yourself. Services are
available to help; we’ll look at a few of them here.

4.5.1. Movila DetectFree

Movila Detection (http://www.moviladetection.com) is a server-side Java
solution to detect in 500 microseconds which device is using an
embedded repository. It also
works as a tool for URL rewrites. However, Movila’s most-used
feature is the free service called DetectFree.

DetectFree is a free light version of the service available
for PHP and JavaScript (and for any other platform that sends HTTP
requests) that allows you to detect whether the connecting device is
a mobile device. You can find samples and documentation at http://www.moviladetection.com/detectfree. Just to
illustrate how easy it is to use, the following sample is a
JavaScript detection mechanism:

4.5.2. DetectRight

DetectRight is a detection engine, device database,
analytics engine, and API/SDK with both service-based and dedicated
server options. Free noncommercial/developer licenses are available,
and a shared-service license begins at 399 euros per month. It
features SOAP and REST access, unique custom identification,
country-level geolocation, and profiles in WURFL, DeviceAtlas,
UAProf, DetectRight, and Java ME Polish–compatible formats. It
features over 20,000 devices at the time of this writing.

Note:

If you want easy and quick mobile detection, at http://www.detectmobilebrowsers.mobi you will find
a little PHP code that allows you to determine whether the user is
using a mobile browser without any repository, database, or service
call.

If you register at http://www.detectright.com, you will receive via
email a key that enables you to access a variety of PHP, .NET, and
SOAP samples and APIs.

Remember that this is a service-based solution, so you don’t
need to download or update any database on your server. Every
request will be sent over the Internet to the DetectRight
servers.

Warning:

Remember that when using service-based solutions, your
mobile website’s performance will depend on the reliability of the
third-party server to which you are connecting.

You can download the PHP or .NET API for easy usage for those
platforms.

In PHP, once you’ve downloaded the API you can use the service
as shown in the following sample: