143 lines
4.7 KiB
Kotlin
143 lines
4.7 KiB
Kotlin
package jp.juggler.subwaytooter.util
|
|
|
|
import android.content.Context
|
|
import android.net.*
|
|
import android.os.Build
|
|
import jp.juggler.util.LogCategory
|
|
import java.lang.RuntimeException
|
|
|
|
class NetworkStateTracker(
|
|
val context : Context,
|
|
val onConnectionStateChanged:()->Unit
|
|
|
|
) : ConnectivityManager.NetworkCallback() {
|
|
|
|
companion object {
|
|
private val log = LogCategory("NetworkStateTracker")
|
|
|
|
// private val NetworkCapabilities?.isConnected : Boolean
|
|
// get() = if(this == null) {
|
|
// log.e("isConnected: missing NetworkCapabilities.")
|
|
// false
|
|
// } else {
|
|
// this.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
|
// }
|
|
}
|
|
|
|
private val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE)
|
|
as ConnectivityManager
|
|
|
|
init {
|
|
if(Build.VERSION.SDK_INT >= 28) {
|
|
try {
|
|
cm.registerDefaultNetworkCallback(this)
|
|
}catch(ex:Throwable){
|
|
// android.net.ConnectivityManager$TooManyRequestsException:
|
|
log.e(ex,"registerDefaultNetworkCallback failed.")
|
|
}
|
|
}
|
|
}
|
|
|
|
// private fun <T> tryOrNull(block : () -> T?) : T? = try {
|
|
// block()
|
|
// } catch(ex : Throwable) {
|
|
// null
|
|
// }
|
|
|
|
// @Suppress("DEPRECATION")
|
|
// private fun NetworkInfo?.getStateString() =
|
|
// if(this == null) {
|
|
// "null"
|
|
// } else {
|
|
// // API 28 以上で typeName と state がdeprecated になっている
|
|
// "${tryOrNull { this.typeName }} ${tryOrNull { this.subtypeName }} ${tryOrNull { this.state }} ${tryOrNull { this.detailedState }}"
|
|
// }
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// NetworkCallback
|
|
|
|
// Called when the framework connects and has declared a new network ready for use.
|
|
// 準備ができた
|
|
override fun onAvailable(network : Network) {
|
|
super.onAvailable(network)
|
|
val nc = try {
|
|
cm.getNetworkCapabilities(network)?.toString()
|
|
} catch(ex : Throwable) {
|
|
log.e(ex, "getNetworkCapabilities failed.")
|
|
}
|
|
log.d("onAvailable $network $nc")
|
|
onConnectionStateChanged()
|
|
}
|
|
|
|
// Called when the network the framework connected to for this request changes capabilities but still satisfies the stated need.
|
|
// 接続完了し、ネットワークが変わったあと
|
|
override fun onCapabilitiesChanged(
|
|
network : Network,
|
|
networkCapabilities : NetworkCapabilities
|
|
) {
|
|
super.onCapabilitiesChanged(network, networkCapabilities)
|
|
log.d("onCapabilitiesChanged $network, $networkCapabilities")
|
|
onConnectionStateChanged()
|
|
}
|
|
|
|
// Called when the network the framework connected to for this request changes LinkProperties.
|
|
override fun onLinkPropertiesChanged(network : Network, linkProperties : LinkProperties) {
|
|
super.onLinkPropertiesChanged(network, linkProperties)
|
|
log.d("onLinkPropertiesChanged $network, $linkProperties")
|
|
onConnectionStateChanged()
|
|
}
|
|
|
|
override fun onLosing(network : Network, maxMsToLive : Int) {
|
|
super.onLosing(network, maxMsToLive)
|
|
log.d("onLosing $network, $maxMsToLive")
|
|
onConnectionStateChanged()
|
|
}
|
|
|
|
// Called when the framework has a hard loss of the network or when the graceful failure ends.
|
|
override fun onLost(network : Network) {
|
|
super.onLost(network)
|
|
log.d("onLost $network")
|
|
onConnectionStateChanged()
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
// null if connected, else error status.
|
|
val connectionState : String?
|
|
get() = if(Build.VERSION.SDK_INT >= 29) {
|
|
val activeNetwork = cm.activeNetwork
|
|
if(activeNetwork == null) {
|
|
"connectionState: activeNetwork is null"
|
|
} else {
|
|
val capabilities = cm.getNetworkCapabilities(activeNetwork)
|
|
|
|
// log.d("connectionState: $activeNetwork $capabilities")
|
|
// connectionState: 103 [ Transports: WIFI Capabilities: NOT_METERED&INTERNET&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps SignalStrength: -48]
|
|
|
|
// capabilities.isConnected でも cm.isDefaultNetworkActive でもなく
|
|
// インターネット接続ありかどうかを確認する
|
|
if( capabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) ==true ) {
|
|
null
|
|
}else{
|
|
"connectionState: hasCapability(internet) is false. $activeNetwork $capabilities"
|
|
}
|
|
}
|
|
} else {
|
|
@Suppress("DEPRECATION")
|
|
val activeNetworkInfo = cm.activeNetworkInfo
|
|
|
|
@Suppress("DEPRECATION")
|
|
if(activeNetworkInfo == null) {
|
|
"connectionState: activeNetworkInfo is null"
|
|
} else if(! activeNetworkInfo.isConnected) {
|
|
"connectionState: not connected. $activeNetworkInfo"
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
|
|
fun checkNetworkState() {
|
|
val status = connectionState
|
|
if(status != null) throw RuntimeException(status)
|
|
}
|
|
} |