Android 判断用户2G/3G/4G移动数据网络

在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以在 App 的设置模块里,让用户自己选择,在 2G / 3G / 4G 网络条件下,是否允许请求一些流量比较大的数据。

通过 Android 提供的 TelephonyManager 和 ConnectivityManager 都可以获取到 NetworksInfo 对象,可以通过 getType() 获取类型,判断是 wifi 还是 mobile ,如果是 mobile ,可以通过 NetworksInfo 对象的 getSubType() 和 getSubTypeName() 可以获取到对于的网络类型和名字。

网络类型和名字定义在 TelephonyManager 类里。

  1. /** Network type is unknown */
  2. public static final int NETWORK_TYPE_UNKNOWN = 0;
  3. /** Current network is GPRS */
  4. public static final int NETWORK_TYPE_GPRS = 1;
  5. /** Current network is EDGE */
  6. public static final int NETWORK_TYPE_EDGE = 2;
  7. /** Current network is UMTS */
  8. public static final int NETWORK_TYPE_UMTS = 3;
  9. /** Current network is CDMA: Either IS95A or IS95B*/
  10. public static final int NETWORK_TYPE_CDMA = 4;
  11. /** Current network is EVDO revision 0*/
  12. public static final int NETWORK_TYPE_EVDO_0 = 5;
  13. /** Current network is EVDO revision A*/
  14. public static final int NETWORK_TYPE_EVDO_A = 6;
  15. /** Current network is 1xRTT*/
  16. public static final int NETWORK_TYPE_1xRTT = 7;
  17. /** Current network is HSDPA */
  18. public static final int NETWORK_TYPE_HSDPA = 8;
  19. /** Current network is HSUPA */
  20. public static final int NETWORK_TYPE_HSUPA = 9;
  21. /** Current network is HSPA */
  22. public static final int NETWORK_TYPE_HSPA = 10;
  23. /** Current network is iDen */
  24. public static final int NETWORK_TYPE_IDEN = 11;
  25. /** Current network is EVDO revision B*/
  26. public static final int NETWORK_TYPE_EVDO_B = 12;
  27. /** Current network is LTE */
  28. public static final int NETWORK_TYPE_LTE = 13;
  29. /** Current network is eHRPD */
  30. public static final int NETWORK_TYPE_EHRPD = 14;
  31. /** Current network is HSPA+ */
  32. public static final int NETWORK_TYPE_HSPAP = 15;

看到这个代码和注释,相信没有这方面知识的人很难看懂,都啥玩意?这注释跟没注释有啥区别?!就是让人看着更加闹心而已。所以说,注释对阅读代码的人很重要。当然这些东西可能太专业了,写这些代码的人估计是想写也不知道该怎么了,得写多大一坨啊?!我在最后会贴上一些我整理的资料,可以供大家参考一下,不是很详细,也不专业,就是大概有个印象。

TelephonyManager 还提供了 getNetworkTypeName(int type) 的方法,这个方法可以返回一个字符串,但是信息量不大。

那怎么判断是 2G , 3G 还是 4G 网络呢?TelephonyManager 还提供了另外一个方法,getNetworkClass(int networkType) ,但这个方法被隐藏掉了,我把代码贴一下。

  1. public static int getNetworkClass(int networkType) {
  2. switch (networkType) {
  3. case NETWORK_TYPE_GPRS:
  4. case NETWORK_TYPE_EDGE:
  5. case NETWORK_TYPE_CDMA:
  6. case NETWORK_TYPE_1xRTT:
  7. case NETWORK_TYPE_IDEN:
  8. return NETWORK_CLASS_2_G;
  9. case NETWORK_TYPE_UMTS:
  10. case NETWORK_TYPE_EVDO_0:
  11. case NETWORK_TYPE_EVDO_A:
  12. case NETWORK_TYPE_HSDPA:
  13. case NETWORK_TYPE_HSUPA:
  14. case NETWORK_TYPE_HSPA:
  15. case NETWORK_TYPE_EVDO_B:
  16. case NETWORK_TYPE_EHRPD:
  17. case NETWORK_TYPE_HSPAP:
  18. return NETWORK_CLASS_3_G;
  19. case NETWORK_TYPE_LTE:
  20. return NETWORK_CLASS_4_G;
  21. default:
  22. return NETWORK_CLASS_UNKNOWN;
  23. }
  24. }

  然后下面是这几个常量的值。

  1. /** Unknown network class. {@hide} */
  2. public static final int NETWORK_CLASS_UNKNOWN = 0;
  3. /** Class of broadly defined "2G" networks. {@hide} */
  4. public static final int NETWORK_CLASS_2_G = 1;
  5. /** Class of broadly defined "3G" networks. {@hide} */
  6. public static final int NETWORK_CLASS_3_G = 2;
  7. /** Class of broadly defined "4G" networks. {@hide} */
  8. public static final int NETWORK_CLASS_4_G = 3;

  

