はじめに
今回はAndroidにおけるネットワーク監視の共通処理を実装してみようと思います
コード
fun Context.isOnline(): Boolean {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
return connectivityManager?.getNetworkCapabilities(connectivityManager.activeNetwork)?.run {
when {
hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
hasTransport(NetworkCapabilities.TRANSPORT_VPN) -> true
else -> false
}
} ?: false
}
@Singleton
class NetworkConnectivityChecker @Inject constructor(
@ApplicationContext private val context: Context,
) {
private val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// ネットワーク状態を Flow で公開
private val _networkState = MutableStateFlow(context.isOnline())
val networkState: StateFlow<Boolean> = _networkState.asStateFlow()
init {
registerNetworkCallback()
}
private fun registerNetworkCallback() {
try {
val networkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build()
val callback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
_networkState.value = true
}
override fun onLost(network: Network) {
// 他のネットワークがまだ有効かどうかを確認
// Wi-Fi ↔ モバイルネットワークの切り替え時に誤ってfalseにならないようにする
_networkState.value = context.isOnline()
}
override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities,
) {
val hasInternet = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
val hasValidated = networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
_networkState.value = hasInternet && hasValidated
}
}
connectivityManager.registerNetworkCallback(networkRequest, callback)
} catch (e: Exception) {
}
}
}
最後に
復帰時にすぐ更新をかけたい時などに役立つと思います