12.查詢網(wǎng)絡連接狀態(tài)

12.1 問題

應用程序需要監(jiān)控網(wǎng)絡連接狀態(tài)的變化。

12.2 解決方案

(API Level 1)
通過ConnectivityManager監(jiān)控設備的網(wǎng)絡連接設備简珠。在移動應用程序的設計過程中梦湘,需要考慮的一個很重要的問題就是網(wǎng)絡并不是隨時都是連通的板乙。隨著人的移動,網(wǎng)絡的速度和容量都在不斷地變化。正因為如此蒋伦,使用網(wǎng)絡資源的應用程序需要隨時監(jiān)控這些資源是否可訪問,并不能訪問時通知用戶访敌。
除了連通性凉敲,ConnectivityManager還能向應用程序提供網(wǎng)絡連接的類型。這樣就能根據(jù)情況決定是否要下載大文件寺旺,如果用戶處于漫游狀態(tài)的話爷抓,下載大文件會使數(shù)據(jù)流量暴增。

12.3 實現(xiàn)機制

以下代碼清單封裝了一個方法阻塑,可以把它放到你的代碼中來檢查網(wǎng)絡的連通性蓝撇。

ConnectivityManager 封裝方法

    public boolean isNetworkReachable() {

      final ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 
        NetworkInfo current = mManager.getActiveNetworkInfo();
        if(current == null) {
            return false;
        }
        return (current.getState() == NetworkInfo.State.CONNECTED);
    }

ConnectivityManager所做的工作是評估哪個網(wǎng)絡數(shù)據(jù)接口被認為是活躍的(Wi-Fi或蜂窩網(wǎng)絡)。在最簡單的情況下陈莽,我們僅檢查給定接口是否已連接渤昌。注意:如果沒有可用的活躍數(shù)據(jù)連接,ConnectivityManager.getActiveNetworkInfo()會返回null走搁,所以首先要檢查這種情況独柑。如果有可用的網(wǎng)絡,就可以檢查其狀態(tài)私植,可能的返回值如下:

  • DISCONNECTED
  • CONNTECTING
  • CONNECTED
  • DISCONNECTING

如果返回的狀態(tài)是CONNECTED忌栅,網(wǎng)絡就是穩(wěn)定的,可以用來訪問遠程資源曲稼。

1. 驗證路線

移動設備有多條連接路線(Wi-Fi索绪、3G/4G等),并且設備經(jīng)常連接到?jīng)]有外部Web路線的網(wǎng)絡贫悄;Wi-Fi網(wǎng)絡尤其如此瑞驱。ConnectivityManager僅僅通知用戶其設備是否已關(guān)聯(lián)特定的網(wǎng)絡,但不會表明該網(wǎng)絡是否能夠訪問外部IP地址窄坦。因此唤反,當設備嘗試通過已“連接”但沒有有效路線的網(wǎng)絡進行連接時,網(wǎng)絡棧就會花費幾分鐘的時間超時并適當失敗鸭津。
在某些情況下彤侍,更加智能的方法是檢查有效的Internet連接,而非僅檢查與網(wǎng)絡的關(guān)聯(lián)曙博。以下代碼清單以前面的連通性檢查為基礎拥刻,用于檢查Internet連接怜瞒。

