Фон
Я заметил, что в классе WifiManager есть функция под названием addNetwork, который может быть полезен, если я хочу восстановить или сохранить информацию о сети (имя сети AKA SSID, вместе с паролем и типом), чтобы я также мог подключиться к ней.
Эта проблема
Я не могу найти много информации о том, как это сделать. Я видел различные примеры в StackOverflow, и если я нацелен на Android API 28 (или ниже), мне действительно удается добавить сеть и даже подключиться к ней.
Однако при ориентации на Android 29 (Android Q) не удается добавить сеть.
Что я нашел
Поскольку я пытаюсь использовать Pixel 2 с Android Q beta 4, я думаю, что, возможно, это потому, что addNetwork
устарел, поэтому в документации даже сказано, и что если я нацелен на Android Q, это не сработает, и действительно, это не так ' т работать:
Примечание о совместимости: для приложений, предназначенных для Build.VERSION_CODES.Q или выше, этот API всегда будет возвращать -1.
Кажется, что это должно работать до Android Q (исключая), - это подготовить WifiConfiguration
и добавить его. Позже я тоже могу к нему подключиться, если захочу. В Android Q кажется, что он был заменен на WifiNetworkSuggestion strong >, но похоже, что речь идет не о добавлении сети:
Объект «Предложение сети» используется для предоставления сети 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», что означает, что он терпит неудачу.
Я также обнаружил проблему в системе отслеживания проблем (здесь и Я писал об этом здесь), рассказывая о том, кому нужен 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")
}
При запуске (я дал ему данные о своей сети Wi-Fi, после того, как ОС забыла об этом), он говорит, что это удалось, но в настройках Wi-Fi ОС ничего не произошло. Там нет сети с добавленным мной паролем. Так что я действительно не понимаю, что он сделал ...
Через несколько долгих секунд я заметил уведомление, спрашивающее меня, можно ли подключиться к предлагаемым сетям, созданным приложением:
Но все же, когда я выбрал то, что принимаю, ничего не произошло, как раньше.
Я попытался сделать еще один POC, подумав, что, возможно, сделал это неправильно, но тогда он даже не показывал уведомление. Поскольку я считаю, что все это поведение является ошибкой, я сообщил об этом здесь < / а>.
Более того, я обнаружил, что, если действительно предполагается добавить сеть тем или иным способом, у нее все еще есть некоторые серьезные ограничения, такие как максимальное количество добавленных сетей ( здесь) и удаляется при удалении приложения ( здесь)
Вопросы
Как именно следует обращаться с Android Q? Неужели больше нет API для добавления сети?
Если
WifiNetworkSuggestion
не о добавлении сети, то для чего она на самом деле используется?Поскольку я недостаточно знаком с лакомыми кусочками добавления сети, верен ли мой код в отношении всех возможных способов добавления сети? Я спрашиваю об этом, потому что кто-то написал здесь, что люди должны включить Wi-Fi и убедиться, что
pingSupplicant
возвращает true. Это правда? Или достаточно просто позвонитьaddNetwork
?Если сейчас невозможно добавить сеть с помощью обычного API, есть ли решение, используя вместо этого рутированное устройство? Может какая-то команда adb?
РЕДАКТИРОВАТЬ: не знаю, как это сделать официально, но используя adb, вы могли бы добавить Wifi-сети на Android 11. Нужно проверить adb shell cmd wifi help
.