Monday, November 30, 2009

Simple Perl Mobile Device Detection

Here is a simple Perl subroutine to try to detect mobile devices from within a Perl script. This subroutine has been cobbled together from bits and pieces I have found around the web. Let me know if you have comments or improvements to it's logic.

sub is_mobile_device {
# -----------------------------

my $mobile_browser = 0;
my $env_ua = lc $ENV{'HTTP_USER_AGENT'} || '';

if ((!$env_ua =~ /linux/) &&
(!$env_ua =~ /win/) &&
(!$env_ua =~ /os\s+(X|9)/) &&
(!$env_ua =~ /solaris/) &&
(!$env_ua =~ /bsd/)) {
# This user agent is not Linux, Windows, a Mac, Solaris or BSD
$mobile_browser++;
}
if ($env_ua =~ m/up\.browser|up\.link|mmp|symbian|smartphone|midp|wap|phone/) {
$mobile_browser++;
}
if ((index lc $ENV{'HTTP_ACCEPT'}, 'application/vnd.wap.xhtml+xml') != -1) {
$mobile_browser += 2;
}
if ((index lc $ENV{'HTTP_ACCEPT'}, 'application/xhtml+xml') != -1) {
$mobile_browser++;
}
if ((index lc $ENV{'ALL_HTTP'}, 'operamini') != -1) {
$mobile_browser++;
}
if ((index $env_ua, ' ppc;') != -1) {
$mobile_browser++;
}
if ($env_ua =~ /ip(hone|od)(;|\s)/) {
$mobile_browser++;
}
if ((index $env_ua, 'windows ce') != -1) {
$mobile_browser++;
} elsif ((index $env_ua, 'windows') != -1) {
$mobile_browser -= 2;
}
if ((index $env_ua,'iemobile') != -1) {
$mobile_browser++;
}
if (defined $ENV{'HTTP_X_WAP_PROFILE'}) {
$mobile_browser += 2;
}
if (defined $ENV{'HTTP_PROFILE'}) {
$mobile_browser++;
}

my $mobile_ua = substr($env_ua, 0, 4);

my @mobile_agents = (
'w3c ','acs-','alav','alca','amoi','audi','avan','benq','bird','blac',
'blaz','brew','cell','cldc','cmd-','dang','doco','eric','hipt','inno',
'ipaq','java','jigs','kddi','keji','leno','lg-c','lg-d','lg-g','lge-',
'maui','maxo','midp','mits','mmef','mobi','mot-','moto','mwbp','nec-',
'newt','noki','oper','palm','pana','pant','phil','play','port','prox',
'qwap','sage','sams','sany','sch-','sec-','send','seri','sgh-','shar',
'sie-','siem','smal','smar','sony','sph-','symb','t-mo','teli','tim-',
'tosh','tsm-','upg1','upsi','vk-v','voda','wap-','wapa','wapi','wapp',
'wapr','webc','winw','winw','xda','xda-'
);

if (grep $_ eq $mobile_ua, @mobile_agents) {
$mobile_browser++;
}

return $mobile_browser;
}

The output is simple. If a value of 1 or less is returned, the visiter is probably using a full size pc or laptop. For values greater than 1, the visiter is probably using a mobile device. It's not perfect, but gives a quick first cut.