不知道为啥要把这些东西给隐藏起来,然道是不靠谱?!还是其他的更好的方式?!不知道,先这样吧,现在通过上面的手段,是可以知道用户用的是什么网络,当然也可以区分出来用户使用的是 2G , 3G 还是 4G 了。当然,你获取到这些数据后,你也可以推算出用户用的是哪家公司的网络,移动的,联通的,还是电信的,当然,只在中国。而且虚拟运营商开始真正上市后,这个就区分不出来是京东的,还是国美,苏宁的了,但是你可以知道你的手机号用的是联通的网还是移动的网。

最后贴上我收集整理的一些资料,可以参考一下。

  • GPRS : 2G(2.5) General Packet Radia Service 114kbps
  • EDGE : 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
  • UMTS : 3G WCDMA 联通3G Universal Mobile Telecommunication System 完整的3G移动通信技术标准
  • CDMA : 2G 电信 Code Division Multiple Access 码分多址
  • EVDO_0 : 3G (EVDO 全程 CDMA2000 1xEV-DO) Evolution - Data Only (Data Optimized) 153.6kps - 2.4mbps 属于3G
  • EVDO_A : 3G 1.8mbps - 3.1mbps 属于3G过渡,3.5G
  • 1xRTT : 2G CDMA2000 1xRTT (RTT - 无线电传输技术) 144kbps 2G的过渡,
  • HSDPA : 3.5G 高速下行分组接入 3.5G WCDMA High Speed Downlink Packet Access 14.4mbps
  • HSUPA : 3.5G High Speed Uplink Packet Access 高速上行链路分组接入 1.4 - 5.8 mbps
  • HSPA : 3G (分HSDPA,HSUPA) High Speed Packet Access
  • IDEN : 2G Integrated Dispatch Enhanced Networks 集成数字增强型网络 (属于2G,来自维基百科)
  • EVDO_B : 3G EV-DO Rev.B 14.7Mbps 下行 3.5G
  • LTE : 4G Long Term Evolution FDD-LTE 和 TDD-LTE , 3G过渡,升级版 LTE Advanced 才是4G
  • EHRPD : 3G CDMA2000向LTE 4G的中间产物 Evolved High Rate Packet Data HRPD的升级
  • HSPAP : 3G HSPAP 比 HSDPA 快些

