判断是否是手机访问及手机操作系统

简介:

我们现在做的项目,移动端和PC端网站访问的是同一套接口,那么如何在接口中区分是手机访问还是PC短访问呢?

核心思想:根据请求头(request header)来判断,如何请求没有header或伪造user agent则无法判断.

先看一些user agent的实例:

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0

Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) (Engine, like URL) Mobile/12B440 MicroMessenger/6.0.1 NetType/3G+

 

Mozilla/5.0 (Linux; U; Android 4.1.1; en-cn; HTC T528d) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.2.58_r984381.520 NetType/WIFI

 

Mozilla/5.0 (Linux; U; Android 4.2.2; zh-CN; 2013023 Build/HM2013023) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.5.489 U3/0.8.0 Mobile Safari/533.1

 

Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10

 

Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; HUAWEI G700-U00 Build/HuaweiG700-U00) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 V1_AND_SQ_5.3.1_196_YYB_D QQ/5.3.1.2335 NetType/WIFI

 

Mozilla/5.0 (Linux; U; Android 4.0.4; zh-cn; HS-EG906 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/5.3.1.67_r745169.462

 

Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; GT-I9500 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.0 QQ-Manager Mobile Safari/537.36



 

以下是我封装的一套方法

ClientOsInfo 是用于保存访问设备信息的,结构如下(省略getter,setter):

Java代码   收藏代码
  1. public class ClientOsInfo {  
  2.     /*** 
  3.      * 比如 Android_3.0 
  4.      */  
  5.     private String osTypeVersion;  
  6.     /*** 
  7.      * Pad或Phone 
  8.      */  
  9.     private String deviceType;  
  10.     /*** 
  11.      * os type 
  12.      */  
  13.     private String osType;  
  14.     /*** 
  15.      * 只是版本号,例如"4.1.1" 
  16.      */  
  17.     private String version;  
  18.     private String userAgent;  
  19. /*** 
  20.      * 是否是移动设备 
  21.      * @return 
  22.      */  
  23.     public boolean isMobile(){  
  24.         return (!ValueWidget.isNullOrEmpty(this.deviceType));  
  25.     }  
  26. }  

 核心方法:

Java代码   收藏代码
  1. /*** 
  2.  * 当移动端(手机或Pad)访问网页时获取移动端操作系统信息 
  3.  * @param request 
  4.  * @return 
  5.  */  
  6. public static ClientOsInfo getMobileOsInfo(HttpServletRequest request){  
  7.     String userAgent=request.getHeader("user-agent");  
  8.     if(ValueWidget.isNullOrEmpty(userAgent)){  
  9.         userAgent=request.getHeader("User-Agent");  
  10.     }  
  11.     ClientOsInfo info= HeaderUtil.getMobilOS(userAgent);  
  12.     info.setUserAgent(userAgent);  
  13.     return info;  
  14. }  

 

核心工具类:用于解析user agent

Java代码   收藏代码
  1. package com.common.util;  
  2.   
  3. import java.util.regex.Matcher;  
  4. import java.util.regex.Pattern;  
  5.   
  6. import com.common.bean.ClientOsInfo;  
  7. import com.string.widget.util.ValueWidget;  
  8.   
  9. /*** 
  10.  *  
  11.  * @author huangwei 
  12.  * @since 2013-08-15 
  13.  */  
  14. public class HeaderUtil {  
  15.     public static final String OSTYPE_ANDROID="Android";  
  16.     public static final String OSTYPE_IOS="Ios";  
  17.     public static final String OSTYPE_WP="WINDOWS PHONE";  
  18.     public static final String OSTYPE_BLACKBERRY="BLACKBERRY";  
  19.     /*** 
  20.      * pad 
  21.      */  
  22.     public static final String DEVICE_TYPE_PAD="Pad";  
  23.     /*** 
  24.      * 手机 
  25.      */  
  26.     public static final String DEVICE_TYPE_PHONE="Phone";  
  27.   
  28.   
  29.     /*** 
  30.      * 校验渠道终端版本号是否合法,eg:0.0.0.3 
  31.      *  
  32.      * @param clientVersion 
  33.      * @return true-->合法 ;false-->非法 
  34.      */  
  35.     public static boolean verifyClientVersion(String clientVersion) {  
  36.         boolean result = Pattern.matches("[\\d\\.]+", clientVersion);  
  37.         if (result) {  
  38.             result = Pattern.matches("^\\d\\.\\d\\.\\d\\.\\d$", clientVersion);  
  39.             return result;  
  40.         } else {  
  41.             return false;  
  42.         }  
  43.     }  
  44.       
  45.     /** 
  46.      * 根据useragent和手机厂商查手机型号 
  47.      *  
  48.      * @param UA 
  49.      * @param vendor 
  50.      * @return 
  51.      */  
  52.     public static String getMobModel(String UA, String operatingSystem) {  
  53.         if (UA == null) {  
  54.             return null;  
  55.         }  
  56.         // 存放正则表达式  
  57.         String rex = "";  
  58.         // 苹果产品  
  59.         if (operatingSystem.indexOf("IOS") != -1) {  
  60.             if (UA.indexOf("IPAD") != -1) {// 判断是否为ipad  
  61.                 return "IPAD";  
  62.             }  
  63.             if (UA.indexOf("IPOD") != -1) {// 判断是否为ipod  
  64.                 return "IPOD";  
  65.             }  
  66.             if (UA.indexOf("IPONE") != -1) {// 判断是否为ipone  
  67.                 return "IPONE";  
  68.             }  
  69.             return "IOS DEVICE";  
  70.   
  71.         }  
  72.         // 安卓系统产品  
  73.         if (operatingSystem.indexOf("ANDROID") != -1) {  
  74.             String re = "BUILD";  
  75.             rex = ".*" + ";" + "(.*)" + re;  
  76.             Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
  77.             Matcher m = p.matcher(UA);  
  78.             boolean rs = m.find();  
  79.             if (rs) {  
  80.                 System.out.println("Mobil Model is" + m.group(1));  
  81.                 return m.group(1);  
  82.             }  
  83.         }  
  84.         return null;  
  85.     }  
  86.   
  87.     /** 
  88.      * 判断手机的操作系统 IOS/android/windows phone/BlackBerry 
  89.      *  
  90.      * @param UA 
  91.      * @return 
  92.      */  
  93.     public static ClientOsInfo getMobilOS(String UA) {  
  94.         UA=UA.toUpperCase();  
  95.         if (UA == null) {  
  96.             return null;  
  97.         }  
  98.         ClientOsInfo osInfo=new  ClientOsInfo();  
  99.         // 存放正则表达式  
  100.         String rex = "";  
  101.         // IOS 判断字符串  
  102.         String iosString = " LIKE MAC OS X";  
  103.         if (UA.indexOf(iosString) != -1) {  
  104.             if(isMatch(UA, "\\([\\s]*iPhone[\\s]*;", Pattern.CASE_INSENSITIVE)){  
  105.                 osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
  106.             }else if(isMatch(UA, "\\([\\s]*iPad[\\s]*;", Pattern.CASE_INSENSITIVE)){  
  107.                 osInfo.setDeviceType(DEVICE_TYPE_PAD);  
  108.             }  
  109.             rex = ".*" + "[\\s]+(\\d[_\\d]*)" + iosString;  
  110.             Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
  111.             Matcher m = p.matcher(UA);  
  112.             boolean rs = m.find();  
  113.             if (rs) {  
  114.                 String osVersion= m.group(1).replace("_"".");  
  115.                 osInfo.setVersion(osVersion);  
  116. //              System.out.println("Mobil OS is" + " IOS" +osVersion);  
  117.                 osInfo.setOsTypeVersion(OSTYPE_IOS+"_" + osVersion);  
  118.             }else{  
  119.                 System.out.println("IOS");  
  120.                 osInfo.setOsTypeVersion(OSTYPE_IOS);  
  121.             }  
  122.             osInfo.setOsType(OSTYPE_IOS);  
  123.             return osInfo;  
  124.         }  
  125.         // Android 判断  
  126.         String androidString = "ANDROID";  
  127.         if (UA.indexOf(androidString) != -1) {  
  128.             if(isMatch(UA, "\\bMobi", Pattern.CASE_INSENSITIVE)){  
  129.                 osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
  130.             }else {  
  131.                 osInfo.setDeviceType(DEVICE_TYPE_PAD);  
  132.             }  
  133.             rex = ".*" + androidString + "[\\s]*(\\d*[\\._\\d]*)";  
  134.             Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
  135.             Matcher m = p.matcher(UA);  
  136.             boolean rs = m.find();  
  137.             if (rs) {  
  138.                 String version=m.group(1).replace("_"".");  
  139.                 osInfo.setVersion(version);  
  140.                 System.out.println("Mobil OS is " + OSTYPE_ANDROID + version);  
  141.                 osInfo.setOsTypeVersion(OSTYPE_ANDROID+"_" + version);  
  142.             }else{  
  143.                 System.out.println("Android");  
  144.                 osInfo.setOsTypeVersion(OSTYPE_ANDROID);  
  145.             }  
  146.             osInfo.setOsType(OSTYPE_ANDROID);  
  147.             return osInfo;  
  148.         }  
  149.         // windows phone 判断  
  150.         String wpString = "WINDOWS PHONE";  
  151.         if (UA.indexOf(wpString) != -1) {  
  152.             rex = ".*" + wpString + "[\\s]*[OS\\s]*([\\d][\\.\\d]*)";  
  153.             Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
  154.             Matcher m = p.matcher(UA);  
  155.             boolean rs = m.find();  
  156.             if (rs) {  
  157.                 System.out.println("Mobil OS is " + OSTYPE_WP + m.group(1));  
  158.                 String version=m.group(1);  
  159.                 osInfo.setVersion(version);  
  160.                 osInfo.setOsTypeVersion(OSTYPE_WP+"_" + version);  
  161.             }else{  
  162.                 System.out.println("WINDOWS PHONE");  
  163.                 osInfo.setOsTypeVersion(OSTYPE_WP);  
  164.             }  
  165.             osInfo.setOsType(OSTYPE_WP);  
  166.             return osInfo;  
  167.         }  
  168.         // BlackBerry 黑莓系统判断  
  169.         String bbString = "BLACKBERRY";  
  170.         if (UA.indexOf(bbString) != -1) {  
  171.             rex = ".*" + bbString + "[\\s]*([\\d]*)";  
  172.             Pattern p = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);  
  173.             Matcher m = p.matcher(UA);  
  174.             boolean rs = m.find();  
  175.             if (rs) {  
  176.                 System.out.println("Mobil OS is" + " BLACKBERRY " + m.group(1));  
  177.                 String version=m.group(1);  
  178.                 osInfo.setVersion(version);  
  179.                 osInfo.setOsTypeVersion(OSTYPE_BLACKBERRY+"_" + version);  
  180.             }else{  
  181.                 System.out.println("BLACKBERRY");  
  182.                 osInfo.setOsTypeVersion(OSTYPE_BLACKBERRY);  
  183.             }  
  184.             osInfo.setOsType(OSTYPE_BLACKBERRY);  
  185.             return osInfo;  
  186.         }  
  187.         if(UA.contains("LINUX")){//android  
  188.             if(isMatch(UA, "\\bMobi", Pattern.CASE_INSENSITIVE)){  
  189.                 osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
  190.             }else {  
  191.                 osInfo.setDeviceType(DEVICE_TYPE_PAD);  
  192.             }  
  193.               
  194.              Pattern p = Pattern.compile("U;\\s*(Adr[\\s]*)?(\\d[\\.\\d]*\\d)[\\s]*;",Pattern.CASE_INSENSITIVE);  
  195.                 Matcher m = p.matcher(UA);  
  196.                 boolean result = m.find();  
  197.                 String find_result = null;  
  198.                 if (result)  
  199.                 {  
  200.                     find_result = m.group(2);  
  201.                 }  
  202.                 if(ValueWidget.isNullOrEmpty(find_result)){  
  203.                     osInfo.setOsTypeVersion(OSTYPE_ANDROID);  
  204.                     return osInfo;  
  205.                 }else{  
  206.                     osInfo.setVersion(find_result);  
  207.                     osInfo.setOsTypeVersion(OSTYPE_ANDROID+"_"+find_result);  
  208.                     return osInfo;  
  209.                 }  
  210.         }  
  211.           
  212.         //UCWEB/2.0 (iOS; U; iPh OS 4_3_2; zh-CN; iPh4)  
  213.         if(UA.matches(".*((IOS)|(iPAD)).*(IPH).*")){  
  214.             if(isMatch(UA, "[\\s]*iPh[\\s]*", Pattern.CASE_INSENSITIVE)){  
  215.                 osInfo.setDeviceType(DEVICE_TYPE_PHONE);  
  216.             }else {  
  217.                 osInfo.setDeviceType(DEVICE_TYPE_PAD);  
  218.             }  
  219.              Pattern p = Pattern.compile("U;\\s*(IPH[\\s]*)?(OS[\\s]*)?(\\d[\\._\\d]*\\d)[\\s]*;",Pattern.CASE_INSENSITIVE);  
  220.                 Matcher m = p.matcher(UA);  
  221.                 boolean result = m.find();  
  222.                 String find_result = null;  
  223.                 if (result)  
  224.                 {  
  225.                     find_result = m.group(3);  
  226.                 }  
  227.                 if(ValueWidget.isNullOrEmpty(find_result)){  
  228.                     osInfo.setOsTypeVersion(OSTYPE_IOS);  
  229.                     osInfo.setOsType(OSTYPE_IOS);  
  230.                     return osInfo;  
  231.                 }else{  
  232.                     String version=find_result.replace("_"".");  
  233.                     osInfo.setVersion(version);  
  234.                     osInfo.setOsTypeVersion(OSTYPE_IOS+"_"+version);  
  235.                     osInfo.setOsType(OSTYPE_IOS);  
  236.                     return osInfo;  
  237.                 }  
  238.         }  
  239.         return osInfo;  
  240.     }  
  241.     public static boolean isMatch(String source,String regx,int flags){  
  242.         Pattern p = Pattern.compile(regx,flags);  
  243.         Matcher m = p.matcher(source);  
  244.         boolean result = m.find();  
  245.         return result;  
  246.     }  
  247.   
  248. }  

 

