web-dev-qa-db-ja.com

Android:インターネット接続変更リスナー

接続の変更をリッスンするこのコードは既にあります-

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");
    }
  }
}

このコードを使用してインターネット接続を確認します- インターネットチェック

しかし問題は、接続が変更されずにネットワークが突然インターネット接続を失った場合、このコードは役に立たないことです。インターネット接続の変更のためにBroadcast Receiverリスナーを作成する方法はありますか? Webアプリを使用していますが、インターネット接続が突然変更されると問題が発生する可能性があります。

50
Confuse

これを試して

public class NetworkUtil {
    public static final int TYPE_WIFI = 1;
    public static final int TYPE_MOBILE = 2;
    public static final int TYPE_NOT_CONNECTED = 0;
    public static final int NETWORK_STATUS_NOT_CONNECTED = 0;
    public static final int NETWORK_STATUS_WIFI = 1;
    public static final int NETWORK_STATUS_MOBILE = 2;

    public static int getConnectivityStatus(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        if (null != activeNetwork) {
            if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
                return TYPE_WIFI;

            if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
                return TYPE_MOBILE;
        } 
        return TYPE_NOT_CONNECTED;
    }

    public static int getConnectivityStatusString(Context context) {
        int conn = NetworkUtil.getConnectivityStatus(context);
        int status = 0;
        if (conn == NetworkUtil.TYPE_WIFI) {
            status = NETWORK_STATUS_WIFI;
        } else if (conn == NetworkUtil.TYPE_MOBILE) {
            status = NETWORK_STATUS_MOBILE;
        } else if (conn == NetworkUtil.TYPE_NOT_CONNECTED) {
            status = NETWORK_STATUS_NOT_CONNECTED;
        }
        return status;
    }
}

BroadcastReceiverの場合

public class NetworkChangeReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {

        int status = NetworkUtil.getConnectivityStatusString(context);
        Log.e("Sulod sa network reciever", "Sulod sa network reciever");
        if ("Android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
            if (status == NetworkUtil.NETWORK_STATUS_NOT_CONNECTED) {
                new ForceExitPause(context).execute();
            } else {
                new ResumeForceExitPause(context).execute();
            }
       }
    }
}

これをAndroidManifest.xmlに入れることを忘れないでください

 <uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE" />
 <uses-permission Android:name="Android.permission.INTERNET" />
 <receiver
        Android:name="NetworkChangeReceiver"
        Android:label="NetworkChangeReceiver" >
        <intent-filter>
            <action Android:name="Android.net.conn.CONNECTIVITY_CHANGE" />
            <action Android:name="Android.net.wifi.WIFI_STATE_CHANGED" />
        </intent-filter>
    </receiver>

これが乾杯に役立つことを願っています!

74
Cjames

更新

Android 7.0(APIレベル24)以降を対象とするアプリは、マニフェストでブロードキャストレシーバーを宣言している場合、CONNECTIVITY_ACTIONブロードキャストを受信しません。アプリがBroadcastReceiverをContext.registerReceiver()に登録しても、そのコンテキストがまだ有効な場合、アプリはCONNECTIVITY_ACTIONブロードキャストを受信します。

registerReceiver()メソッドでレシーバーを登録する必要があります。

 IntentFilter intentFilter = new IntentFilter("Android.net.conn.CONNECTIVITY_CHANGE");
 mCtx.registerReceiver(new NetworkBroadcastReceiver(), intentFilter);
31
Silvia H

これは動作するはずです:

public class ConnectivityChangeActivity extends Activity {

    private BroadcastReceiver networkChangeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.d("app","Network connectivity change");
        }
    };

    @Override
    protected void onResume() {
        super.onResume();

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(networkChangeReceiver, intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();

        unregisterReceiver(networkChangeReceiver);
    }
}
13

ConnectivityActionは、API 28以降では 非推奨 です。代わりに、api 24+をサポートしている限り、registerDefaultNetworkCallbackを使用できます。

コトリンでは:

val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager?.let {
    it.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            //take action when network connection is gained
        }
        override fun onLost(network: Network?) {
            //take action when network connection is lost
        }
    })
}
13
bmjohns

これは、アプリケーションスコープで提供できる私の実装です。

class NetworkStateHelper @Inject constructor(
        private val context: Context
) {
    private val cache: BehaviorSubject<Boolean> = BehaviorSubject.create()

    private val receiver = object : BroadcastReceiver() {
        override fun onReceive(c: Context?, intent: Intent?) {
            cache.onNext(isOnlineOrConnecting())
        }
    }

    init {
        val intentFilter = IntentFilter()
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION)
        context.registerReceiver(receiver, intentFilter)
        cache.onNext(isOnlineOrConnecting())
    }

    fun subscribe(): Observable<Boolean> {
        return cache
    }

    fun isOnlineOrConnecting(): Boolean {
        val cm = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val netInfo = cm.activeNetworkInfo
        return netInfo != null && netInfo.isConnectedOrConnecting
    }
}
0
Harco