web-dev-qa-db-ja.com

インターネットリスナーAndroidの例

私はAndroidアプリを継続的にインターネットに接続したままにします。インターネットがダウンしている場合、ユーザーに適切なメッセージを表示するはずです。

インターネットリスナーのようなものはありますか?または、このイベントを実装して、インターネット接続が利用できない場合は常に警告を表示する方法。

25

そのためのブロードキャストレシーバーを1つ作成し、マニフェストファイルに登録します。

まず、新しいクラスNetworkStateReceiverを作成し、BroadcastReceiverを拡張します。

public class NetworkStateReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
     Log.d("app","Network connectivity change");
     if(intent.getExtras()!=null) {
        NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
        if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
            Log.i("app","Network "+ni.getTypeName()+" connected");
        }
     }
     if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
            Log.d("app","There's no network connectivity");
     }
   }
}

このコードをAndroidManifest.xmlの「application」要素の下に配置します。

<receiver Android:name=".NetworkStateReceiver">
   <intent-filter>
      <action Android:name="Android.net.conn.CONNECTIVITY_CHANGE" />
   </intent-filter>
</receiver>

そして、この許可を追加します

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

[〜#〜]編集[〜#〜]

このコードは接続の変更を検出するだけですが、接続先のネットワークがインターネットにアクセスできるかどうかはわかりません。このメソッドを使用して、次のことを確認します-

public static boolean hasActiveInternetConnection(Context context) {
    if (isNetworkAvailable(context)) {
        try {
            HttpURLConnection urlc = (HttpURLConnection) (new URL("http://www.google.com").openConnection());
            urlc.setRequestProperty("User-Agent", "Test");
            urlc.setRequestProperty("Connection", "close");
            urlc.setConnectTimeout(1500); 
            urlc.connect();
            return (urlc.getResponseCode() == 200);
        } catch (IOException e) {
        Log.e(LOG_TAG, "Error checking internet connection", e);
        }
    } else {
    Log.d(LOG_TAG, "No network available!");
    }
    return false;
}
49
Chirag

上記のChirag Ravalのコードは確かに機能します。問題は、アプリケーションがフォアグラウンドで実行されていない場合でもリスナーが呼び出されることです。

IMHO、より良いアプローチは、すべてのアプリケーションアクティビティのonResume()/onPause()メソッドでレシーバーを登録/登録解除することです。このコードはそれを行うべきです:

private final NetworkStateReceiver stateReceiver = new NetworkStateReceiver();

@Override
protected void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter();
    filter.addAction("Android.net.conn.CONNECTIVITY_CHANGE");
    registerReceiver(stateReceiver, filter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(stateReceiver);
}

もちろん、AndroidManifest.xmlファイルから登録を削除します。

このソリューションを使用すると、アプリケーションのアクティビティを切り替えるときにもレシーバーが呼び出されます(アクティビティを閉じている場合)。このような場合は、以下の例のように(onlineと呼ばれる)静的フラグ(すべてのアクティビティ間で共有される)を使用します。

public class NetworkStateReceiver extends BroadcastReceiver {

    private static boolean online = true;  // we expect the app being online when starting

    public static final String TAG = NetworkStateReceiver.class.getSimpleName();

    public void onReceive(Context context, Intent intent) {
        Log.d(TAG,"Network connectivity change");
        ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = manager.getActiveNetworkInfo();
        if (ni == null || ni.getState() != NetworkInfo.State.CONNECTED) {
            Log.d(TAG,"There's no network connectivity");
            if (online) // don't show the message if already offline
                Toast.makeText(context, R.string.noInternet, Toast.LENGTH_SHORT).show();
            online = false;
        } else {
            Log.d(TAG,"Network "+ni.getTypeName()+" connected");
            if (!online)  // don't show the message if already online
                Toast.makeText(context, R.string.backOnline, Toast.LENGTH_SHORT).show();
            online = true;
        }
    }
}

オフラインでアプリを起動すると、トーストメッセージが表示されます。それ以外の場合は、接続が失われた/再確立されたときにのみ表示されます。

2
pepan