Java User Agent Detection code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ******************************************* | |
// LICENSE INFORMATION | |
// The code, "Detecting Smartphones Using PHP" | |
// by Anthony Hand, is licensed under a Creative Commons | |
// Attribution 3.0 United States License. | |
// | |
// Updated 01 March 2010 by Bryan J Swift | |
// – Remove un-needed if statements instead just returning the boolean | |
// inside the if clause | |
// | |
// Updated 14 December 2009 by A Hand | |
// – Added the method for detecting BlackBerry Touch | |
// devices like the Storm 1 and 2. | |
// | |
// Updated 5 December 2009 by A Hand | |
// – Fixed the DetectPalmOS method. It should filter | |
// out WebOS devices. | |
// | |
// Updated 8 November 2009 by A Hand | |
// – Added the deviceWebOS variable. | |
// – Added Palm's WebOS to the DetectPalmOS method. | |
// – Created a new method to check for Palm's WebOS devices. | |
// – Added Palm's WebOS to the DetectTierIphone method. | |
// | |
// Updated 4 April 2009 by A Hand | |
// – Changed the name of the class from DetectSmartPhone to UAgentInfo. | |
// New name is more consistent with PHP and JavaScript classes. | |
// – Added a method to detect Opera Mobile and Mini. Opera Mobile is new. | |
// – Updated the algorithm for detecting a Sony Mylo. | |
// – Added Android to the DetectTierIphone method. | |
// – Updated comments for Detect Tier methods. | |
// | |
// Updated 22 January 2009 | |
// – Ported to Java from the PHP code by | |
// Satish Kumar Nookala, [email protected] | |
// | |
// Anthony Hand, [email protected] | |
// Web: www.hand-interactive.com | |
// | |
// License info: http://creativecommons.org/licenses/by/3.0/us/ | |
// | |
// This code is provided AS IS with no expressed or implied warranty. | |
// You have the right to use this code or any portion of it | |
// so long as you provide credit toward myself as the original author. | |
// | |
// ******************************************* | |
*/ | |
package com.handinteractive.mobile; | |
import javax.servlet.http.HttpServletRequest; | |
/** | |
* The DetectSmartPhone class encapsulates information about | |
* a browser's connection to your web site. | |
* You can use it to find out whether the browser asking for | |
* your site's content is probably running on a mobile device. | |
* The methods were written so you can be as granular as you want. | |
* For example, enquiring whether it's as specific as an iPod Touch or | |
* as general as a smartphone class device. | |
* The object's methods return true, or false. | |
*/ | |
public class UAgentInfo { | |
// User-Agent and Accept HTTP request headers | |
private String userAgent = ""; | |
private String httpAccept = ""; | |
// Initialize some initial smartphone string variables. | |
public static final String engineWebKit = "webkit"; | |
public static final String deviceAndroid = "android"; | |
public static final String deviceIphone = "iphone"; | |
public static final String deviceIpod = "ipod"; | |
public static final String deviceSymbian = "symbian"; | |
public static final String deviceS60 = "series60"; | |
public static final String deviceS70 = "series70"; | |
public static final String deviceS80 = "series80"; | |
public static final String deviceS90 = "series90"; | |
public static final String deviceWinMob = "windows ce"; | |
public static final String deviceWindows = "windows"; | |
public static final String deviceIeMob = "iemobile"; | |
public static final String enginePie = "wm5 pie"; //An old Windows Mobile | |
public static final String deviceBB = "blackberry"; | |
public static final String vndRIM = "vnd.rim"; //Detectable when BB devices emulate IE or Firefox | |
public static final String deviceBBStorm = "blackberry95"; //Storm 1 and 2 | |
public static final String devicePalm = "palm"; | |
public static final String deviceWebOS = "webos"; //For Palm's new WebOS devices | |
public static final String engineBlazer = "blazer"; //Old Palm | |
public static final String engineXiino = "xiino"; //Another old Palm | |
//Initialize variables for mobile-specific content. | |
public static final String vndwap = "vnd.wap"; | |
public static final String wml = "wml"; | |
//Initialize variables for other random devices and mobile browsers. | |
public static final String deviceBrew = "brew"; | |
public static final String deviceDanger = "danger"; | |
public static final String deviceHiptop = "hiptop"; | |
public static final String devicePlaystation = "playstation"; | |
public static final String deviceNintendoDs = "nitro"; | |
public static final String deviceNintendo = "nintendo"; | |
public static final String deviceWii = "wii"; | |
public static final String deviceXbox = "xbox"; | |
public static final String deviceArchos = "archos"; | |
public static final String engineOpera = "opera"; //Popular browser | |
public static final String engineNetfront = "netfront"; //Common embedded OS browser | |
public static final String engineUpBrowser = "up.browser"; //common on some phones | |
public static final String engineOpenWeb = "openweb"; //Transcoding by OpenWave server | |
public static final String deviceMidp = "midp"; //a mobile Java technology | |
public static final String uplink = "up.link"; | |
public static final String devicePda = "pda"; //some devices report themselves as PDAs | |
public static final String mini = "mini"; //Some mobile browsers put "mini" in their names. | |
public static final String mobile = "mobile"; //Some mobile browsers put "mobile" in their user agent strings. | |
public static final String mobi = "mobi"; //Some mobile browsers put "mobi" in their user agent strings. | |
//Use Maemo, Tablet, and Linux to test for Nokia"s Internet Tablets. | |
public static final String maemo = "maemo"; | |
public static final String maemoTablet = "tablet"; | |
public static final String linux = "linux"; | |
public static final String qtembedded = "qt embedded"; //for Sony Mylo | |
public static final String mylocom2 = "com2"; //for Sony Mylo also | |
//In some UserAgents, the only clue is the manufacturer. | |
public static final String manuSonyEricsson = "sonyericsson"; | |
public static final String manuericsson = "ericsson"; | |
public static final String manuSamsung1 = "sec-sgh"; | |
public static final String manuSony = "sony"; | |
//In some UserAgents, the only clue is the operator. | |
public static final String svcDocomo = "docomo"; | |
public static final String svcKddi = "kddi"; | |
public static final String svcVodafone = "vodafone"; | |
// Standard desktop browser detection strings | |
public static final String msie = "msie"; | |
public static final String msie60 = "msie 6.0"; | |
public static final String msie61 = "msie 6.1"; | |
public static final String msie7 = "msie 7.0"; | |
public static final String msie8 = "msie 8.0"; | |
public static final String msie9 = "msie 9.0"; | |
public static final String firefox = "firefox"; | |
public static final String safari = "apple"; | |
public static final String chrome = "chrome"; | |
public static final String opera = "presto"; | |
// OS Detection | |
public static final String windows = "windows"; | |
/** | |
* Initialize the userAgent and httpAccept variables | |
* | |
* @param userAgent the User-Agent header | |
* @param httpAccept the Accept header | |
*/ | |
public UAgentInfo(String userAgent, String httpAccept) { | |
if (userAgent != null) { | |
this.userAgent = userAgent.toLowerCase(); | |
} | |
if (httpAccept != null) { | |
this.httpAccept = httpAccept.toLowerCase(); | |
} | |
} | |
/** | |
* Initialize the userAgent and httpAccept variables by getting the headers | |
* from the HttpServletRequest | |
* | |
* @param request the HttpServletRequest to get the header information from | |
*/ | |
public UAgentInfo(HttpServletRequest request) { | |
this(request.getHeader("User-Agent"),request.getHeader("Accept")); | |
} | |
/** | |
* Return the lower case HTTP_USER_AGENT | |
*/ | |
public String getUserAgent() { | |
return userAgent; | |
} | |
/** | |
* Return the lower case HTTP_ACCEPT | |
*/ | |
public String getHttpAccept() { | |
return httpAccept; | |
} | |
/** | |
* Detects if the current device is an iPhone. | |
*/ | |
public boolean detectIphone() { | |
// The iPod touch says it's an iPhone! So let's disambiguate. | |
return userAgent.indexOf(deviceIphone) != -1 && !detectIpod(); | |
} | |
/** | |
* Detects if the current device is an iPod Touch. | |
*/ | |
public boolean detectIpod() { | |
return userAgent.indexOf(deviceIpod) != -1; | |
} | |
/** | |
* Detects if the current device is an iPhone or iPod Touch. | |
*/ | |
public boolean detectIphoneOrIpod() { | |
//We repeat the searches here because some iPods may report themselves as an iPhone, which would be okay. | |
return userAgent.indexOf(deviceIphone) != -1 || userAgent.indexOf(deviceIpod) != -1; | |
} | |
/** | |
* Detects if the current device is an Android OS-based device. | |
*/ | |
public boolean detectAndroid() { | |
return userAgent.indexOf(deviceAndroid) != -1; | |
} | |
/** | |
* Detects if the current device is an Android OS-based device and | |
* the browser is based on WebKit. | |
*/ | |
public boolean detectAndroidWebKit() { | |
return detectAndroid() && detectWebkit(); | |
} | |
/** | |
* Detects if the current browser is based on WebKit. | |
*/ | |
public boolean detectWebkit() { | |
return userAgent.indexOf(engineWebKit) != -1; | |
} | |
/** | |
* Detects if the current browser is the S60 Open Source Browser. | |
*/ | |
public boolean detectS60OssBrowser() { | |
//First, test for WebKit, then make sure it's either Symbian or S60. | |
return detectWebkit() && (userAgent.indexOf(deviceSymbian) != -1 || userAgent.indexOf(deviceS60) != -1); | |
} | |
/** | |
* | |
* Detects if the current device is any Symbian OS-based device, | |
* including older S60, Series 70, Series 80, Series 90, and UIQ, | |
* or other browsers running on these devices. | |
*/ | |
public boolean detectSymbianOS() { | |
return userAgent.indexOf(deviceSymbian) != -1 || userAgent.indexOf(deviceS60) != -1 || | |
userAgent.indexOf(deviceS70) != -1 || userAgent.indexOf(deviceS80) != -1 || | |
userAgent.indexOf(deviceS90) != -1; | |
} | |
/** | |
* Detects if the current browser is a Windows Mobile device. | |
*/ | |
public boolean detectWindowsMobile() { | |
//Most devices use 'Windows CE', but some report 'iemobile' | |
// and some older ones report as 'PIE' for Pocket IE. | |
return userAgent.indexOf(deviceWinMob) != -1 || | |
userAgent.indexOf(deviceIeMob) != -1 || | |
userAgent.indexOf(enginePie) != -1 || | |
(detectWapWml() && userAgent.indexOf(deviceWindows) != -1); | |
} | |
/** | |
* Detects if the current browser is a BlackBerry of some sort. | |
*/ | |
public boolean detectBlackBerry() { | |
return userAgent.indexOf(deviceBB) != -1 || httpAccept.indexOf(vndRIM) != -1; | |
} | |
/** | |
* Detects if the current browser is a BlackBerry Touch | |
* device, such as the Storm | |
*/ | |
public boolean detectBlackBerryTouch() { | |
return userAgent.indexOf(deviceBBStorm) != -1; | |
} | |
/** | |
* Detects if the current browser is on a PalmOS device. | |
*/ | |
public boolean detectPalmOS() { | |
//Most devices nowadays report as 'Palm', but some older ones reported as Blazer or Xiino. | |
if (userAgent.indexOf(devicePalm) != -1 || userAgent.indexOf(engineBlazer) != -1 || | |
userAgent.indexOf(engineXiino) != -1 && !detectPalmWebOS()) { | |
//Make sure it's not WebOS first | |
if (detectPalmWebOS()) { return false; } | |
else { return true; } | |
} | |
return false; | |
} | |
/** | |
* Detects if the current browser is on a Palm device | |
* running the new WebOS. | |
*/ | |
public boolean detectPalmWebOS() { | |
return userAgent.indexOf(deviceWebOS) != -1; | |
} | |
/** | |
* Check to see whether the device is any device | |
* in the 'smartphone' category. | |
*/ | |
public boolean detectSmartphone() { | |
return (detectIphoneOrIpod() || | |
detectS60OssBrowser() || | |
detectSymbianOS() || | |
detectWindowsMobile() || | |
detectBlackBerry() || | |
detectPalmOS() || | |
detectPalmWebOS() || | |
detectAndroid()); | |
} | |
/** | |
* Detects whether the device is a Brew-powered device. | |
*/ | |
public boolean detectBrewDevice() { | |
return userAgent.indexOf(deviceBrew) != -1; | |
} | |
/** | |
* Detects the Danger Hiptop device. | |
*/ | |
public boolean detectDangerHiptop() { | |
return userAgent.indexOf(deviceDanger) != -1 || userAgent.indexOf(deviceHiptop) != -1; | |
} | |
/** | |
* Detects Opera Mobile or Opera Mini. | |
* Added by AHand | |
*/ | |
public boolean detectOperaMobile() { | |
return userAgent.indexOf(engineOpera) != -1 && (userAgent.indexOf(mini) != -1 || userAgent.indexOf(mobi) != -1); | |
} | |
/** | |
* Detects whether the device supports WAP or WML. | |
*/ | |
public boolean detectWapWml() { | |
return httpAccept.indexOf(vndwap) != -1 || httpAccept.indexOf(wml) != -1; | |
} | |
/** | |
* The quick way to detect for a mobile device. | |
* Will probably detect most recent/current mid-tier Feature Phones | |
* as well as smartphone-class devices. | |
*/ | |
public boolean detectMobileQuick() { | |
//Ordered roughly by market share, WAP/XML > Brew > Smartphone. | |
if (detectWapWml()) { return true; } | |
if (detectBrewDevice()) { return true; } | |
// Updated by AHand | |
if (detectOperaMobile()) { return true; } | |
if (userAgent.indexOf(engineUpBrowser) != -1) { return true; } | |
if (userAgent.indexOf(engineOpenWeb) != -1) { return true; } | |
if (userAgent.indexOf(deviceMidp) != -1) { return true; } | |
if (detectSmartphone()) { return true; } | |
if (detectDangerHiptop()) { return true; } | |
if (detectMidpCapable()) { return true; } | |
if (userAgent.indexOf(devicePda) != -1) { return true; } | |
if (userAgent.indexOf(mobile) != -1) { return true; } | |
//detect older phones from certain manufacturers and operators. | |
if (userAgent.indexOf(uplink) != -1) { return true; } | |
if (userAgent.indexOf(manuSonyEricsson) != -1) { return true; } | |
if (userAgent.indexOf(manuericsson) != -1) { return true; } | |
if (userAgent.indexOf(manuSamsung1) != -1) { return true; } | |
if (userAgent.indexOf(svcDocomo) != -1) { return true; } | |
if (userAgent.indexOf(svcKddi) != -1) { return true; } | |
if (userAgent.indexOf(svcVodafone) != -1) { return true; } | |
return false; | |
} | |
/** | |
* Detects if the current device is a Sony Playstation. | |
*/ | |
public boolean detectSonyPlaystation() { | |
return userAgent.indexOf(devicePlaystation) != -1; | |
} | |
/** | |
* Detects if the current device is a Nintendo game device. | |
*/ | |
public boolean detectNintendo() { | |
return userAgent.indexOf(deviceNintendo) != -1 || userAgent.indexOf(deviceWii) != -1 || | |
userAgent.indexOf(deviceNintendoDs) != -1; | |
} | |
/** | |
* Detects if the current device is a Microsoft Xbox. | |
*/ | |
public boolean detectXbox() { | |
return userAgent.indexOf(deviceXbox) != -1; | |
} | |
/** | |
* Detects if the current device is an Internet-capable game console. | |
*/ | |
public boolean detectGameConsole() { | |
return detectSonyPlaystation() || detectNintendo() || detectXbox(); | |
} | |
/** | |
* Detects if the current device supports MIDP, a mobile Java technology. | |
*/ | |
public boolean detectMidpCapable() { | |
return userAgent.indexOf(deviceMidp) != -1 || httpAccept.indexOf(deviceMidp) != -1; | |
} | |
/** | |
* Detects if the current device is on one of the Maemo-based Nokia Internet Tablets. | |
*/ | |
public boolean detectMaemoTablet() { | |
return (userAgent.indexOf(maemo) != -1 || (userAgent.indexOf(maemoTablet) != -1 && userAgent.indexOf(linux) != -1)); | |
} | |
/** | |
* Detects if the current device is an Archos media player/Internet tablet. | |
*/ | |
public boolean detectArchos() { | |
return userAgent.indexOf(deviceArchos) != -1; | |
} | |
/** | |
* Detects if the current browser is a Sony Mylo device. | |
* Updated by AHand | |
*/ | |
public boolean detectSonyMylo() { | |
return userAgent.indexOf(manuSony) != -1 && (userAgent.indexOf(qtembedded) != -1 || | |
userAgent.indexOf(mylocom2) != -1); | |
} | |
/** | |
* The longer and more thorough way to detect for a mobile device. | |
* Will probably detect most feature phones, | |
* smartphone-class devices, Internet Tablets, | |
* Internet-enabled game consoles, etc. | |
* This ought to catch a lot of the more obscure and older devices, also — | |
* but no promises on thoroughness! | |
*/ | |
public boolean detectMobileLong() { | |
return detectMobileQuick() || detectMaemoTablet() || detectGameConsole(); | |
} | |
//***************************** | |
// For Desktop Browsers | |
//***************************** | |
public boolean detectMSIE() { | |
return userAgent.indexOf(msie) != -1; | |
} | |
public boolean detectMSIE6() { | |
return userAgent.indexOf(msie60) != -1 && userAgent.indexOf(msie61) != -1; | |
} | |
public boolean detectMSIE7() { | |
return userAgent.indexOf(msie7) != -1; | |
} | |
public boolean detectMSIE8() { | |
return userAgent.indexOf(msie8) != -1; | |
} | |
public boolean detectMSIE9() { | |
return userAgent.indexOf(msie9) != -1; | |
} | |
public boolean detectFirefox() { | |
return userAgent.indexOf(firefox) != -1; | |
} | |
public boolean detectSafari() { | |
return userAgent.indexOf(safari) != -1; | |
} | |
public boolean detectChrome() { | |
return userAgent.indexOf(chrome) != -1; | |
} | |
public boolean detectOpera() { | |
return userAgent.indexOf(opera) != -1; | |
} | |
public boolean detectWindows() { | |
return userAgent.indexOf(windows) != -1; | |
} | |
//***************************** | |
// For Mobile Web Site Design | |
//***************************** | |
/** | |
* The quick way to detect for a tier of devices. | |
* This method detects for devices which can | |
* display iPhone-optimized web content. | |
* Includes iPhone, iPod Touch, Android, Palm WebOS, etc. | |
*/ | |
public boolean detectTierIphone() { | |
return detectIphoneOrIpod() || detectPalmWebOS() || detectAndroid() || detectAndroidWebKit(); | |
} | |
/** | |
* The quick way to detect for a tier of devices. | |
* This method detects for all smartphones, but | |
* excludes the iPhone Tier devices. | |
*/ | |
public boolean detectTierSmartphones() { | |
return detectSmartphone() && (!detectTierIphone()); | |
} | |
/** | |
* The quick way to detect for a tier of devices. | |
* This method detects for all other types of phones, | |
* but excludes the iPhone and Smartphone Tier devices. | |
*/ | |
public boolean detectTierOtherPhones() { | |
return detectMobileQuick() && (!detectTierIphone()) && (!detectTierSmartphones()); | |
} | |
} |