应用场景:

 

通过user agent判断是否是手机

Java代码   收藏代码
  1. /*** 
  2.      * 判断是否是手机(移动端) 
  3.      * @param userAgent 
  4.      * @return 
  5.      */  
  6.     public static boolean isMobile(String userAgent)  
  7.     {  
  8.         userAgent=userAgent.toLowerCase();  
  9.         String []mobile_agents = {"240x320","acer","acoon","acs-","abacho","ahong","airness","alcatel","amoi","android","anywhereyougo.com","applewebkit/525","applewebkit/532","asus","audio","au-mic","avantogo","becker","benq","bilbo","bird","blackberry","blazer","bleu","cdm-","compal","coolpad","danger","dbtel","dopod","elaine","eric","etouch","fly ","fly_","fly-","go.web","goodaccess","gradiente","grundig","haier","hedy","hitachi","htc","huawei","hutchison","inno","ipad","ipaq","ipod","jbrowser","kddi","kgt","kwc","lenovo","lg ","lg2","lg3","lg4","lg5","lg7","lg8","lg9","lg-","lge-","lge9","longcos","maemo","mercator","meridian","micromax","midp","mini","mitsu","mmm","mmp","mobi","mot-","moto","nec-","netfront","newgen","nexian","nf-browser","nintendo","nitro","nokia","nook","novarra","obigo","palm","panasonic","pantech","philips","phone","pg-","playstation","pocket","pt-","qc-","qtek","rover","sagem","sama","samu","sanyo","samsung","sch-","scooter","sec-","sendo","sgh-","sharp","siemens","sie-","softbank","sony","spice","sprint","spv","symbian","tablet","talkabout","tcl-","teleca","telit","tianyu","tim-","toshiba","tsm","up.browser","utec","utstar","verykool","virgin","vk-","voda","voxtel","vx","wap","wellco","wig browser","wii","windows ce","wireless","xda","xde","zte"};  
  10.         boolean is_mobile = false;  
  11.         for (String device : mobile_agents) {  
  12.             if(userAgent.contains(device)){  
  13.                 is_mobile=true;  
  14.                 break;  
  15.             }  
  16.         }  
  17.         return is_mobile;  
  18.     }  

 测试代码:

