【问题标题】:Android developer: how to detect when WiFI hotspot is turned on/offAndroid 开发者:如何检测 WiFI 热点何时开启/关闭
【发布时间】:2021-09-24 12:24:19
【问题描述】:

我已经注册了 ConnectivityManager NetworkCallback 如下:

val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val builder = NetworkRequest.Builder()
            .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
cm.registerNetworkCallback(
                builder.build(),
                object : ConnectivityManager.NetworkCallback() {

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

                    override fun onLosing(network: Network, maxMsToLive: Int) {
                        super.onLosing(network, maxMsToLive)
                        Log.i(TAG, "Network $network is losing after $maxMsToLive ms")
                    }

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

                    override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
                        super.onCapabilitiesChanged(network, caps)
                        Log.i(TAG, "Network $network capabilities changed: $caps")
                    }

                    override fun onLinkPropertiesChanged(network: Network, props: LinkProperties) {
                        super.onLinkPropertiesChanged(network, props)
                        Log.i(TAG, "Network $network link properties changed: $props")
                    }
                }
    }

当我在我的 Android 11 设备中打开/关闭热点时,没有调用任何回调函数,即,当我打开/关闭 WiFi 热点时,我没有收到任何消息给 logcat。

当热点关闭时,设备有以下地址:

PAN_sprout:/ $ ip addr                                                        
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 46:85:2d:8f:9a:8e brd ff:ff:ff:ff:ff:ff
    inet6 fe80::4485:2dff:fe8f:9a8e/64 scope link
       valid_lft forever preferred_lft forever
3: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
    link/ipip 0.0.0.0 brd 0.0.0.0
4: ip6_vti0@NONE: <NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1
    link/tunnel6 :: brd ::
5: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
    link/sit 0.0.0.0 brd 0.0.0.0
6: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1
    link/tunnel6 :: brd ::
8: rmnet0: <UP,LOWER_UP> mtu 2000 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/[530]
9: rmnet_data0: <UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/[530]
    inet6 fe80::9e2:b3d5:84e6:14c/64 scope link
       valid_lft forever preferred_lft forever
10: rmnet_data1: <UP,LOWER_UP> mtu 1464 qdisc htb state UNKNOWN group default qlen 1000
    link/[530]
    inet 10.140.85.190/30 scope global rmnet_data1
       valid_lft forever preferred_lft forever
    inet6 2001:14bb:a0:5545:818d:5109:4166:b991/64 scope global dynamic mngtmpaddr
       valid_lft forever preferred_lft forever
    inet6 fe80::818d:5109:4166:b991/64 scope link
       valid_lft forever preferred_lft forever
...
25: r_rmnet_data8: <> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/[530]

当我打开它时,设备有这些地址:

PAN_sprout:/ $ ip addr                                                        
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: dummy0: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
    link/ether 46:85:2d:8f:9a:8e brd ff:ff:ff:ff:ff:ff
    inet6 fe80::4485:2dff:fe8f:9a8e/64 scope link
       valid_lft forever preferred_lft forever
3: ip_vti0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
    link/ipip 0.0.0.0 brd 0.0.0.0
4: ip6_vti0@NONE: <NOARP> mtu 1500 qdisc noop state DOWN group default qlen 1
    link/tunnel6 :: brd ::
5: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
    link/sit 0.0.0.0 brd 0.0.0.0
6: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1
    link/tunnel6 :: brd ::
8: rmnet0: <UP,LOWER_UP> mtu 2000 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/[530]
9: rmnet_data0: <UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 1000
    link/[530]
    inet6 fe80::9e2:b3d5:84e6:14c/64 scope link
       valid_lft forever preferred_lft forever
10: rmnet_data1: <UP,LOWER_UP> mtu 1464 qdisc htb state UNKNOWN group default qlen 1000
    link/[530]
    inet 10.140.85.190/30 scope global rmnet_data1
       valid_lft forever preferred_lft forever
    inet6 2001:14bb:a0:5545:818d:5109:4166:b991/64 scope global dynamic mngtmpaddr
       valid_lft forever preferred_lft forever
    inet6 fe80::818d:5109:4166:b991/64 scope link
       valid_lft forever preferred_lft forever
