我正在开发一种用户必须遵循以下步骤的应用程序:
当用户连接到连接对象的专用热点时,应用程序会执行一些HTTP请求以对其进行配置。然后,我想自动将应用程序重新连接到步骤1的全局wifi。
从API 21到API 28,此功能非常易于实现,因为我知道要将手机重新连接到的SSID。只需几行代码即可完成:
private fun changeCurrentWifiNetworkLegacy(ssidToConnect: String) {
val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
var ssidIdentifier: Int? = null
wifiManager.configuredNetworks?.forEach { config ->
Log.d("SSID", config.SSID)
if (config.SSID == "\"${ssidToConnect}\"") {
ssidIdentifier = config.networkId
}
}
ssidIdentifier?.let { id ->
wifiManager.enableNetwork(id, true)
}
}
在API 29上,根据本文https://developer.android.com/about/versions/10/privacy/changes#configure-wifi
,此简单代码不再起作用根据这篇文章,现在,我应该使用2个类:WifiNetworkSpecifier
和/或WifiNetworkSuggestion
。
不幸的是,我找不到使用这些类的有效示例,以将用户连接到先前配置的SSID。
有人已经实现了吗?
预先感谢您的帮助。
答案 0 :(得分:2)
只要万一有可怜的人遇到这种情况,API很有可能只是在您的设备上被破坏了。在我的OnePlus 5,Android 10,Build 200513上,会发生这种情况:
为此创建了一个Android错误:https://issuetracker.google.com/issues/158344328
此外,如果您没有以正确的顺序终止应用程序和对话框,并且仅重新启动,则可以使操作系统进入不再显示“要使用的设备”对话框的状态。
只需为自己省事,以Android 9为目标,然后使用WifiManager API(如果以10为目标,则很有用)。与新的requestNetwork API相比,它甚至具有更好的用户体验。
答案 1 :(得分:0)
您可以使用以下代码设置要连接的网络:
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(
WifiNetworkSpecifier.Builder()
.setSsid("My ssid")
.build()
)
.build()
cm.requestNetwork(networkRequest, object: ConnectivityManager.NetworkCallback() {
override fun onUnavailable() {
Log.d("TEST", "Network unavailable")
}
override fun onAvailable(network: Network) {
Log.d("TEST", "Network available")
}
})
}
这使用ConnectivityManager的networkRequest方法来请求具有特定SSID的网络。
此方法要求调用者拥有Manifest.permission.CHANGE_NETWORK_STATE
所拥有的Settings.System.canWrite(Context)
权限或修改系统设置的能力。
请参阅NetworkCallback类以获取有关可以获取哪些信息的更多文档。
(编辑:未添加传输类型。)
进一步编辑:我需要使用.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
使其正常工作。因为在WifiNetworkSpecifier
只能用于请求本地wifi网络(即没有互联网 能力)
根据the docs
这给了我一个弹出设备的请求,但随后最终向我显示了我要求的Wifi网络。
答案 2 :(得分:0)
我尝试了很多代码,包括 WifiManager.addNetworkSuggestions
和 ConnectivityManager.requestNetwork
。最后我发现,只需调用 ConnectivityManager.unregisterNetworkCallback
即可恢复用户 wifi 连接。这个代码唯一让我不满意的地方,如果用户保存了WiFi A和WiFi B,那么系统会自动选择一个连接,而不是我指定的。