我正在开发Wifi自动连接功能,但惊奇地发现API存在严重问题。
我现在使用了5个不同的API,但仍无法按照用户期望的方式实现。
我有一个设置项可以在Android 10+上启用Wifi自动连接,我将尝试使用它:
- 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
总结一下:
- 我使用了
WifiNetworkSuggestion
API - 尽可能使用
Settings.ACTION_WIFI_ADD_NETWORKS
作为备选方案 - 我尝试验证用户当前连接的是正确的wifi
- 我尝试使用
Settings.Panel.ACTION_WIFI
操作来帮助用户连接到正确的wifi(甚至打开wifi)
这真的很混乱吗?还是有更简单的方法?
我目前是这样访问SSID的:
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
}
根据 Unable to get WIFI SSID using onCapabilitiesChanged in Android 12,我认为我访问该值的方式不受支持。目前我得到的值是"<unknown ssid>"
。
ACCESS_WIFI_STATE
是一个普通
权限,自Android 1.0以来就存在。除了已经root的设备或者疯狂的ROM之外,如果你的应用程序已经安装并运行,你就拥有这个权限。你是否看到其他情况? - CommonsWareACCESS_FINE_LOCATION
返回。请注意,根据情况,您可能会得到SSID的null
值,特别是如果您正在连接一个没有互联网访问权限且用户尚未接受通知的网络。一旦他们接受了通知,您应该就能获取到SSID了。 - CommonsWareACCESS_WIFI_STATE
权限检查,请查看此错误:https://issuetracker.google.com/issues/224071894。似乎当您按“不,谢谢”时,该权限会被撤销(更改方法也在那里记录)。 - rekire"<unknown ssid>"
。请参见无法在Android 12中使用onCapabilitiesChanged获取WIFI SSID,我认为我访问该值的方式不受支持。现在我将尝试使用那个标志来广播接收器。 - rekirenull
——自从我上次探索这种情况以来已经有一段时间了。我知道在用户接受该通知之前有一个中间值。然而,我没有在回调中使用onCapabilitiesChanged()
;也许getNetworkCapabilities()
的行为有所不同。 - CommonsWare