2

有人可以提供更好更快的方式來檢查Google是否可用於Android? 我觀察到connectiontimeout在給定的time_out中不會停止。而它需要超過一分鐘..Android:如何檢查Google是否可用?

public static boolean isConnected(Context context){ 
      NetworkInfo info = Connectivity.getNetworkInfo(context); 
      return (info != null && info.isConnected()); 
     } 
     public boolean checkInternetConnectivity() { 

       try { 
        HttpURLConnection urlc = (HttpURLConnection) (new URL(
          "http://www.google.com").openConnection()); 
        urlc.setRequestProperty("User-Agent", "Test"); 
        urlc.setRequestProperty("Connection", "close"); 
        urlc.setConnectTimeout(2000); 
        urlc.setReadTimeout(3000); 
        urlc.connect(); 
        isInterNetAvailable = true; 
        return (urlc.getResponseCode() == 200); 
       } catch (IOException e) { 
        isInterNetAvailable = false; 
        return (false); 
       } 
      } 
public String getNWConnectivityText() {  


     if (Connectivity.isConnected(getSherlockActivity()) == true) { 

      if (checkInternetConnectivity() == true) { 
//   if (true == Connectivity.isConnectingToInternet(getSherlockActivity())) { 
//    if (true == Connectivity.isDataAvailable(getSherlockActivity())) {    

       return "google is available"; 
      } else { 
       return "google is not available"; 
      } 

     } else { 
      return "no connectivity" + "\t"; 
     } 
    } 
+0

你在哪裏建立http連接。 – Raghunandan

+0

你可以輪詢一個連接的變化,簡單的廣播接收器。 – Skynet

+0

我很好奇這個檢查的目的。請注意,如果看到網絡已啓動,則可以嘗試連接,但立即發現它斷開。 – seand

回答

4

除了@ astral-projection的解決方案,您可以簡單地聲明一個Socket。我在我的許多項目中使用了以下代碼,並且超時確實可行。

Socket socket; 
final String host = "www.google.com"; 
final int port = 80; 
final int timeout = 30000; // 30 seconds 

try { 
    socket = new Socket(); 
    socket.connect(new InetSocketAddress(host, port), timeout); 
} 
catch (UnknownHostException uhe) { 
    Log.e("GoogleSock", "I couldn't resolve the host you've provided!"); 
} 
catch (SocketTimeoutException ste) { 
    Log.e("GoogleSock", "After a reasonable amount of time, I'm not able to connect, Google is probably down!"); 
} 
catch (IOException ioe) { 
    Log.e("GoogleSock", "Hmmm... Sudden disconnection, probably you should start again!"); 
} 

雖然這可能會很棘手。正是在UnknownHostException s時,可能需要更長的時間超時,約45秒 - 但在另一邊,這通常發生在無法解析主機,這樣就會morelike意味着你的網絡連接已經missconfigured DNS解析(這是不太可能)。

無論如何,如果你想要對衝你的賭注,你可以通過兩種方式解決這個問題:

  • 不要使用一臺主機,使用IP地址來代替。您可能會在主機上多次使用ping多個Google的IP。例如:

    [email protected] ~/services $ ping www.google.com 
    PING www.google.com (173.194.40.179) 56(84) bytes of data. 
    
  • 另一個解決方法將啓動一個線程WatchDog並完成所需要的時間後,連接嘗試。顯然,強制結束意味着沒有成功,所以在你的情況下,Google會倒閉。

---- ----編輯

我加入的是如何將一個看門狗在這種情況下實施的示例。請記住,這是一種解決方案,甚至不需要發生,但如果您真的需要,它應該可以做到這一點。我要離開原來的代碼,所以你可能會看到不同之處:

Socket socket; 

// You'll use this flag to check wether you're still trying to connect 
boolean is_connecting = false; 

final String host = "www.google.com"; 
final int port = 80; 
final int timeout = 30000; // 30 seconds 

// This method will test whether the is_connecting flag is still set to true 
private void stillConnecting() { 
    if (is_connecting) { 
    Log.e("GoogleSock", "The socket is taking too long to establish a connection, Google is probably down!"); 
    } 
} 

try { 
    socket = new Socket(); 
    is_connecting = true; 
    socket.connect(new InetSocketAddress(host, port), timeout); 

    // Start a handler with postDelayed for 30 seconds (current timeout value), it will check whether is_connecting is still true 
    // That would mean that it won't probably resolve the host at all and the connection failed 
    // postDelayed is non-blocking, so don't worry about your thread being blocked 
    new Handler().postDelayed(
    new Runnable() { 
     public void run() { 
     stillConnecting(); 
     } 
    }, timeout); 
} 
catch (UnknownHostException uhe) { 
    is_connecting = false; 
    Log.e("GoogleSock", "I couldn't resolve the host you've provided!"); 
    return; 
} 
catch (SocketTimeoutException ste) { 
    is_connecting = false; 
    Log.e("GoogleSock", "After a reasonable amount of time, I'm not able to connect, Google is probably down!"); 
    return; 
} 
catch (IOException ioe) { 
    is_connecting = false; 
    Log.e("GoogleSock", "Hmmm... Sudden disconnection, probably you should start again!"); 
    return; 
} 

// If you've reached this point, it would mean that the socket went ok, so Google is up 
is_connecting = false; 

注意:我假設你這樣做,你應該(我的意思是,不是在主UI),而這正在一個線程內進行(您可以使用AsyncTask,一個線程,一個服務內的線程......)。

+0

您能解釋一下WatchDog線程如何應用於您的解決方案嗎? – RDX

+0

編輯並添加了一個示例,以便您可以看到與以前答案的差異。希望這可以幫助。 – nKn

1

的廣播接收機可能出現派上用場:

BroadcastReceiver networkStateReceiver = new BroadcastReceiver() { 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      Toast.makeText(getActivity(), "Connection reset, rolling back", Toast.LENGTH_LONG).show(); 

     } 
    }; 

這也是省電的。

而且不要忘記註銷它:(的onDestroy())

getActivity().unregisterReceiver(networkStateReceiver); 
+1

您應該按照正確的意圖操作進行過濾,否則您會收到系統發送的所有廣播,並且發送錯誤消息。在onResume/onPause中首選註冊/取消註冊,如果需要其他生命週期,您可以創建清單broadcastreceiver ... – Magnus

+0

沒錯! onPause onResume更受歡迎! – Skynet

1

隨着星芒說,你可以用廣播接收器來獲得互聯網連接的狀態,這就是檢查互聯網連接的最佳方式;但是如果你試圖連接的服務器關閉或者沒有響應,那麼爲了安全起見,創建一個超時循環。 如果在特定時間內沒有從服務器回覆迴應,則取消請求並向用戶顯示錯誤消息。