Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android WiFi manager network switch when connecting to a configured network

I am seeing some interesting behaviour when dealing with Wifi Manager on latest versions of Android(on Pixel especially). I am trying to make the WIFI manager connect to a known hotspot(IOT appliance).

Google lists the steps clearly in a blog post, if you are on lollipop and above you need to bind to a particular network to make sure your network requests pass through a given network. Can find the steps here https://android-developers.googleblog.com/2016/07/connecting-your-app-to-wifi-device.html

The listed steps work fine in a normal scenario( you search for the access points through a scan and do an add network because this wasn't configured earlier). But if the access point is connected manually from the Wifi list the add network would fail( from Android M and above you are not allowed to change wifi configuration done by another app or the system) and I have to connect to the already configured network. This case always causes a network switch after about 20-30 seconds.

I think this is caused by https://android.googlesource.com/platform/frameworks/base/+/master/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java because Google calls home and checks if the network has internet.

But I could not figure out why this only happens when the network is previously connected from Settings -> Wifi

Sorry for the long-winded post if anyone has any clue why this is happening and if there is any way to prevent it, would really appreciate it. Note that it is not possible to update the wifi configuration on M and above. Also, disable network doesn't help either. Also interestingly this only happens on a pixel but not on a Samsung device(No network agent ?).

like image 823
eswarm Avatar asked Jan 22 '18 09:01

eswarm


1 Answers

I've encountered similar problem.

I may only assume that manual connection via Settings-> WiFi in Android system is considered as an Internet connection by default and if there is no Internet on particular WiFi network it tries to switch it to the one that have this connection.

In seems that Google thinks that if you are using IOT device - you should have an app to handle this connection and device usage. The default app in Settings is only for the Internet things.

It seems that it is the default behaviour of clean Android. I assume that Samsung(and maybe some others) changed this behaviour on purpose since they have plenty of devices that can be connected this way to the phone from their smart home line - just for it to be more comfortable for the end users.

From the developers perspective - there are not much you can do since proprietary and stuff...

But there is always a way you can try.

The most obvious one is to use reflection and normal operations to alter the behaviour of NetworkAgentInfo.java - change lingering and avoidBadWiFi stuff or something like that - it would require a bit of investigation about what exactly should be changed.

Reflection approach could be used to alter the WifiManager behaviour - for example you may call the forgetNetwork(int netId) method via reflection and forget the network if it was manually added via Settings -> WiFi and reconnect it once more via your app. You can make it as silent as possible for the user not to be aware of this under-the-hood kitchen.

The downside of reflection is that you may have to create different approaches for different versions of Android and might be even for different devices(hopefully not)

If you are developing for the specific device - root it and alter default WiFi settings - it is very radical solution though, and it is very limiting one. Also it will require quite a learning curve to know your way in .smali infrastructure.

One more thing - you can use WiFi direct if your phone and device support this protocol via WifiP2pManager. I will not stop on this point too much because it is quite device specific one.

The last but not least - you can create a "graceful fall" flow. It means that in case of described situation you will be ready for it - create a flow in your app that navigates your user through manual solution of the issue. I believe it would be the most correct way there is also. But in the same time it is the most user unfriendly one. (I used this approach in my app - I asked user to forget the spot manually and rescan one more time inside the app...(lame I know))

Sorry for the long-winded answer, based on assumptions rather than on actual data and without a concrete solution, but I hope it will help you somehow...

like image 125
Pavlo Ostasha Avatar answered Oct 04 '22 02:10

Pavlo Ostasha