I have registered ConnectivityManager NetworkCallback as follows:
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")
}
}
}
When I turn hotspot on/off in my Android 11 device, none of the CallBack functions are called, i.e., I don't get any messages to logcat, when I turn WiFi hotspot on/off.
When hotspot is off, device has these addresses:
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]
and when I turn it on, device has these addresses:
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
As you see, wlan0 was added, but no callback function was called. Callback functions do work otherwise, for example, when I turn cellular network on/off.
Question is: what do I need to do in order to get callback functions called when WiFi hotspot is turned on/off.
Edit: Based on Sergio Pardo's answer, I created this:
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"))
It can be used to detect when WiFi hotspot is enabled or disabled and answers the title of the question. But it does not help in getting the NetworkCallbacks called.
The callbacks would have allowed me to learn hotspot's local IP address and interface name. Is there some other way to figure that out?
Edit: It turned out that when the above hotSpotReceiver logs "Hotspot is enabled", there is delay before the hotspot interface gets its IP addresses and routes. The missing network callbacks would help.