...
25: r_rmnet_data8: <> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/[530]
176: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 7a:d1:a3:76:b8:8a brd ff:ff:ff:ff:ff:ff
    inet 192.168.214.149/24 brd 192.168.214.255 scope global wlan0
       valid_lft forever preferred_lft forever
    inet6 2001:14bb:a0:5545::5a/64 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::78d1:a3ff:fe76:b88a/64 scope link
       valid_lft forever preferred_lft forever

如您所见,添加了 wlan0,但没有调用回调函数。回调函数确实可以正常工作,例如,当我打开/关闭蜂窝网络时。

问题是:我需要做什么才能在打开/关闭 WiFi 热点时调用回调函数。

编辑:根据 Sergio Pardo 的回答,我创建了这个:

val hotSpotReceiver = object : BroadcastReceiver() {
            override fun onReceive(contxt: Context, intent: Intent) {
                val action = intent.action
                if ("android.net.wifi.WIFI_AP_STATE_CHANGED" == action) {
                    val state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0)
                    if (WifiManager.WIFI_STATE_ENABLED == state % 10)
                        Log.d(TAG, "HotSpot is enabled")
                    else
                        Log.d(TAG, "HotSpot is disabled")
                    }
                }
            }
        }
this.registerReceiver(hotSpotReceiver,
    IntentFilter("android.net.wifi.WIFI_AP_STATE_CHANGED"))

它可用于检测 WiFi 热点何时启用或禁用并回答问题的标题。但它对调用 NetworkCallbacks 没有帮助。

回调可以让我了解热点的本地 IP 地址和接口名称。有没有其他方法可以解决这个问题?

编辑:原来,当上面的hotSpotReceiver记录“Hotspot is enabled”时,热点接口获取IP地址和路由有延迟。缺少的网络回调会有所帮助。

【问题讨论】:

    标签: android hotspot android-connectivitymanager


    【解决方案1】:

    我认为您正在尝试使用错误的系统服务,并在稍后实施。您应该使用“Context.WIFI_SERVICE”,这将为您提供一个 Wifi 管理器。

    val manager = getSystemService(Context.CONNECTIVITY_SERVICE) as WifiManager
    

    然后您可以使用该值来查看热点是否开启:

    public static boolean isHotspotOn(final WifiManager manager) {
        try {
            final Method method = 
                manager.getClass().getDeclaredMethod("isWifiApEnabled");
            return (Boolean) method.invoke(manager);
        } catch (final Throwable ignored) {}
    
        return false;
    }
    

    如果你还想监听热点的更新,你应该用下面的 IntentFilter 来做

    IntentFilter filter = new IntentFilter("android.net.wifi.WIFI_AP_STATE_CHANGED");
    

    【讨论】:

    • 感谢您的回复。我会试一试。根据 Android 开发者文档,ConnectivityManager“监控网络连接(Wi-Fi、GPRS、UMTS 等),在网络连接发生变化时发送广播意图,......”。确保WiFi热点开启时,网络连接发生变化,热点所在设备可以通过热点WiFi网络启动与其他方通信。如果 Connectivitymanager 与 WiFI 热点相关的连接变化没有任何关系,那么 ConnectivityManager 官方文档就有很大问题。
    【解决方案2】:

    Google 对我的错误报告的回答:

    这是自 Android 12 起所有 Android 实现的已知限制。我们希望在未来对此进行改进,但目前无法分享时间表。

    然后他们关闭了状态为Won't Fix (Intended behavior) 的错误报告。我将尝试升级此问题,因为违反官方 API 文档并阻止应用响应网络连接更改的行为不能是“预期行为”。

    【讨论】:

      猜你喜欢
      • 2011-09-17
      • 1970-01-01
      • 1970-01-01
      • 2018-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      相关资源
      最近更新 更多