Android之判断网络状态(网络的连接,改变,和判断2G/3G/4G)
? ? 現在app大多都需要從網絡上獲得數據。所以訪問網絡是在所難免。但是再訪問網絡之前,我們應該先做一下網絡的狀態判斷。其實在訪問網絡之前我們要做一些狀態判斷,對應一些狀態判斷來做處理,并不是直接使用Http訪問網絡即可。很多人在開發就經常把網絡這塊直接跳過,直接訪問網絡,可以一斷網,各種體驗效果不好,不是說app沒法用,只是體驗效果差。還有,就是我們可能為用戶考慮,因為現在一般連網是wifi和手機流量,都知道后者收費是比較高的。假如我們的app加載的圖片或者有大的數據下載操作,可是用戶的本意是要是在流量下的話就不要操作這些很費流量的的操作,這樣就必須要我們做一些連網狀態的判斷。網絡是否連接良好,連接的wifi還是流量,斷網或者網絡改變了的時候怎么做,這都是一些細節,但是要注意處理。
我們在做訪問的時候都得進行判斷是否連網。判斷連網也比較簡單,就用到了這幾個類。ConnectivityManager、TelephonyManager?和NetworkInfo。
只要執行下面的代碼就可以了。
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);boolean isWifiConn = networkInfo.isConnected();networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);boolean isMobileConn = networkInfo.isConnected();
只要有一個連接就是有網,NetworkInfo就是網絡的信息。還有一種更簡便的判斷是否連網的方法。
ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
在一個就是監聽網絡變化,就是設置一個廣播。
注冊廣播,監聽ConnectivityManager.CONNECTIVITY_ACTION這個action
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);receiver = new NetworkReceiver();context.registerReceiver(receiver, filter); 再實現一個廣播類就可以了。這樣網絡一變化,就會受到廣播,然后執行對應操作了。@Overridepublic void onReceive(Context context, Intent intent) {Log.i("TAG", "intent============>>>>" + intent.toString());}}
下面就是來說一下判斷手機網絡的類型了,2G,3G,4G
關于網絡類型,在得到networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);這個后,確定是手機網絡后,通過networkInfo.getSubtype()會得到網絡的類型,用networkInfo.getSubtypeName()會得到網絡的名字。
我們通過這個networkInfo.getSubtype()得到的類型來判斷當前是什么網絡。
其實,Android的Api中已經定義了各種網絡狀態,不是在ConnectivityManager里面定義的,而是在TelephonyManager里面的定義的。通過不同的api版本的修改,目前增加到了14個狀態值:
下面是通過自己查資料,和看別人查資料實驗得來的。整理如下:
--------------------Added in API level 1--------------------- public static final int NETWORK_TYPE_UNKNOWN Network type is unknown Constant Value: 0 (0x00000000) (不知道網絡類型)public static final int NETWORK_TYPE_GPRS Current network is GPRS Constant Value: 1 (0x00000001) (2.5G)移動和聯通public static final int NETWORK_TYPE_EDGE Current network is EDGE Constant Value: 2 (0x00000002) (2.75G)2.5G到3G的過渡 移動和聯通public static final int NETWORK_TYPE_UMTS Current network is UMTS Constant Value: 3 (0x00000003) (3G)聯通-----------------Added in API level 4--------------------- public static final int NETWORK_TYPE_CDMA Current network is CDMA: Either IS95A or IS95B Constant Value: 4 (0x00000004) (2G 電信)public static final int NETWORK_TYPE_EVDO_0 Current network is EVDO revision 0 Constant Value: 5 (0x00000005) ( 3G )電信public static final int NETWORK_TYPE_EVDO_A Current network is EVDO revision A Constant Value: 6 (0x00000006) (3.5G) 屬于3G過渡public static final int NETWORK_TYPE_1xRTT Current network is 1xRTT Constant Value: 7 (0x00000007) ( 2G )---------------------Added in API level 5-------------------- public static final int NETWORK_TYPE_HSDPA Current network is HSDPA Constant Value: 8 (0x00000008) (3.5G )public static final int NETWORK_TYPE_HSUPA Current network is HSUPA Constant Value: 9 (0x00000009) ( 3.5G )public static final int NETWORK_TYPE_HSPA Current network is HSPA Constant Value: 10 (0x0000000a) ( 3G )聯通--------------------------Added in API level 8------------------------- public static final int NETWORK_TYPE_IDEN Current network is iDen Constant Value: 11 (0x0000000b) (2G )--------------------------Added in API level 9------------------------- public static final int NETWORK_TYPE_EVDO_B Current network is EVDO revision B Constant Value: 12 (0x0000000c) 3G-3.5G--------------------------Added in API level 11------------------------ public static final int NETWORK_TYPE_LTE Current network is LTE Constant Value: 13 (0x0000000d) (4G)public static final int NETWORK_TYPE_EHRPD Current network is eHRPD Constant Value: 14 (0x0000000e) 3G(3G到4G的升級產物)--------------------------Added in API level 13--------------------------- public static final int NETWORK_TYPE_HSPAP Current network is HSPA+ Constant Value: 15 (0x0000000f) ( 3G )所以我們可以networkInfo.getSubtype()得到值和上面的進行對應,就知道目前是幾G網絡了。由于手里的手機卡有限,所以有些不全,歡迎大家補充,共享。
網絡類型和名字定義在 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 快些
總結
以上是生活随笔為你收集整理的Android之判断网络状态(网络的连接,改变,和判断2G/3G/4G)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android之开源框架NineOldA
- 下一篇: Android之android.grap