【问题标题】:Android ConnectivityManager onAvailable sometime not returnedAndroid ConnectivityManager onAvailable 有时未返回
【发布时间】:2019-09-13 08:37:40
【问题描述】:

我们使用 Android ConnectivityManager 来监听我们应用内的互联网连接变化,如下所示。

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        ConnectionStateMonitor().enable(this)
    }

    class ConnectionStateMonitor : NetworkCallback() {
        private val networkRequest: NetworkRequest = NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build()

        fun enable(context: Context) {
            val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            connectivityManager.registerNetworkCallback(networkRequest, this)
        }

        override fun onAvailable(network: Network) {
            Log.i(TAG, "onAvailable ")
        }

        override fun onLost(network: Network?) {
            super.onLost(network)
            Log.i(TAG, "onLost ")
        }
    }
}

除了我们遇到的两个问题之外,此实现运行良好

  1. 如果我们同时使用 wifi 和移动数据连接到互联网并关闭 wifi,有时会触发onLost() 回调,然后触发onAvailable(),正如预期的那样,但在其他情况下 onLost() 被触发,这是不正确的。

  2. 如果我们没有互联网连接并打开应用程序onLost() 不会触发,但是如果我们有互联网连接并打开应用程序onAvailable() 会触发。

任何帮助、建议、解决方法或其他可靠地检测互联网连接变化的方法都将非常感激。

在小米 A2 (Android 9)、一加 (Android 9) 上测试

演示项目
https://github.com/PhanVanLinh/AndroidNetworkChangeReceiver

【问题讨论】:

  • 您找到解决第二个问题的方法了吗?
  • 不,我找不到答案,所以我从我的应用程序中删除了这个功能。我还在寻找解决方案

标签: android android-connectivitymanager


【解决方案1】:

我使用了您的项目,并添加了另一种方法:onCapabilitiesChanged。我从 ebabled 的飞行模式开始,然后我关闭然后再次打开。这些是日志:

onAvailable 632

onCapabilitiesChanged 632 [传输:CELLULAR ...]

onAvailable 632

onCapabilitiesChanged 632 [传输:CELLULAR ...]

onAvailable 632

onCapabilitiesChanged 632 [传输:CELLULAR ...]

onCapabilitiesChanged 632 [传输:CELLULAR ...]

onCapabilitiesChanged 632 [传输:CELLULAR ...]

onAvailable 633

onCapabilitiesChanged 633 [传输:WIFI ...] onAvailable 633 onCapabilitiesChanged 633 [传输:WIFI ...]

onAvailable 633

onCapabilitiesChanged 633 [传输:WIFI ...]

onCapabilitiesChanged 633 [传输:WIFI ...]

onCapabilitiesChanged 633 [传输:WIFI ...]

onCapabilitiesChanged 633 [传输:WIFI ...]

onCapabilitiesChanged 633 [传输:WIFI ...]

onCapabilitiesChanged 633 [传输:WIFI ...]

onLost 632

onLost 632

onLost 632

onLost 633

onLost 633

onLost 633

onAvailable 634

onCapabilitiesChanged 634 [传输:CELLULAR ...]

onAvailable 634

onCapabilitiesChanged 634 [传输:CELLULAR ...]

onAvailable 634

onCapabilitiesChanged 634 [传输:CELLULAR ...]

onCapabilitiesChanged 634 [传输:CELLULAR ...]

onCapabilitiesChanged 634 [传输:CELLULAR ...]

onCapabilitiesChanged 634 [传输:CELLULAR ...]

onAvailable 635

onCapabilitiesChanged 635 [传输:WIFI ...]

onAvailable 635

onCapabilitiesChanged 635 [传输:WIFI ...]

onAvailable 635

onCapabilitiesChanged 635 [传输:WIFI ...]

onCapabilitiesChanged 635 [传输:WIFI ...]

onCapabilitiesChanged 635 [传输:WIFI ...]

onCapabilitiesChanged 635 [传输:WIFI ...]