有朋友说他是移动 4G 的网络,获取到的是 17。于是我又去翻了一下源码,找到了如下的代码。也就是说当有新的类型被支持的时候,Android 会增加对于的类型代码。确实 17 是 NETWORKTYPETD_SCDMA 也就是移动的那一坨。其他的代码就不贴了,大概就是这个意思。下面的代码是5.1的代码。

  1. /** Network type is unknown */
  2. public static final int NETWORK_TYPE_UNKNOWN = 0;
  3. /** Current network is GPRS */
  4. public static final int NETWORK_TYPE_GPRS = 1;
  5. /** Current network is EDGE */
  6. public static final int NETWORK_TYPE_EDGE = 2;
  7. /** Current network is UMTS */
  8. public static final int NETWORK_TYPE_UMTS = 3;
  9. /** Current network is CDMA: Either IS95A or IS95B*/
  10. public static final int NETWORK_TYPE_CDMA = 4;
  11. /** Current network is EVDO revision 0*/
  12. public static final int NETWORK_TYPE_EVDO_0 = 5;
  13. /** Current network is EVDO revision A*/
  14. public static final int NETWORK_TYPE_EVDO_A = 6;
  15. /** Current network is 1xRTT*/
  16. public static final int NETWORK_TYPE_1xRTT = 7;
  17. /** Current network is HSDPA */
  18. public static final int NETWORK_TYPE_HSDPA = 8;
  19. /** Current network is HSUPA */
  20. public static final int NETWORK_TYPE_HSUPA = 9;
  21. /** Current network is HSPA */
  22. public static final int NETWORK_TYPE_HSPA = 10;
  23. /** Current network is iDen */
  24. public static final int NETWORK_TYPE_IDEN = 11;
  25. /** Current network is EVDO revision B*/
  26. public static final int NETWORK_TYPE_EVDO_B = 12;
  27. /** Current network is LTE */
  28. public static final int NETWORK_TYPE_LTE = 13;
  29. /** Current network is eHRPD */
  30. public static final int NETWORK_TYPE_EHRPD = 14;
  31. /** Current network is HSPA+ */
  32. public static final int NETWORK_TYPE_HSPAP = 15;
  33. /** Current network is GSM {@hide} */
  34. public static final int NETWORK_TYPE_GSM = 16;
  35. /** Current network is TD_SCDMA {@hide} */
  36. public static final int NETWORK_TYPE_TD_SCDMA = 17;
  37. /** Current network is IWLAN {@hide} */
  38. public static final int NETWORK_TYPE_IWLAN = 18;

  示例:

  1. ////////
  2. /*
  3. * 前边注释和后边注释是后来加的判断网络类型
  4. */
  5. //WIFI("wifi", 1), G2("2G", 2), G3("3G", 3), WAP("wap", 4), NO("invalid", 5), ALL(
  6. //"all", 6), G4("4G",7);
  7. private static final int NETWORK_TYPE_UNAVAILABLE = 5;
  8. // private static final int NETWORK_TYPE_MOBILE = -100;
  9. private static final int NETWORK_TYPE_WIFI = 1;
  10.  
  11. private static final int NETWORK_CLASS_WIFI = 1;
  12. private static final int NETWORK_CLASS_UNAVAILABLE = 5;
  13. /** Unknown network class. */
  14. private static final int NETWORK_CLASS_UNKNOWN = 6;
  15. /** Class of broadly defined "2G" networks. */
  16. private static final int NETWORK_CLASS_2_G = 2;
  17. /** Class of broadly defined "3G" networks. */
  18. private static final int NETWORK_CLASS_3_G = 3;
  19. /** Class of broadly defined "4G" networks. */
  20. private static final int NETWORK_CLASS_4_G = 7;
  21. /**
  22. * 获取网络类型
  23. *
  24. * @return
  25. */
  26. public String getCurrentNetworkType() {
  27. int networkClass = getNetworkClass();
  28. String type = "未知";
  29. switch (networkClass) {
  30. case NETWORK_CLASS_UNAVAILABLE:
  31. type = "无";
  32. break;
  33. case NETWORK_CLASS_WIFI:
  34. type = "Wi-Fi";
  35. break;
  36. case NETWORK_CLASS_2_G:
  37. type = "2G";
  38. break;
  39. case NETWORK_CLASS_3_G:
  40. type = "3G";
  41. break;
  42. case NETWORK_CLASS_4_G:
  43. type = "4G";
  44. break;
  45. case NETWORK_CLASS_UNKNOWN:
  46. type = "未知";
  47. break;
  48. }
  49. return type;
  50. }
  51.  
  52. private int getNetworkClassByType(int networkType) {
  53. switch (networkType) {
  54. case TelephonyManager.NETWORK_TYPE_GPRS:
  55. case TelephonyManager.NETWORK_TYPE_EDGE:
  56. case TelephonyManager.NETWORK_TYPE_CDMA:
  57. case TelephonyManager.NETWORK_TYPE_1xRTT:
  58. case TelephonyManager.NETWORK_TYPE_IDEN:
  59. return NETWORK_CLASS_2_G;
  60. case TelephonyManager.NETWORK_TYPE_UMTS:
  61. case TelephonyManager.NETWORK_TYPE_EVDO_0:
  62. case TelephonyManager.NETWORK_TYPE_EVDO_A:
  63. case TelephonyManager.NETWORK_TYPE_HSDPA:
  64. case TelephonyManager.NETWORK_TYPE_HSUPA:
  65. case TelephonyManager.NETWORK_TYPE_HSPA:
  66. case TelephonyManager.NETWORK_TYPE_EVDO_B:
  67. case TelephonyManager.NETWORK_TYPE_EHRPD:
  68. case TelephonyManager.NETWORK_TYPE_HSPAP:
  69. return NETWORK_CLASS_3_G;
  70. case TelephonyManager.NETWORK_TYPE_LTE:
  71. return NETWORK_CLASS_4_G;
  72. default:
  73. return NETWORK_CLASS_UNKNOWN;
  74. }
  75. }
  76. private int getNetworkClass() {
  77.  
  78. connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
  79. networkInfo = connectivityManager.getActiveNetworkInfo();
  80.  
  81. if (networkInfo != null&& networkInfo.isConnected()) {
  82. int type = networkInfo.getType();
  83. if (type == ConnectivityManager.TYPE_WIFI) {
  84. mNetWorkType = NetEnum.WIFI.getID();
  85. } else if (type == ConnectivityManager.TYPE_MOBILE) {
  86. TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(
  87. Context.TELEPHONY_SERVICE);
  88. mNetWorkType = getNetworkClassByType(telephonyManager.getNetworkType());
  89. }
  90. } else {
  91. mNetWorkType = NETWORK_TYPE_UNAVAILABLE;
  92. }
  93. return mNetWorkType;
  94. }
  95.  
  96. ////

  参考博客:http://blog.binkery.com/android/networks_type.html

http://www.eoeandroid.com/thread-540327-1-1.html?_dsign=77a59737

最近在项目中用到啦,总结了下。。。。大部分都是别人总结好的,就直接拿过来啦,哈哈。。

