Android判断用户2G/3G/4G移动数据网络
在做 android app 的时候,为了给用户省流量,为了不激起用户的愤怒,为了更好的用户体验,是需要根据用户当前网络情况来做一些调整的,也可以在 app 的设置模块里,让用户自己选择,在 2g / 3g / 4g 网络条件下,是否允许请求一些流量比较大的数据。
通过 android 提供的 telephonymanager 和 connectivitymanager 都可以获取到 networksinfo 对象,可以通过 gettype() 获取类型,判断是 wifi 还是 mobile ,如果是 mobile ,可以通过 networksinfo 对象的 getsubtype() 和 getsubtypename() 可以获取到对于的网络类型和名字。
网络类型和名字定义在 telephonymanager 类里。
/** network type is unknown */ public static final int network_type_unknown = 0; /** current network is gprs */ public static final int network_type_gprs = 1; /** current network is edge */ public static final int network_type_edge = 2; /** current network is umts */ public static final int network_type_umts = 3; /** current network is cdma: either is95a or is95b*/ public static final int network_type_cdma = 4; /** current network is evdo revision 0*/ public static final int network_type_evdo_0 = 5; /** current network is evdo revision a*/ public static final int network_type_evdo_a = 6; /** current network is 1xrtt*/ public static final int network_type_1xrtt = 7; /** current network is hsdpa */ public static final int network_type_hsdpa = 8; /** current network is hsupa */ public static final int network_type_hsupa = 9; /** current network is hspa */ public static final int network_type_hspa = 10; /** current network is iden */ public static final int network_type_iden = 11; /** current network is evdo revision b*/ public static final int network_type_evdo_b = 12; /** current network is lte */ public static final int network_type_lte = 13; /** current network is ehrpd */ public static final int network_type_ehrpd = 14; /** current network is hspa+ */ public static final int network_type_hspap = 15;
看到这个代码和注释,相信没有这方面知识的人很难看懂,都啥玩意?这注释跟没注释有啥区别?!就是让人看着更加闹心而已。所以说,注释对阅读代码的人很重 要。当然这些东西可能太专业了,写这些代码的人估计是想写也不知道该怎么了,得写多大一坨啊?!我在最后会贴上一些我整理的资料,可以供大家参考一下,不 是很详细,也不专业,就是大概有个印象。
telephonymanager 还提供了 getnetworktypename(int type) 的方法,这个方法可以返回一个字符串,但是信息量不大。
那怎么判断是 2g , 3g 还是 4g 网络呢?telephonymanager 还提供了另外一个方法,getnetworkclass(int networktype) ,但这个方法被隐藏掉了,我把代码贴一下。
public static int getnetworkclass(int networktype) { switch (networktype) { case network_type_gprs: case network_type_edge: case network_type_cdma: case network_type_1xrtt: case network_type_iden: return network_class_2_g; case network_type_umts: case network_type_evdo_0: case network_type_evdo_a: case network_type_hsdpa: case network_type_hsupa: case network_type_hspa: case network_type_evdo_b: case network_type_ehrpd: case network_type_hspap: return network_class_3_g; case network_type_lte: return network_class_4_g; default: return network_class_unknown; } }
然后下面是这几个常量的值。
/** unknown network class. {@hide} */ public static final int network_class_unknown = 0; /** class of broadly defined "2g" networks. {@hide} */ public static final int network_class_2_g = 1; /** class of broadly defined "3g" networks. {@hide} */ public static final int network_class_3_g = 2; /** class of broadly defined "4g" networks. {@hide} */ 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 快些
实例:
import java.io.bufferedreader; import java.io.inputstreamreader; import java.text.decimalformat; import java.util.list; import android.content.context; import android.net.connectivitymanager; import android.net.networkinfo; import android.net.wifi.wifiinfo; import android.net.wifi.wifimanager; import android.telephony.neighboringcellinfo; import android.telephony.telephonymanager; import android.telephony.cdma.cdmacelllocation; import android.telephony.gsm.gsmcelllocation; import android.util.log; public class networkutil { public static boolean iswifiavailable() { connectivitymanager connectivitymanager = (connectivitymanager) configmanager .getcontext().getsystemservice(context.connectivity_service); networkinfo networkinfo = connectivitymanager.getactivenetworkinfo(); return (networkinfo != null && networkinfo.isconnected() && networkinfo .gettype() == connectivitymanager.type_wifi); } /** * 获取mac地址 * * @param context * @return */ public static string getmacaddress(context context) { if (context == null) { return ""; } string localmac = null; if (iswifiavailable()) { localmac = getwifimacaddress(context); } if (localmac != null && localmac.length() > 0) { localmac = localmac.replace(":", "-").tolowercase(); return localmac; } localmac = getmacfromcallcmd(); if (localmac != null) { localmac = localmac.replace(":", "-").tolowercase(); } return localmac; } private static string getwifimacaddress(context context) { string localmac = null; try { wifimanager wifi = (wifimanager) context .getsystemservice(context.wifi_service); wifiinfo info = wifi.getconnectioninfo(); if (wifi.iswifienabled()) { localmac = info.getmacaddress(); if (localmac != null) { localmac = localmac.replace(":", "-").tolowercase(); return localmac; } } } catch (exception e) { e.printstacktrace(); } return null; } /** * 通过callcmd("busybox ifconfig","hwaddr")获取mac地址 * * @attention 需要设备装有busybox工具 * @return mac address */ private static string getmacfromcallcmd() { string result = ""; result = callcmd("busybox ifconfig", "hwaddr"); if (result == null || result.length() <= 0) { return null; } debuglog.v("tag", "cmd result : " + result); // 对该行数据进行解析 // 例如:eth0 link encap:ethernet hwaddr 00:16:e8:3e:df:67 if (result.length() > 0 && result.contains("hwaddr") == true) { string mac = result.substring(result.indexof("hwaddr") + 6, result.length() - 1); if (mac.length() > 1) { result = mac.replaceall(" ", ""); } } return result; } public static string callcmd(string cmd, string filter) { string result = ""; string line = ""; try { process proc = runtime.getruntime().exec(cmd); inputstreamreader is = new inputstreamreader(proc.getinputstream()); bufferedreader br = new bufferedreader(is); // 执行命令cmd,只取结果中含有filter的这一行 while ((line = br.readline()) != null && line.contains(filter) == false) { } result = line; } catch (exception e) { e.printstacktrace(); } return result; } /** * 网络是否可用 * * @param context * @return */ public static boolean isnetworkenable(context context) { try { connectivitymanager connectivity = (connectivitymanager) context .getsystemservice(context.connectivity_service); if (connectivity == null) { toastutil.showmessage(context, "无法连接网络"); return false; } networkinfo info = connectivity.getactivenetworkinfo(); if (info != null && info.isconnected()) { // 判断当前网络是否已经连接 if (info.getstate() == networkinfo.state.connected) { return true; } } } catch (exception e) { e.printstacktrace(); } toastutil.showmessage(context, "无法连接网络"); return false; } private static final int network_type_unavailable = -1; // private static final int network_type_mobile = -100; private static final int network_type_wifi = -101; private static final int network_class_wifi = -101; private static final int network_class_unavailable = -1; /** unknown network class. */ private static final int network_class_unknown = 0; /** class of broadly defined "2g" networks. */ private static final int network_class_2_g = 1; /** class of broadly defined "3g" networks. */ private static final int network_class_3_g = 2; /** class of broadly defined "4g" networks. */ private static final int network_class_4_g = 3; private static decimalformat df = new decimalformat("#.##"); // 适配低版本手机 /** network type is unknown */ public static final int network_type_unknown = 0; /** current network is gprs */ public static final int network_type_gprs = 1; /** current network is edge */ public static final int network_type_edge = 2; /** current network is umts */ public static final int network_type_umts = 3; /** current network is cdma: either is95a or is95b */ public static final int network_type_cdma = 4; /** current network is evdo revision 0 */ public static final int network_type_evdo_0 = 5; /** current network is evdo revision a */ public static final int network_type_evdo_a = 6; /** current network is 1xrtt */ public static final int network_type_1xrtt = 7; /** current network is hsdpa */ public static final int network_type_hsdpa = 8; /** current network is hsupa */ public static final int network_type_hsupa = 9; /** current network is hspa */ public static final int network_type_hspa = 10; /** current network is iden */ public static final int network_type_iden = 11; /** current network is evdo revision b */ public static final int network_type_evdo_b = 12; /** current network is lte */ public static final int network_type_lte = 13; /** current network is ehrpd */ public static final int network_type_ehrpd = 14; /** current network is hspa+ */ public static final int network_type_hspap = 15; /** * 格式化大小 * * @param size * @return */ public static string formatsize(long size) { string unit = "b"; float len = size; if (len > 900) { len /= 1024f; unit = "kb"; } if (len > 900) { len /= 1024f; unit = "mb"; } if (len > 900) { len /= 1024f; unit = "gb"; } if (len > 900) { len /= 1024f; unit = "tb"; } return df.format(len) + unit; } public static string formatsizebysecond(long size) { string unit = "b"; float len = size; if (len > 900) { len /= 1024f; unit = "kb"; } if (len > 900) { len /= 1024f; unit = "mb"; } if (len > 900) { len /= 1024f; unit = "gb"; } if (len > 900) { len /= 1024f; unit = "tb"; } return df.format(len) + unit + "/s"; } public static string format(long size) { string unit = "b"; float len = size; if (len > 1000) { len /= 1024f; unit = "kb"; if (len > 1000) { len /= 1024f; unit = "mb"; if (len > 1000) { len /= 1024f; unit = "gb"; } } } return df.format(len) + "\n" + unit + "/s"; } /** * 获取运营商 * * @return */ public static string getprovider() { string provider = "未知"; try { telephonymanager telephonymanager = (telephonymanager) configmanager .getcontext().getsystemservice(context.telephony_service); string imsi = telephonymanager.getsubscriberid(); log.v("tag", "getprovider.imsi:" + imsi); if (imsi == null) { if (telephonymanager.sim_state_ready == telephonymanager .getsimstate()) { string operator = telephonymanager.getsimoperator(); log.v("tag", "getprovider.operator:" + operator); if (operator != null) { if (operator.equals("46000") || operator.equals("46002") || operator.equals("46007")) { provider = "中国移动"; } else if (operator.equals("46001")) { provider = "中国联通"; } else if (operator.equals("46003")) { provider = "中国电信"; } } } } else { if (imsi.startswith("46000") || imsi.startswith("46002") || imsi.startswith("46007")) { provider = "中国移动"; } else if (imsi.startswith("46001")) { provider = "中国联通"; } else if (imsi.startswith("46003")) { provider = "中国电信"; } } } catch (exception e) { e.printstacktrace(); } return provider; } /** * 获取网络类型 * * @return */ public static string getcurrentnetworktype() { int networkclass = getnetworkclass(); string type = "未知"; switch (networkclass) { case network_class_unavailable: type = "无"; break; case network_class_wifi: type = "wi-fi"; break; case network_class_2_g: type = "2g"; break; case network_class_3_g: type = "3g"; break; case network_class_4_g: type = "4g"; break; case network_class_unknown: type = "未知"; break; } return type; } private static int getnetworkclassbytype(int networktype) { switch (networktype) { case network_type_unavailable: return network_class_unavailable; case network_type_wifi: return network_class_wifi; case network_type_gprs: case network_type_edge: case network_type_cdma: case network_type_1xrtt: case network_type_iden: return network_class_2_g; case network_type_umts: case network_type_evdo_0: case network_type_evdo_a: case network_type_hsdpa: case network_type_hsupa: case network_type_hspa: case network_type_evdo_b: case network_type_ehrpd: case network_type_hspap: return network_class_3_g; case network_type_lte: return network_class_4_g; default: return network_class_unknown; } } private static int getnetworkclass() { int networktype = network_type_unknown; try { final networkinfo network = ((connectivitymanager) configmanager .getcontext() .getsystemservice(context.connectivity_service)) .getactivenetworkinfo(); if (network != null && network.isavailable() && network.isconnected()) { int type = network.gettype(); if (type == connectivitymanager.type_wifi) { networktype = network_type_wifi; } else if (type == connectivitymanager.type_mobile) { telephonymanager telephonymanager = (telephonymanager) configmanager .getcontext().getsystemservice( context.telephony_service); networktype = telephonymanager.getnetworktype(); } } else { networktype = network_type_unavailable; } } catch (exception ex) { ex.printstacktrace(); } return getnetworkclassbytype(networktype); } public static string getwifirssi() { int asu = 85; try { final networkinfo network = ((connectivitymanager) configmanager .getcontext() .getsystemservice(context.connectivity_service)) .getactivenetworkinfo(); if (network != null && network.isavailable() && network.isconnected()) { int type = network.gettype(); if (type == connectivitymanager.type_wifi) { wifimanager wifimanager = (wifimanager) configmanager .getcontext() .getsystemservice(context.wifi_service); wifiinfo wifiinfo = wifimanager.getconnectioninfo(); if (wifiinfo != null) { asu = wifiinfo.getrssi(); } } } } catch (exception e) { e.printstacktrace(); } return asu + "dbm"; } public static string getwifissid() { string ssid = ""; try { final networkinfo network = ((connectivitymanager) configmanager .getcontext() .getsystemservice(context.connectivity_service)) .getactivenetworkinfo(); if (network != null && network.isavailable() && network.isconnected()) { int type = network.gettype(); if (type == connectivitymanager.type_wifi) { wifimanager wifimanager = (wifimanager) configmanager .getcontext() .getsystemservice(context.wifi_service); wifiinfo wifiinfo = wifimanager.getconnectioninfo(); if (wifiinfo != null) { ssid = wifiinfo.getssid(); if (ssid == null) { ssid = ""; } ssid = ssid.replaceall("\"", ""); } } } } catch (exception e) { e.printstacktrace(); } return ssid; } /** * 检查sim卡状态 * * @param ctx * @return */ public static boolean checksimstate() { telephonymanager tm = (telephonymanager) configmanager.getcontext() .getsystemservice(context.telephony_service); if (tm.getsimstate() == telephonymanager.sim_state_absent || tm.getsimstate() == telephonymanager.sim_state_unknown) { return false; } return true; } /** * 获取imei */ public static string getimei() { telephonymanager mtelephonymgr = (telephonymanager) configmanager .getcontext().getsystemservice(context.telephony_service); string imei = mtelephonymgr.getdeviceid(); if (imei == null) { imei = "000000000000000"; } return imei; } public static string getphoneimsi() { telephonymanager mtelephonymgr = (telephonymanager) configmanager .getcontext().getsystemservice(context.telephony_service); return mtelephonymgr.getsubscriberid(); } public static cellinfo getnetinfo() { cellinfo info = new cellinfo(); try { telephonymanager mtelephonymanager = (telephonymanager) configmanager .getcontext().getsystemservice(context.telephony_service); string operator = mtelephonymanager.getnetworkoperator(); if (operator != null) { /** 通过operator获取 mcc 和mnc */ if (operator.length() > 3) { string mcc = operator.substring(0, 3); string mnc = operator.substring(3); info.setmcc(mcc); info.setmnc(mnc); } } int lac = 0; int cellid = 0; int phonetype = mtelephonymanager.getphonetype(); if (phonetype == telephonymanager.phone_type_gsm) { gsmcelllocation location = (gsmcelllocation) mtelephonymanager .getcelllocation(); /** 通过gsmcelllocation获取中国移动和联通 lac 和cellid */ lac = location.getlac(); cellid = location.getcid(); } else if (phonetype == telephonymanager.phone_type_cdma) { cdmacelllocation location = (cdmacelllocation) mtelephonymanager .getcelllocation(); lac = location.getnetworkid(); cellid = location.getbasestationid(); cellid /= 16; } if (lac == 0 || cellid == 0) { list<neighboringcellinfo> infos = mtelephonymanager .getneighboringcellinfo(); int lc = 0; int ci = 0; int rssi = 0; for (neighboringcellinfo cell : infos) { // 根据邻区总数进行循环 if (lc == 0 || ci == 0) { lc = cell.getlac(); ci = cell.getcid(); rssi = cell.getrssi(); } // sb.append(" lac : " + info.getlac()); // // 取出当前邻区的lac // sb.append(" cid : " + info.getcid()); // // 取出当前邻区的cid // sb.append(" bsss : " + (-113 + 2 * info.getrssi()) + // "\n"); // 获取邻区基站信号强度 } rssi = -113 + 2 * rssi; } } catch (exception e) { e.printstacktrace(); } return info; } }
希望本文所述对大家学习android软件编程有所帮助。