Android判斷用戶2G/3G/4G移動數(shù)據(jù)網(wǎng)絡(luò)
在做 Android App 的時候,為了給用戶省流量,為了不激起用戶的憤怒,為了更好的用戶體驗,是需要根據(jù)用戶當(dāng)前網(wǎng)絡(luò)情況來做一些調(diào)整的,也可以在 App 的設(shè)置模塊里,讓用戶自己選擇,在 2G / 3G / 4G 網(wǎng)絡(luò)條件下,是否允許請求一些流量比較大的數(shù)據(jù)。
通過 Android 提供的 TelephonyManager 和 ConnectivityManager 都可以獲取到 NetworksInfo 對象,可以通過 getType() 獲取類型,判斷是 wifi 還是 mobile ,如果是 mobile ,可以通過 NetworksInfo 對象的 getSubType() 和 getSubTypeName() 可以獲取到對于的網(wǎng)絡(luò)類型和名字。
網(wǎng)絡(luò)類型和名字定義在 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;
看到這個代碼和注釋,相信沒有這方面知識的人很難看懂,都啥玩意?這注釋跟沒注釋有啥區(qū)別?!就是讓人看著更加鬧心而已。所以說,注釋對閱讀代碼的人很重 要。當(dāng)然這些東西可能太專業(yè)了,寫這些代碼的人估計是想寫也不知道該怎么了,得寫多大一坨啊?!我在最后會貼上一些我整理的資料,可以供大家參考一下,不 是很詳細,也不專業(yè),就是大概有個印象。
TelephonyManager 還提供了 getNetworkTypeName(int type) 的方法,這個方法可以返回一個字符串,但是信息量不大。
那怎么判斷是 2G , 3G 還是 4G 網(wǎng)絡(luò)呢?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;
不知道為啥要把這些東西給隱藏起來,不靠譜?還是其他的更好的方式?!不知道,先這樣吧,現(xiàn)在通過上面的手段,是可以知道用戶用的是什么網(wǎng)絡(luò),當(dāng) 然也可以區(qū)分出來用戶使用的是 2G , 3G 還是 4G 了。當(dāng)然,你獲取到這些數(shù)據(jù)后,你也可以推算出用戶用的是哪家公司的網(wǎng)絡(luò),移動的,聯(lián)通的,還是電信的,當(dāng)然,只在中國。而且虛擬運營商開始真正上市后, 這個就區(qū)分不出來是京東的,還是國美,蘇寧的了,但是你可以知道你的手機號用的是聯(lián)通的網(wǎng)還是移動的網(wǎng)。
最后貼上我收集整理的一些資料,可以參考一下。
- GPRS 2G(2.5) General Packet Radia Service 114kbps
- EDGE 2G(2.75G) Enhanced Data Rate for GSM Evolution 384kbps
- UMTS 3G WCDMA 聯(lián)通3G Universal Mobile Telecommunication System 完整的3G移動通信技術(shù)標準
- 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 - 無線電傳輸技術(shù)) 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 集成數(shù)字增強型網(wǎng)絡(luò) (屬于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的中間產(chǎn)物 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 需要設(shè)備裝有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); // 對該行數(shù)據(jù)進行解析 // 例如: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); // 執(zhí)行命令cmd,只取結(jié)果中含有filter的這一行 while ((line = br.readLine()) != null && line.contains(filter) == false) { } result = line; } catch (Exception e) { e.printStackTrace(); } return result; } /** * 網(wǎng)絡(luò)是否可用 * * @param context * @return */ public static boolean IsNetWorkEnable(Context context) { try { ConnectivityManager connectivity = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity == null) { ToastUtil.showMessage(context, "無法連接網(wǎng)絡(luò)"); return false; } NetworkInfo info = connectivity.getActiveNetworkInfo(); if (info != null && info.isConnected()) { // 判斷當(dāng)前網(wǎng)絡(luò)是否已經(jīng)連接 if (info.getState() == NetworkInfo.State.CONNECTED) { return true; } } } catch (Exception e) { e.printStackTrace(); } ToastUtil.showMessage(context, "無法連接網(wǎng)絡(luò)"); 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 = "中國聯(lián)通"; } else if (operator.equals("46003")) { provider = "中國電信"; } } } } else { if (IMSI.startsWith("46000") || IMSI.startsWith("46002") || IMSI.startsWith("46007")) { provider = "中國移動"; } else if (IMSI.startsWith("46001")) { provider = "中國聯(lián)通"; } else if (IMSI.startsWith("46003")) { provider = "中國電信"; } } } catch (Exception e) { e.printStackTrace(); } return provider; } /** * 獲取網(wǎng)絡(luò)類型 * * @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卡狀態(tài) * * @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獲取中國移動和聯(lián)通 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) { // 根據(jù)鄰區(qū)總數(shù)進行循環(huán) if (lc == 0 || ci == 0) { lc = cell.getLac(); ci = cell.getCid(); rssi = cell.getRssi(); } // sb.append(" LAC : " + info.getLac()); // // 取出當(dāng)前鄰區(qū)的LAC // sb.append(" CID : " + info.getCid()); // // 取出當(dāng)前鄰區(qū)的CID // sb.append(" BSSS : " + (-113 + 2 * info.getRssi()) + // "\n"); // 獲取鄰區(qū)基站信號強度 } rssi = -113 + 2 * rssi; } } catch (Exception e) { e.printStackTrace(); } return info; } }
希望本文所述對大家學(xué)習(xí)Android軟件編程有所幫助。
- Android獲取當(dāng)前手機網(wǎng)絡(luò)類型(2g、3g、4g、wifi)以及手機型號、版本號代碼
- Android判斷網(wǎng)絡(luò)類型的方法(2g,3g還是wifi)
- Android中判斷有無可用網(wǎng)絡(luò)的代碼(是否是3G或者WIFI網(wǎng)絡(luò))
- Android判斷是Wifi還是4G網(wǎng)絡(luò)代碼
- Android判斷用戶的網(wǎng)絡(luò)類型實例講解(2/3/4G、wifi)
- Android中判斷網(wǎng)絡(luò)連接是否可用及監(jiān)控網(wǎng)絡(luò)狀態(tài)
- android 檢查網(wǎng)絡(luò)連接狀態(tài)實現(xiàn)步驟
- Android中監(jiān)聽判斷網(wǎng)絡(luò)連接狀態(tài)的方法
- Android中監(jiān)聽系統(tǒng)網(wǎng)絡(luò)連接打開或者關(guān)閉的實現(xiàn)代碼
- android檢測網(wǎng)絡(luò)連接狀態(tài)示例講解
- android網(wǎng)絡(luò)編程之a(chǎn)ndroid連接網(wǎng)絡(luò)的簡單示例代碼
- Android中判斷網(wǎng)絡(luò)連接狀態(tài)的方法
- Android編程判斷是否連接網(wǎng)絡(luò)的方法【W(wǎng)iFi及3G判斷】
相關(guān)文章
Android切換至SurfaceView時閃屏(黑屏閃一下)以及黑屏移動問題的解決方法
本文主要介紹了Android切換至SurfaceView時閃屏(黑屏閃一下)以及黑屏移動問題的解決方法。具有一定的參考作用,下面跟著小編一起來看下吧2017-01-01Android 圖片切換器(dp、sp、px) 的單位轉(zhuǎn)換器
這篇文章主要介紹了Android 圖片切換器(dp、sp、px) 的單位轉(zhuǎn)換器的相關(guān)資料,需要的朋友可以參考下2017-03-03Android之RecyclerView輕松實現(xiàn)下拉刷新和加載更多示例
本篇文章主要介紹了Android之RecyclerView輕松實現(xiàn)下拉刷新和加載更多示例,非常具有實用價值,需要的朋友可以參考下。2017-02-02