转:Android 判断用户2G/3G/4G移动数据网络的更多相关文章

  1. Android 判断用户2G/3G/4G移动数据网络

    Android 判断用户2G/3G/4G移动数据网络 在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以 ...

  2. (转)Android 判断用户2G/3G/4G移动数据网络

    在做 Android App 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需(要根据用户当前网络情况来做一些调整的,也可以在 App 的设置模块里,让用户自己选择,在 2G ...

  3. Android判断用户的网络类型(2/3/4G、wifi)

    很多时候需要先判断当前用户的网络,才会继续之后的一些处理逻辑.但网络类型获取这一块,我用我自己的的手机调试时遇到一些问题,这里记录一下. 一加手机一代,移动4G 网络,得到的subtype类型值为17 ...

  4. iOS中利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G)

    前言: 在项目开发当中,往往需要利用网络.而用户的网络环境也需要我们开发者去注意,根据不同的网络状态作相应的优化,以提升用户体验. 但通常我们只会判断用户是在WIFI还是移动数据,而实际上,移动数据也 ...

  5. 利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G)

    前言: 在项目开发当中,往往需要利用网络.而用户的网络环境也需要我们开发者去注意,根据不同的网络状态作相应的优化,以提升用户体验. 但通常我们只会判断用户是在WIFI还是移动数据,而实际上,移动数据也 ...

  6. iOS中利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G) by徐文棋

    前言: 在项目开发当中,往往需要利用网络.而用户的网络环境也需要我们开发者去注意,根据不同的网络状态作相应的优化,以提升用户体验. 但通常我们只会判断用户是在WIFI还是移动数据,而实际上,移动数据也 ...

  7. iOS 中如何判断当前是2G/3G/4G/5G/WiFi

    5G 什么的,还得等苹果API更新啊,不过将来还是这个处理过程就是了. 关于判断当前的网络环境是2G/3G/4G,这个问题以前经常看到,最近在一工程里看到了如果判断的API.而在撸WebRTC音视频通 ...

  8. iOS开发-Reachability实时检测Wifi,2G/3G/4G/网络状态

    最近遇到一个功能就是根据用户当前的网络状,用户未联网需要提示一下,如果是Wifi可以推荐一些图片新闻,如果是3G模式设置为无图的模式,获取网络状态比较简单,毕竟中国现在的流量还是一个比较贵的状态,哪天 ...

  9. 通信网络 2G 3G 4G 和路由器2.4G 5G的区分和关系

    通信网络 2G 3G 4G 和路由器2.4G 5G的区分和关系 作者:魔仙圆缘链接:https://www.zhihu.com/question/34076333/answer/57850104来源: ...

随机推荐

  1. Redis配置以及通过C#访问小试

    首先安装一个Ubuntu14.04的虚拟机用来安装Redis.Ubuntu的Unity在虚拟机里面卡爆了,可以通过如下方法安装传统的Gnome界面: sudo aptitude install gno ...

  2. winform用户控件

    用途用户控件包含Time控件和一个lable控件,一个ToolStrip控件,每隔一秒显示一次时间     1. 生成用户控件   新建一个项目类型为用户控件   注意定义类名,此类名为以后工具箱中显 ...

  3. 在 Ubuntu 配置 PPTP Server

    本文在 Ubuntu 12.4 或 14 亲测有效. 建立 PPTP 服务器 首先安装 pptp 服务器. # apt-get install pptpd 然后配置 pptpd. # sudo vi ...

  4. [Git] Git 常用技巧

    版本对比 1. 对比两个 COMMIT git diff <commit> <commit> 2. 对比 COMMIT 和父 COMMIT git diff <commi ...

  5. 认识SuperSocket 1.6.4

    SuperSocket 是一个轻量级的可扩展的 Socket 开发框架,由江振宇先生开发,之所以选用它是因为一下几点恰好复合项目需求: 开源,基于Apache 2.0协议,可以免费使用到商业项目. 高 ...

  6. C++的Trigraph

    ??=include <stdio.h> class HelloWolrd ??< public: void Trigraph() ??< printf("Hello ...

  7. codeforces MUH and Important Things

    /* 题意:给一个序列,表示每一项任务的难度,要求完成每一项任务的循序是按照难度由小到大的!输出三种符合要求的工作顺序的序列! 思路:直接看代码.... */ 1 #include<iostre ...

  8. Tips10:你可以像写文档一样自由的复制粘贴游戏组件(Game Object Component)

    相对于添加组件后再进行调整和赋值,通过复制和粘贴已有游戏组件能够带来更高的效率.

  9. 一些有用的UtilityExtend小方法

    public static bool StartBy(this string thisValue, params string[] startBy) { foreach (string item in ...

  10. Sprint第三个冲刺(第七天)

    项目基本上可以说完成了,只是还有些小bug要修复.