ConnectivityManager.CONNECTIVITY_ACTION
は API level 28 で、 ConnectivityManager.getActiveNetworkInfo()
と NetworkInfo
クラスそのものは API level 29 で、それぞれ Deprecated になりました。
長きにわたり大変お世話になりました。
Android 10 で通信状態の変更を監視するには、 ConnectivityManager.registerNetworkCallback()
を使いましょう。
サンプルコード
NetworkRequest
で通知を受け取る条件を指定して NetworkCallback
を登録します。
NetworkRequest
は、 NetworkCapabilities
クラスの定数を使って、通知を受け取る条件を細かく指定することができます。
ここではインターネットへの接続が確立されたネットワークに関する通知を受け取りたいので、 NET_CAPABILITY_INTERNET
と NET_CAPABILITY_VALIDATED
を指定しました。
NetworkCallback
や NetworkCapabilities
は API level 21 から使えるのですが、 NET_CAPABILITY_VALIDATED
が API level 23 で追加された定数なので、 API 23 前後で従来の方法と分岐しています。
private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager private fun registerNetworkCallback() { if (Build.VERSION.SDK_INT < 23) { context.registerReceiver( networkReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) ) } else { val request = NetworkRequest.Builder() .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) .build() cm.registerNetworkCallback(request, networkCallback) } } private fun unregisterNetworkCallback() { if (Build.VERSION.SDK_INT < 23) { context.unregisterReceiver(networkReceiver) } else { cm.unregisterNetworkCallback(networkCallback) } }
ネットワークに接続されたときと切断されたときに、通信状態を取得します。
@RequiresApi(23) private val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network?) = checkConnection() override fun onLost(network: Network?) = checkConnection() } @RequiresApi(23) private fun checkConnection() { val activeNetworks = cm.allNetworks.mapNotNull { cm.getNetworkCapabilities(it) }.filter { it.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && it.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) } val isConnected = activeNetworks.isNotEmpty(), val isWiFi = activeNetworks.any { it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) } }
NetworkCallback
は、個々の Network に対して呼ばれます。
例えば Cellular が繋がっているときに WiFi に接続すると、 onAvailable()
で WiFi 接続が有効になったことが通知されたあとしばらく経ってから onLost()
で Cellular の切断が通知されます。
また ConnectivityManager.getActiveNetwork()
は、 WiFi を切って Cellular に切り替わる場合などで、すでに切断されたはずの WiFi Network を返すことがありました。
以上を踏まえて、何らかの通信状態の変更通知を受けたタイミングですべての Network を確認し、
- インターネットへの接続が確立されたものがあるか
- その中に WiFi はあるか
を判断するのが良さそうです。
出典: