2017-07-05 85 views
15

根據Android開發者網站,Determining and Monitoring the Connectivity Status,我們可以檢查有一個活動的Internet連接。但是,即使只連接了Wi-Fi並且沒有可用的互聯網(它通知有互聯網連接),這也不起作用。Android互聯網連接檢查更好的方法

現在我ping一個網站,並檢查互聯網連接是否可用。而這種方法需要更多的處理時間。有沒有比這更好的方法來檢查互聯網連接,以避免ping地址的時間延遲?

+0

對不起,但它也與Wifi一起工作。許多開發人員正在使用這個但仍然沒有問題。即使我使用相同的功能,因爲多年,我沒有面臨任何與WIFI或移動數據連接互聯網連接的問題。 –

+1

是的,我也使用相同的方法,即谷歌檢查互聯網連接,是的,它需要一些時間,但我認爲它是我們目前唯一的解決方案。 –

+0

@AbdulKawee我完全同意你的看法。 –

回答

4

試試這個:

這真的很簡單,快捷:

public boolean isInternetAvailable(String address, int port, int timeoutMs) { 
    try { 
     Socket sock = new Socket(); 
     SocketAddress sockaddr = new InetSocketAddress(address, port); 

     sock.connect(sockaddr, timeoutMs); // This will block no more than timeoutMs 
     sock.close(); 

     return true; 

    } catch (IOException e) { return false; } 
} 

那麼無論你想檢查只需使用:

if (isInternetAvailable("8.8.8.8", 53, 1000)) { 
    // Internet available, do something 
} else { 
    // Internet not available 
} 
+3

您爲什麼要檢查Google DNS的可用性,而不是您想要與之互動的實際網站?此外,OP聲稱他們已經做到這一點,並正在尋找一個更好的方法。 –

+1

這是因爲這樣它會很快。有時由於交通繁忙,實際網站可能會很慢。 – sumit

+3

如果實際網站速度慢或無響應,即使連接檢查速度很快,與其交互的代碼也會很慢或無響應。 –

4

嘗試以下操作:

public boolean checkOnlineState() { 
    ConnectivityManager CManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); 
    NetworkInfo NInfo = CManager.getActiveNetworkInfo(); 
    if (NInfo != null && NInfo.isConnectedOrConnecting()) { 
     return true; 
    } 
    return false; 
} 

不要原諒等訪問:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

否則:

if (InetAddress.getByName("www.google.com").isReachable(timeout)) 
{ } 
else 
{ } 
1

也許這可以幫助你:

private boolean checkInternetConnection() { 
     ConnectivityManager cm = (ConnectivityManager) 
getSystemService(Context.CONNECTIVITY_SERVICE); 
     // Test for connection 
     if (cm.getActiveNetworkInfo() != null 
      && cm.getActiveNetworkInfo().isAvailable() 
      && cm.getActiveNetworkInfo().isConnected()) { 
     return true; 
    } 
    else { 
     return false; 
    } 
} 
+2

這隻會講,有一個工作活動連接(WIFI /移動數據),而不是是否該連接實際提供互聯網接入。它可以連接到路由器沒有ISP連接,沒有數據信用移動數據,酒店的WiFi,沒有有效證件,限制學校/辦公局域網等 – Martheen

+0

那麼你應該做一個HTTP請求或者使用抽射或任何其他方式處理基於響應的響應檢查網絡是否可用。 –

1

試試這個方法,這將幫助你:

public static boolean isNetworkConnected(Context context) 
{ 
    ConnectivityManager connectivityManager = (ConnectivityManager) 
      context.getSystemService(Context.CONNECTIVITY_SERVICE); 
    if (connectivityManager != null) 
    { 
     NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo(); 
     if (netInfo != null && netInfo.isConnected()) 
     { 
      return true; 
     } 
    } 
    return false; 
} 
+10

你沒有明白他的觀點,當WI-FI與互聯網連接無關時,即使在有限的連接上,這種方法也會返回'true'。仔細閱讀問題 –

2

你可以嘗試一下本作檢查Internet連接:

/** 
* Check Connectivity of network. 
*/ 
public static boolean isOnline(Context context) { 
    try { 
     if (context == null) 
      return false; 

     ConnectivityManager cm = (ConnectivityManager) context 
       .getSystemService(Context.CONNECTIVITY_SERVICE); 

     if (cm != null) { 
      if (cm.getActiveNetworkInfo() != null) { 
       return cm.getActiveNetworkInfo().isConnected(); 
      } else { 
       return false; 
      } 
     } else { 
      return false; 
     } 
    } 
    catch (Exception e) { 
     Log.error("Exception", e); 
     return false; 
    } 
} 

在你的活動,你這樣調用這個函數。