Java代码   收藏代码
  1. @Test  
  2.     public void test_userAgent()  
  3.     {  
  4.         String userAgent="Mozilla/5.0 (Linux; U; Android 4.1.1; en-cn; HTC T528d) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 MicroMessenger/6.0.2.58_r984381.520 NetType/WIFI";  
  5.         System.out.println(HeaderUtil.isMobile(userAgent));  
  6.           
  7.         userAgent="Opera/9.80 (Android 2.3.7; Linux; Opera Mobi/46154) Presto/2.11.355 Version/12.10";  
  8.         System.out.println(HeaderUtil.isMobile(userAgent));  
  9.     }  
相关文章
|
7月前
|
人工智能 安全 搜索推荐
未来智能手机操作系统的发展趋势
在过去几十年里,智能手机操作系统一直处于不断发展和演变的过程中。从最初的简单功能到如今的强大生态系统,智能手机操作系统已经成为人们日常生活和工作中不可或缺的一部分。本文将探讨未来智能手机操作系统的发展趋势,包括人工智能、增强现实、安全性和用户体验等方面的创新和突破。
|
1月前
|
安全 搜索推荐 Android开发
Android vs. iOS:解锁智能手机操作系统的奥秘####
【10月更文挑战第21天】 在当今这个数字化时代,智能手机已成为我们生活中不可或缺的伙伴。本文旨在深入浅出地探讨两大主流操作系统——Android与iOS的核心差异、优势及未来趋势,帮助读者更好地理解这两个平台背后的技术哲学和用户体验设计。通过对比分析,揭示它们如何塑造了我们的数字生活方式,并展望未来可能的发展路径。无论您是技术爱好者还是普通用户,这篇文章都将带您走进一个充满创新与可能性的移动世界。 ####
57 3
|
5月前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
6月前
Discuz 手机版访问自动跳转到手机域名
Discuz 手机版访问自动跳转到手机域名
98 1
|
5月前
|
Python
Python的`signal`模块提供了访问底层操作系统提供的信号机制的方式。信号是操作系统用来通知进程发生了某种情况(如用户按下Ctrl+C)的一种机制。
Python的`signal`模块提供了访问底层操作系统提供的信号机制的方式。信号是操作系统用来通知进程发生了某种情况(如用户按下Ctrl+C)的一种机制。
|
5月前
|
JavaScript
vue 项目/备案网页/ip网页打包成 apk 安装到平板/手机(含vue项目跨域代理打包成apk后无法访问接口的解决方案)
vue 项目/备案网页/ip网页打包成 apk 安装到平板/手机(含vue项目跨域代理打包成apk后无法访问接口的解决方案)
126 0
|
5月前
|
Web App开发
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
软件开发常见流程之移动端调试方法,利用Chrome(谷歌浏览器)的模拟手机调试,搭建本地Web服务器,手机和服务器在一个局域网,通过手机访问服务器,使用服务器,利用ip实现域名访问
|
5月前
|
Linux 网络安全 数据安全/隐私保护
网络安全教程-------渗透工具Kali,官网链接,ARM的介绍,Mobil,华为小米,oppe手机,是无法刷入第三方的操作系统的,E+手机,谷歌的picksoul,或者三星手机,系统盘是WSL的
网络安全教程-------渗透工具Kali,官网链接,ARM的介绍,Mobil,华为小米,oppe手机,是无法刷入第三方的操作系统的,E+手机,谷歌的picksoul,或者三星手机,系统盘是WSL的
|
6月前
|
JavaScript
技术心得:根据不同访问设备跳转到PC页面或手机页面
技术心得:根据不同访问设备跳转到PC页面或手机页面
70 0
|
6月前
|
人工智能 安全 vr&ar
探索未来智能手机操作系统的发展趋势
本文将从技术角度探讨智能手机操作系统未来的发展趋势,分析安卓和iOS在人工智能、虚拟现实、物联网等领域的应用,展望未来智能手机操作系统的创新方向。
38 0