I'm working on a Wifi auto connect feature and I am shocked how broken that API is.
I'm using now 5 different APIs and I still don't get it in a way the user would expect it.
I have a setting to enable wifi auto connection on Android 10+ I'll try this:
- Check if I hold the
ACCESS_WIFI_STATE
permission with:
When I own the permission I go on with 2. if not I continue with 6.appOpsManager.unsafeCheckOp("android:change_wifi_state", Process.myUid(), context.packageName) == AppOpsManager.MODE_ALLOWED
- When I hold the permission I'll check on Android 11+ if from a previous run my wifi suggestion was saved
wifiManager.networkSuggestions.isNotEmpty()
if that is true I check which Wifi I'm currently connected with see step x. On lower levels I skip this and go to step 3 - I use the wifi suggestion API with the
WifiNetworkSuggestion.Builder()
and suggest the user my wifi withval status = wifiManager.addNetworkSuggestions(listOf(suggestion)) // Strage bug: On first usage the return value is always SUCCESS val success = status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS
- When the user accepts my suggestion I'm fine so far. I cannot verify on Android 10 if my suggestion was accepted. On Android 11 this is possible (see step 2). However I still don't know if the device actually connected with the wifi. So I go to step 7
- When the user rejected my suggestion I'm almost out of the game I can never ask the user again (well technically there is a well hidden feature where you can switch the permission, but no user will ever find it). On Android 10 I can just check if I'm connected with the right wifi, well at least theoretically (see step 7).
- On Android 11+ I can fallback to the
Settings.ACTION_WIFI_ADD_NETWORKS
intent which can always add Wifis (with the downside that the user can share the wifi password) - I need to verify if the steps before worked and the user is actually connected to the desired wifi. To do so I already own the permissions
ACCESS_WIFI_STATE
,ACCESS_NETWORK_STATE
,ACCESS_COARSE_LOCATION
andACCESS_FINE_LOCATION
. However theConnectivityManager
API don't return the actualSSID
, that drives me crazy. - If the user is not connected to the right wifi I would try to use the
Settings.Panel.ACTION_WIFI
action to let the user to connect to the right wifi
To summarize that:
- I use the
WifiNetworkSuggestion
API - I fallback to
Settings.ACTION_WIFI_ADD_NETWORKS
where possible - I try to verify if the user is currently connected to the right wifi
- I try to assist the user to conenct to the right wifi (or even turn wifi on) with the
Settings.Panel.ACTION_WIFI
action
Is that really such a mess or is there a easier way?
I'm currently accessing the SSID like this:
private val currentSsid: String?
get() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val wifiInfo = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)?.transportInfo as? WifiInfo
wifiInfo?.ssid
} else {
wifiManager.connectionInfo?.ssid
}
Based on Unable to get WIFI SSID using onCapabilitiesChanged in Android 12 I think that way I access the value is not supported. I get currently the value "<unknown ssid>"
.