web-dev-qa-db-ja.com

Androidインターネット接続チェックのより良い方法

Android開発者サイト、接続ステータスの判断と監視によると、アクティブなインターネット接続があることを確認しますが、Wi-Fiのみが接続されていて、インターネットが利用できない場合は機能しません(インターネット接続があることを通知します)。

次に、Webサイトにpingを実行して、インターネット接続が利用可能かどうかを確認します。また、この方法にはさらに処理時間が必要です。アドレスのpingの時間遅延を回避するために、これよりもインターネット接続を確認するためのより良い方法はありますか?

16
Rohith Krishnan

これを試して:

それは本当にシンプルで速いです:

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
}
9
sumit

以下を試してください:

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
{    }
4
Atlas_Gondal

最初に明らかにすべき問題は、whether internet is available

  • Wi-Fiまたはセルラーネットワークに接続されていません。
  • 限られたwifiに接続:例学校のネットワークでは、学校のwifiに接続すると、イントラネットに直接アクセスできます。ただし、エクストラネットにアクセスするには、学校のアカウントでログインする必要があります。この場合、エクストラネットWebサイトにpingを実行すると、一部のイントラネットがログインページに自動リダイレクトされたため、応答が返される場合があります。
  • 無制限の無線LANに接続:ほとんどのウェブサイトに自由にアクセスできます。

2番目の問題は、何を達成したいですか?

あなたの説明を理解している限り、ネットワークの接続をテストし、失敗した場合にユーザーに通知する必要があります。そのため、サーバーにpingを実行することをお勧めします。これは、サーバーとデータを交換する場合は常に問題ありません。


接続性をテストするより良い方法があるかどうか疑問に思います、そして答えはノーです。

現在のTCP/IPネットワークは仮想回線、パケット交換ネットワークです。つまり、実行するデータの固定「パス」はありません。つまり、電話のようではなく、実際の接続があります。 2人のユーザーの場合、回線が切断された直後に接続が失われたことがわかります。パケットを宛先に送信する必要があり、応答が見つからない場合、接続が失われることがわかります(これはping-ICMPプロトコル-が行うことです)。

結論として、ping以外にホストへの接続をテストするより良い方法はありません。そのため、サービス管理でheartbeatが使用されます。

4
Tony

この問題を確認すると、開発者サイトで指定されているメソッドを使用して、アクティブなインターネット接続が存在するかどうかを判断できないことがわかりました: https://developer.Android.com/training/monitoring-device-state/ connectivity-monitoring.html

これは、wifiのアクティブな接続のみをチェックします。

だから、アクティブなインターネット接続があるかどうかを確認する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.ソケットを使用してGoogle 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;
} 

2番目の方法は2番目の方法よりも少し高速です(私の要件に適しています)

回答とサポートに感謝します。

2
Rohith Krishnan

インターネット接続を確認するためにこれを試すことができます:

/**
 * 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 PERMISSIONを追加することを忘れないでください:

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

URLをpingするだけの場合は、これを試してください。

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
Andy Developer

// ***インターネットアクセスを確認するには

public static Boolean isOnline(){

    boolean isAvailable = false;
    try {

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);
        URL url = new URL("https://stackoverflow.com/");
        HttpURLConnection httpURLConnection = null;
        httpURLConnection = (HttpURLConnection) url.openConnection();

        // 2 second time out.
        httpURLConnection.setConnectTimeout(2000);
        httpURLConnection.connect();
        if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
            isAvailable = true;
        } else {
            isAvailable = false;
        }
    } catch (IOException e) {
        e.printStackTrace();
        isAvailable = false;
    }

    if (isAvailable){
        return true;
    }else {
        return false;
    }
}
1
Milad shoeibi

たぶんこれはあなたを助けることができます:

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;
    }
}
1

コメントしたかったのですが、評判が十分ではありませんでした:/

とにかく、受け入れられた答えの問題は、SocketTimeoutExceptionをキャッチしないことです。これは、クラッシュを引き起こす野生(Android)で見たものです。

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; 
    } catch (SocketTimeoutException e) {
        return false;
    }
}
1
Justin Midyet

この方法を試してください、これはあなたを助けます:

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;
}
1
vikas singh

ConnectivityManagerは、WIFIにアクティブな接続があるかどうかを通知できません。

アクティブなインターネット接続があるかどうかを確認する唯一のオプションは、URLをpingすることです。ただし、アプリから行うすべての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秒に設定します。 10秒以内に応答が得られない場合、アクティブなインターネット接続がなく、例外がスローされます(ほとんどの場合、10秒以内に応答が得られます)。毎回pingを実行してアクティブな接続を確認する必要はありません(チャットアプリやVOIPアプリを作成していない場合)

1
Ashish Rathee