if(YourClass.isOnline(context)) 
{ 
    // Do your stuff here. 
} 
else 
{ 
    // Show alert, no Internet connection. 
} 

不要忘了添加ACCESS_NETWORK_STATE權限:

public static boolean isPingAvailable(String myUrl) { 
    boolean isAvailable = false; 
    try { 
     URL url = new URL(myUrl); 
     HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); 
     // 30 second time out. 
     httpURLConnection.setConnectTimeout(30000); 
     httpURLConnection.connect(); 
     if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { 
      isAvailable = true; 
     } 
    } catch (Exception e) { 
     isAvailable = false; 
     e.printStackTrace(); 
    } 
    return isAvailable; 
} 
+1

不,它將無法正常工作,我們需要ping任何網站以確認互聯網的可用性 –

+1

在這種情況下,您必須使用InetAddress。看看[這裏](https://developer.android.com/reference/java/net/InetAddress.html#isReachable(int))。 –

+0

@RohithKrishnan看到我更新的答案。 –

1

ConnectivityManager將無法彷彿在告訴你:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

,如果你只想ping通網址試試這個你在WIFI上有活動連接。

檢查我們是否具有活動Internet連接的唯一選項是ping URL。但是,您不需要通過從應用程序製作的每個HTTP請求來執行此操作。

你可以做什麼:下面的代碼

  1. 用於檢查連接

    private boolean checkInternetConnection() 
    { 
        ConnectivityManager cm = (ConnectivityManager) 
        getSystemService(Context.CONNECTIVITY_SERVICE); 
        // test for connection 
        if (cm.getActiveNetworkInfo() != null 
         && cm.getActiveNetworkInfo().isAvailable() 
         && cm.getActiveNetworkInfo().isConnected()) 
        { 
         return true; 
        } 
        else 
        { 
         return false; 
        } 
    } 
    
  2. ,同時使用HTTP客戶端設置超時時間如10秒內做出REST調用。如果你在10秒內沒有得到答覆意味着你不能有活躍的互聯網連接,並且會拋出異常(大多數情況下你會在10秒內得到答覆)。不需要檢查通過ping每次活動連接(如果你不進行聊天或者VOIP應用)

3

你應該清楚是你是什麼意思whether internet is available的第一個問題?

  • 未連接到wifi或蜂窩網絡;
  • 連接到有限的wifi:例如在學校網絡中,如果您連接到學校的無線網絡,則可以直接訪問內部網。但是您必須使用學校帳戶登錄才能訪問外部網。在這種情況下,如果您ping外網網站,您可能會收到響應,因爲某些內網會將自動重定向到登錄頁面;
  • 連接到無限的無線網絡:您可以免費訪問大多數網站;

第二個問題是你想達到什麼樣的?

據我瞭解你的描述,你似乎想要測試網絡的連接,並提醒用戶,如果它失敗。所以我建議你只需要ping你的服務器,如果你想與它交換數據,這總是很好。


你想知道是否有更好的方法來測試連接,答案是否定的。

當前的TCP/IP網絡虛電路,分組交換網絡,這意味着沒有一個固定的「路徑」的數據來運行,即,不是像電話,我們有兩個之間的實際連接用戶,我們可以知道電路斷開後連接立即丟失。我們必須將數據包發送到目的地,並且沒有找到任何響應,然後我們知道,我們失去了連接(這是ping-ICMP協議所做的)。

總之,我們沒有更好的辦法來測試連接比平以外的主機它,這就是爲什麼心跳服務管理使用。

+0

@託尼,我想描述就足以明白,我現在面臨 –

+0

據我理解你的更新版本的問題,你想測試連接到特定的網站,所以有沒有更好的辦法,如果你想交換數據用它。 – Tony

+0

是的,我發現,並檢查Android的WiFi設置的谷歌代碼。 –

2

在檢查這個問題才發現,我們無法確定活動的互聯網連接是否存在,通過使用在開發者網站規定的方法: https://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html

這隻會檢查無線網絡連接的whther療法有效連接。

所以我發現2種方法,將檢查是否有一個有效的互聯網連接

1.Ping使用以下方法的網站

URL url = new URL(myUrl); 
     HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection(); 
     // 30 second time out. 
     httpURLConnection.setConnectTimeout(30000); 
     httpURLConnection.connect(); 
     if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { 
      isAvailable = true; 
     } 

2.檢查谷歌DNS的使用插座

可用性
try { 
     Socket sock = new Socket(); 
     SocketAddress sockaddr = new InetSocketAddress("8.8.8.8", 53); 

     sock.connect(sockaddr, 1000); // this will block no more than timeoutMs 
     sock.close(); 

     return true; 
} 

第二種方法比第二種方法稍快(適合我的要求)

感謝所有的答案和支持。