onLost 634

onLost 634

onLost 634

onCapabilitiesChanged 635 [传输:WIFI ...]

onCapabilitiesChanged 635 [传输:WIFI ...]

如您所见,LOST 用于蜂窝传输,而AVAILABLE 用于WiFi

按照您的用例(启用 wifi、启用移动数据、禁用 wifi 数据、启用 wifi、禁用 wifi)这就是我得到的。

onAvailable 640

onCapabilitiesChanged 640 [传输:WIFI ...]

onAvailable 640

onCapabilitiesChanged 640 [传输:WIFI ...]

onCapabilitiesChanged 640 [传输:WIFI ...]

onCapabilitiesChanged 640 [传输:WIFI ...]

onCapabilitiesChanged 640 [传输:WIFI ...]

onCapabilitiesChanged 640 [传输:WIFI ...]

onLost 640

onLost 640

onAvailable 641

onCapabilitiesChanged 641 [传输:CELLULAR ...]

onAvailable 641

onCapabilitiesChanged 641 [传输:CELLULAR ...]

onCapabilitiesChanged 641 [传输:CELLULAR ...]

onCapabilitiesChanged 641 [传输:CELLULAR ...]

onAvailable 642

onCapabilitiesChanged 642 [传输:WIFI ...]

onAvailable 642

onCapabilitiesChanged 642 [传输:WIFI ...]

onCapabilitiesChanged 642 [传输:WIFI ...]

onCapabilitiesChanged 642 [传输:WIFI ...]

onCapabilitiesChanged 642 [传输:WIFI ...]

onCapabilitiesChanged 642 [传输:WIFI ...]

onLost 641

onLost 641

onLost 642

onLost 642

onAvailable 643

onCapabilitiesChanged 643 [传输:CELLULAR ...]

onAvailable 643

onCapabilitiesChanged 643 [传输:CELLULAR ...]

onCapabilitiesChanged 643 [传输:CELLULAR ...]

onCapabilitiesChanged 643 [传输:CELLULAR ...]

【讨论】:

  • 感谢您的测试。我读了你的日志 3 次,但仍然无法理解。目前,如果你有 android 9 设备,你可以像这样再次测试几次`enable wifi, enable mobiledata, disable wifi data, enable wifi, disable wifi // 通常这里不调用 onAvaiable)。你可以尝试几次,你会发现问题。在我的 android 8 设备中,一切正常,但我不确定所有 android 8 是否正常
  • 它为我的蜂窝网络调用了 onAvailable:每次我关闭 Wifi(即使是最后一次)。我使用的是搭载 Android 9 的三星 Note 8。
  • 再试一次,我打开 Wifi 时没有得到蜂窝网络的 onLost,然后我关闭它时没有得到 onAvailable。
  • onCapabilitiesChanged 应该可以解决问题。我也有类似的问题,并通过添加检查有效的互联网 networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) 帮助
【解决方案2】:

AndroidManifest 上的广播接收器定义发生了一些变化。您可以在here 上找到相应的描述。

您已经实现了这种方式,但无论如何我想添加 Network callback class references 作为参考点。

【讨论】:

  • 我在 github 上阅读了您的源代码,发现您的主要想法是每 5 秒检查一次互联网状态。如果它是正确的,我觉得它对性能不是很好。有什么办法可以优化吗?如果我错了,请纠正我。
  • 您好 Linh,我可以理解您的担忧,然后我会更新答案的上下文可能您可以在 developer.android.com 上找到另一个解决方案。
  • 是的,实际上聆听互联网连接的变化对我的应用程序来说只是一点点改进。如果它消耗太多电池,我想我不需要把它放在里面,因为它没有太多好处。现在我已经从我的应用程序中删除了这个功能:D,就在调用 API 并且没有互联网时,我显示错误:v
【解决方案3】:

也许您可以尝试使用requestNetwork 而不是registerNetworkCallback

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-29
    • 1970-01-01
    相关资源
    最近更新 更多