Android | 判斷連接的網(wǎng)絡是否可用以及是否連接網(wǎng)絡

一、查看當前手機的網(wǎng)絡狀態(tài),需要獲取ConnectionManager

    1. ConnectionManager方式
 /**
     * 判斷當前是否有網(wǎng)絡連接,但是如果該連接的網(wǎng)絡無法上網(wǎng),也會返回true
     * @param mContext
     * @return
     */
    public static boolean isNetConnection(Context mContext) {
        if (mContext!=null){
            ConnectivityManager connectivityManager = 
                          (ConnectivityManager) mContext.
                          getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
            boolean connected = networkInfo.isConnected();
            if (networkInfo!=null&&connected){
                if (networkInfo.getState()== NetworkInfo.State.CONNECTED){
                    return true;
                }else{
                    return false;
                }
            }
        }
        return false;
    }

    1. NetworkCapabilities類方式(6.0以上)

NetworkCapabilities是API 21新增加的一個工具類,這類本身沒有太多內容,主要是用來描述網(wǎng)絡狀態(tài)和傳輸類型,具體的內容請查閱相關文檔,這里就不多介紹了。NetworkCapabilities提供了方法,用來判斷當前網(wǎng)絡是否可用,而且是不耗時的方法。


  /**
     * 判斷當前網(wǎng)絡是否可用(6.0以上版本)
     * 實時
     * @param context
     * @return
     */
    public static boolean isNetSystemUsable(Context context) {
        boolean isNetUsable = false;
        ConnectivityManager manager = (ConnectivityManager)
                context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            NetworkCapabilities networkCapabilities =
                    manager.getNetworkCapabilities(manager.getActiveNetwork());
            if (networkCapabilities != null) {
                isNetUsable = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
            }
        }
        return isNetUsable;
    }




二、有網(wǎng)絡連接情況下,檢測網(wǎng)絡能否正常上網(wǎng)

注意:此方法需要在子線程調用,否則報錯:android.os.NetworkOnMainThreadException



 /**
     * 功能:檢測當前URL是否可連接或是否有效,
     * 描述:最多連接網(wǎng)絡 x次, 如果 x 次都不成功,視為該地址不可用
     * @return true是可以上網(wǎng),false是不能上網(wǎng)
     */
    private static URL url;
    private static HttpURLConnection con;
    private static int state = -1;
    public static boolean isNetOnline() {
        // Android 4.0 之后不能在主線程中請求HTTP請求
        int counts = 0;
        boolean isNetsOnline = true;
        while (counts < 2) {
            try {
                url = new URL("https://www.baidu.com");
                con = (HttpURLConnection) url.openConnection();
                state = con.getResponseCode();
                Log.e("FragmentNet", "isNetOnline counts: " + counts + "=state: " + state);
                if (state == 200) {
                    isNetsOnline = true;
                }
                break;
            } catch (Exception ex) {
                isNetsOnline = false;
                counts++;
                Log.e("FragmentNet", "isNetOnline URL不可用,連接第 " + counts + " 次");
                continue;
            }
        }
        return isNetsOnline;

    }


三、ping 網(wǎng)絡方式

注意: ping網(wǎng)址是最最常用的一種判斷網(wǎng)絡的方式,也是通用方法。這種方法最大的劣勢是,耗時很長,我曾計算過,ping一次的時間大約是10s,兩次是11s,每增加一次就多耗時1s。雖然這種方法耗時較長,但這是目前最常用的方法,而且沒有更好的方法取代。

有時候我們連接上一個沒有外網(wǎng)連接的WiFi或者有線就會出現(xiàn)這種極端的情況,
目前Android SDK還不能識別這種情況,一般的解決辦法就是ping一個外網(wǎng)

    /**
     * @category 判斷是否有外網(wǎng)連接(普通方法不能判斷外網(wǎng)的網(wǎng)絡是否連接,比如連接上局域網(wǎng))
     * @return
     */
    public static final boolean ping() {

        String result = null;
        try {
            String ip = "www.baidu.com";// ping 的地址,可以換成任何一種可靠的外網(wǎng)
            Process p = Runtime.getRuntime().exec("ping -c 3 -w 100 " + ip);// ping網(wǎng)址3次
            // 讀取ping的內容,可以不加
            InputStream input = p.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(input));
            StringBuffer stringBuffer = new StringBuffer();
            String content = "";
            while ((content = in.readLine()) != null) {
                stringBuffer.append(content);
            }

//            Log.d("------ping-----", "result content : " + stringBuffer.toString());
            // ping的狀態(tài)
            int status = p.waitFor();
            if (status == 0) {
                result = "success";
                return true;
            } else {
                result = "failed";
            }
        } catch (IOException e) {
            result = "IOException";
        } catch (InterruptedException e) {
            result = "InterruptedException";
        } finally {
//            Log.d("----result---", "result = " + result);
        }
        return false;
    }
  • 雖然現(xiàn)在主流手機系統(tǒng)都是6.0以上,但是總有一些“老爺機”還堅挺的使用5.0甚至是4.4以上的系統(tǒng)。為了適配問題,方法1依然是主流的方法,這也是Android開發(fā)最麻煩的地方。

  • 另外,ping的方法可以判斷當前網(wǎng)絡的可用情況。

     process.waitFor() 返回0,當前網(wǎng)絡可用
     process.waitFor() 返回1,需要網(wǎng)頁認證的wifi
     process.waitFor() 返回2,當前網(wǎng)絡不可用

-關于需要網(wǎng)頁認證的wifi:

警惕360wifi?。。?/code>


360wifi本身其實是不需要認證的,連接上網(wǎng)絡之后就可以直接使用。但是用方法進行判斷時,
process.waitFor()返回的卻是1。有一些手機系統(tǒng)(比如魅族),在監(jiān)測到當前wifi需要網(wǎng)頁認證時,
會自動打開瀏覽器。這本身是一個很人性化的設計,然而會被某些企業(yè)利用,在連接上wifi之后,
自動跳轉到廣告頁面。

所以大家如果用360wifi進行驗證,自求多福,那畢竟是360啊。


四、解決android.os.NetworkOnMainThreadException

1.在Android 4.0以上,網(wǎng)絡連接不能放在主線程上,不然就會報錯android.os.NetworkOnMainThreadException。但是4.0下版本可以不會報錯。

2.在Android4.0以后,會發(fā)現(xiàn),只要是寫在主線程(就是Activity)中的HTTP請求,運行時都會報錯,這是因為Android在4.0以后為了防止應用的ANR(Aplication Not Response)異常,Android這個設計是為了防止網(wǎng)絡請求時間過長而導致界面假死的情況發(fā)生。

image.png

解決此問題有兩種解決的方法:

1.可以再Activity的onCreate()方法中加入這樣一段代碼,適用于網(wǎng)絡請求數(shù)據(jù)量很小的話,如下

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

2.啟動一條子線程進行你的網(wǎng)絡請求,推薦使用這種

// Android 4.0 之后不能在主線程中請求HTTP請求
new Thread(new Runnable(){
         @Override
         public void run() {
               cachedImage = asyncImageLoader.loadDrawable(imageUrl, position);
               imageView.setImageDrawable(cachedImage);
         }
 }).start();
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容