如何确定在恢复 android 应用程序时无法访问互联网

how to determine internet access is not available on resuming android application

我当前的 android 应用程序需要在用户会话期间丢失 Internet 访问时通知用户

我使用了以下回调侦听器:-

@OptIn(DelicateCoroutinesApi::class)
class ConnectivityListener @Inject constructor() : CoroutineScope by GlobalScope, ConnectivityManager.NetworkCallback() {

    private var backgroundStateJob: Job? = null
    private val internalSharedWorkState = MutableSharedFlow<BackgroundState>(replay = 1, extraBufferCapacity = 7, onBufferOverflow = BufferOverflow.DROP_OLDEST)
    private val sharedWorkScheduleState: SharedFlow<BackgroundState> = internalSharedWorkState

    override fun onBlockedStatusChanged(network: Network, blocked: Boolean) {
        Timber.e( "onBlockedStatusChanged() called with: network = $network, blocked = $blocked")
    }
    override fun onLosing(network: Network, maxMsToLive: Int) {
        Timber.e( "onLosing() called with: network = $network, maxMsToLive = $maxMsToLive")
    }
    override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
        Timber.e( "onCapabilitiesChanged() called with: network = $network, networkCapabilities = $networkCapabilities")
    }
    override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
        Timber.e( "onLinkPropertiesChanged() called with: network = $network, linkProperties = $linkProperties")
    }
    override fun onUnavailable() {
        Timber.e( "onUnavailable() called")
    }

    override fun onAvailable(network: Network) {
        Timber.e("onAvailable() called with: network = $network")
        backgroundStateJob?.cancel()
        backgroundStateJob = launch(Dispatchers.IO) {
            internalSharedWorkState.emit(BackgroundState.Connected())
        }
    }

    override fun onLost(network: Network) {
        Timber.e("onLost() called with: network = $network")
        backgroundStateJob?.cancel()
        backgroundStateJob = launch(Dispatchers.IO) {
            internalSharedWorkState.emit(BackgroundState.Disconnected())
        }
    }

    fun stateFlow(): SharedFlow<BackgroundState> {
        return sharedWorkScheduleState
    }
}

此监听器在我的基地 activity 中使用如下:-

private val networkRequest = NetworkRequest.Builder()
    .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
    .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)
    .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
    .addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
    .build()

...

 override fun onResume() {
        Timber.e("onResume() called")
        super.onResume()
        val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        connectivityManager.registerNetworkCallback(networkRequest, connectivityListener)

    }

    override fun onPause() {
        Timber.e("onPause() called")
        super.onPause()
        val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        connectivityManager.unregisterNetworkCallback(connectivityListener)
    }

当应用程序在前台时,侦听器按预期工作,并且在 Internet 访问丢失时可靠地通知用户当前网络状态。

当我退出应用程序时,侦听器也工作正常,它进入后台并随后恢复。侦听器成功报告我可以访问互联网。

但是当我将应用程序置于后台,启用飞行模式然后恢复应用程序时,侦听器无法按要求工作。

它不会检测到没有互联网访问,即使当应用程序从后台恢复并且未启用飞行模式时它确实检测到互联网访问何时可用。

我做错了什么? 从后台恢复我的应用程序时如何检测当前网络状态?

我通过添加第二个

设法达到了预期的结果

网络回调如下,使用requestNetwork()

超时
override fun onResume() {
    super.onResume()
    val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    connectivityManager.registerNetworkCallback(networkRequest, connectivityListenerMonitor)
    connectivityManager.requestNetwork(networkRequest, connectivityListener, 1000)
}

override fun onPause() {
    super.onPause()
    val connectivityManager = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    connectivityManager.unregisterNetworkCallback(connectivityListener)
    connectivityManager.unregisterNetworkCallback(connectivityListenerMonitor)
}

现在当我的应用程序在后台并且我启用飞行模式时 然后将我的应用程序带到前台,通知我的用户没有互联网连接。