【发布时间】:2019-11-16 06:13:03
【问题描述】:
背景
我注意到在WifiManager 类中有一个名为addNetwork 的函数,如果我想恢复或保存网络信息(网络名称AKA SSID,以及密码和类型),它可能很有用,这样我也可以连接到它。
问题
我找不到太多关于如何做这样的事情的信息。我在 StackOverflow 上看到过各种示例,如果我以 Android API 28(或更低版本)为目标,我确实成功地使它添加了网络,甚至连接到它。
但是,当面向 Android 29 (Android Q) 时,它无法添加网络。
我发现了什么
由于我正在使用 Android Q beta 4 尝试 Pixel 2,我认为这可能是因为 addNetwork 已被弃用,所以文档甚至这么说,如果我以 Android Q 为目标,它将无法工作,实际上它不起作用:
兼容性说明:适用于面向 Build.VERSION_CODES.Q 的应用程序 或以上,此 API 将始终返回 -1。
在Android Q(不包括)之前它似乎应该工作的方式是准备WifiConfiguration并添加它。以后如果我愿意,我也可以连接到它。在 Android Q 上,它似乎被WifiNetworkSuggestion 取代,但似乎根本不是要添加网络:
Network Suggestion 对象用于为以下用户提供 Wi-Fi 网络 自动连接到网络时的考虑。应用程序不能直接 创建这个对象,他们必须使用 WifiNetworkSuggestion.Builder#build() 获取此实例 对象。
应用可以使用以下方式向平台提供此类网络的列表 WifiManager#addNetworkSuggestions(List)。
这是我当前的代码,适用于 pre-Android-Q
@WorkerThread
fun addNetwork(context: Context, networkName: String, networkPassword: String? = null, keyMgmt: Int = WifiConfiguration.KeyMgmt.NONE) {
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
val conf = WifiConfiguration()
conf.SSID = "\"$networkName\""
conf.preSharedKey = if (networkPassword.isNullOrEmpty()) "" else "\"$networkPassword\""
conf.allowedKeyManagement.set(keyMgmt)
when (keyMgmt) {
WifiConfiguration.KeyMgmt.WPA_PSK -> {
//WPA/WPA2
}
WifiConfiguration.KeyMgmt.IEEE8021X -> {
}
WifiConfiguration.KeyMgmt.WPA_EAP -> {
}
WifiConfiguration.KeyMgmt.NONE -> {
if (networkPassword.isNullOrEmpty()) {
//open network
conf.wepKeys[0] = "\"\""
} else {
//wep
conf.wepKeys[0] = "\"" + networkPassword + "\""
conf.wepTxKeyIndex = 0
conf.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40)
}
}
}
if (networkPassword.isNullOrEmpty()) {
//open network
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
} else {
}
wifiManager.isWifiEnabled = true
while (!wifiManager.pingSupplicant()) {
Log.d("AppLog", "waiting to be able to add network")
}
val networkId = wifiManager.addNetwork(conf)
if (networkId == -1)
Log.d("AppLog", "failed to add network")
else {
wifiManager.enableNetwork(networkId, false)
Log.d("AppLog", "success to add network")
}
}
似乎只需要这些权限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
但无论如何,只要您不以 Android Q (API 29) 及更高版本为目标,这将有效。当你瞄准它时,我确实总是得到“-1”,这意味着它失败了。
我还在问题跟踪器上发现了一个问题(here,我写了关于它here),告诉有人需要返回 API,但我不确定它是否与添加网络有关。
查看WifiNetworkSuggestion,我没有看到它可以通过其构建器设置与WifiConfiguration 一样多的东西,所以这是我怀疑它与添加网络无关的另一个原因。
但我还是试过了。这是我尝试过的代码,例如,添加一个普通的 WPA 网络:
@WorkerThread
fun addNetworkAndroidQ(context: Context, networkName: String, networkPassword: String? = null) {
val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager
val list = ArrayList<WifiNetworkSuggestion>()
val builder = WifiNetworkSuggestion.Builder().setSsid(networkName)
if (!networkPassword.isNullOrEmpty())
builder.setWpa2Passphrase(networkPassword)
list.add(builder.build())
val result = wifiManager.addNetworkSuggestions(list)
if (result == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS)
Log.d("AppLog", "success")
else Log.d("AppLog", "failed")
}
运行时(在让操作系统忘记它之后,我给了它我的 Wifi 网络详细信息),它说它成功了,但操作系统的 Wifi 设置上没有发生任何事情。使用我添加的密码的网络不存在。所以我真的不明白它做了什么......
几秒钟后,我注意到一条通知,询问我是否可以连接到应用创建的建议网络:
但是当我选择接受时,它什么也没做,和以前一样。
我尝试制作另一个 POC,以为我可能做错了,但后来它甚至没有显示通知。由于我认为这整个行为是一个错误,我已经报告了它here。
不仅如此,我还发现,如果它确实应该以某种方式添加网络,它仍然有一些严重的限制,例如最大添加网络 (here) 并在卸载时被删除应用程序 (here)
问题
究竟应该如何处理Android Q?真的没有API来添加网络了吗?
如果
WifiNetworkSuggestion不是关于添加网络,那么它到底是用来做什么的?由于我对添加网络的花絮不够熟悉,我的代码对于添加网络的所有可能方式是否正确?我问这个是因为有人写了here 说人们应该启用 Wifi 并确保
pingSupplicant返回 true。这是真的吗?还是打电话给addNetwork就够了?如果现在无法使用普通 API 添加网络,是否可以使用根设备代替解决方案?也许是一些 adb 命令?
编辑:不确定如何正式执行,但使用 adb,您 might be able 在 Android 11 上添加 Wifi-networks 。需要检查adb shell cmd wifi help。
【问题讨论】:
-
这个有什么更新吗?我遇到了同样的问题,并且我看到一些针对 API 29 的应用程序连接到其 wifi 配置而没有此类通知/提示。
-
@AswinPAshok 根据我的阅读,Google 计划在 Android R 上为这个 API 提供更多的灵活性。可能允许将其设置为永久(在应用删除后保留)。
-
你能看一下这张图片吗:imgur.com/cdv3fHR,在这个提示之后,一些应用可以连接到他们的wifi配置。这个意图可能是什么?对不起,我很愚蠢。
-
@AswinPAshok 我不知道。我建议提出一个新问题。我只是出于好奇而测试了这个 API,因为我想在第三方应用程序上拥有这个功能:)
-
@androiddeveloper 如何设置代理选项,例如主机名和代理端口?和 IP 设置?
标签: android android-wifi wifimanager android-10.0