更加智能的ConnectivityManager封裝方法

    public static boolean isNetworkReachable(Context context){
        final ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        final NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        
        //如果沒有與網(wǎng)絡關(guān)聯(lián)父泳,則在此處進行關(guān)聯(lián)
        boolean connected = (null != activeNetworkInfo && activeNetworkInfo.isConnected()){
            if (!connected) return false;
            
            //檢查是否可以訪問遠程服務器
            boolean routeExists;
            try{
                //檢查Google公共DNS
                InetAddress host = InetAddress.getByName("8.8.8.8");

                Socket s = new Socket();
                s.connect(new InetSocketAddress(host,53),5000);
                //如果沒有拋出異常般哼,則DNS存在
                routeExists = true;
                s.close();
            }catch (IOException e){
                routeExists = false;
            }
            return (connected && routeExists);
        }

如往常一樣驗證相同的連通性條件之后,上面的代碼清單進一步嘗試打開套接字(具有5秒的超時)惠窄,該套接字指向Google公共DNS的眾所周知的標準IPv4標準(8.8.8.8)蒸眠。如果成功連接此主機,我們就能夠確信設備可以訪問任何激活的Internet資源杆融。相比于直接全面連接遠程服務器楞卡,此方法的優(yōu)勢是代碼將更快地失敗,強制最多5秒的延遲脾歇,然后就立刻告訴用戶蒋腮,我們實際上并沒有自認為已具備的Internet連接。
當網(wǎng)絡請求失敗時藕各,最好檢查網(wǎng)絡的連通性池摧,告知用戶請求失敗是網(wǎng)絡問題。以下代碼清單中的示例演示了如何在網(wǎng)絡訪問失敗時檢查網(wǎng)絡的連通性激况。

告知用戶網(wǎng)絡不通

    try{
  //嘗試訪問網(wǎng)絡資源時作彤,如果失敗,可能會拋出HttpResponseException或其他  IOException

    }catch(Exception e){
    if( !isNetworkReachable() ){
          AlertDialog.Builder builder = new AlertDialog.Builder builder(context);
          builder.setTitle("No Network Connection");
          builder.setMessage( " The Network is unavailable. " 
                            + " Please try your request again later.  " );
          builder.setPositiveButton("OK"乌逐,null);
          builder.create().show();
       }
}

2. 判斷連接類型

在某些情況下竭讳,應用程序還必須知道用戶所連接的網(wǎng)絡是否是按流量收費的,可以調(diào)用活動網(wǎng)絡連接的NetworkInfo.getType()方法以獲取相關(guān)信息(參見以下代碼)浙踢。

ConnectivityManager帶寬檢查

    public boolean  isWifiReachable(){
        ConnectivityManager mManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo current = mManager.getActiveNetworkInfo();
        if (current == null){
            return false;
        }
        return (current.getType() == ConnectivityManager.TYPE_WIFI);
    }

這個修改后的連通性檢查版本能夠判斷用戶是否連接到了Wi-Fi網(wǎng)絡绢慢,如果連接的是Wi-Fi網(wǎng)絡,通常就意味著網(wǎng)速比較快成黄,而且流量是免費的呐芥。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市奋岁,隨后出現(xiàn)的幾起案子思瘟,更是在濱河造成了極大的恐慌,老刑警劉巖闻伶,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滨攻,死亡現(xiàn)場離奇詭異,居然都是意外死亡蓝翰,警方通過查閱死者的電腦和手機光绕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畜份,“玉大人诞帐,你說我怎么就攤上這事”ⅲ” “怎么了停蕉?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵愕鼓,是天一觀的道長。 經(jīng)常有香客問我慧起,道長菇晃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任蚓挤,我火速辦了婚禮磺送,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘灿意。我一直安慰自己估灿,他們只是感情好,可當我...
    茶點故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布缤剧。 她就那樣靜靜地躺著甲捏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鞭执。 梳的紋絲不亂的頭發(fā)上司顿,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機與錄音兄纺,去河邊找鬼大溜。 笑死,一個胖子當著我的面吹牛估脆,可吹牛的內(nèi)容都是我干的钦奋。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼疙赠,長吁一口氣:“原來是場噩夢啊……” “哼付材!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起圃阳,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤厌衔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后捍岳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體富寿,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年锣夹,在試婚紗的時候發(fā)現(xiàn)自己被綠了页徐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡银萍,死狀恐怖变勇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贴唇,我是刑警寧澤搀绣,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布赃梧,位于F島的核電站,受9級特大地震影響豌熄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜物咳,卻給世界環(huán)境...
    茶點故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一锣险、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧览闰,春花似錦芯肤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至油吭,卻和暖如春击蹲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背婉宰。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工歌豺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人心包。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓类咧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蟹腾。 傳聞我的和親對象是個殘疾皇子痕惋,可洞房花燭夜當晚...
    茶點故事閱讀 45,851評論 2 361