Фон
Я заметил, что в 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 , но совсем не похоже, что речь идет о добавлении сети:
СетьОбъект предложения используется для предоставления сети Wi-Fi для рассмотрения при автоматическом подключении к сетям.Приложения не могут напрямую создавать этот объект, они должны использовать WifiNetworkSuggestion.Builder # build () для получения экземпляра этого объекта.
Приложения могут предоставить список таких сетей платформе с помощью WifiManager # addNetworkSuggestions (List).
Вот мой текущий код для версии до 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")
}
Во время работы (я сообщил подробности своей сети Wifi, после того как ОС забыла об этом), он говорит:удалось, но ничего не произошло в настройках Wi-Fi ОС.Сеть там не существует с паролем, который я добавил.Так что я действительно не понимаю, что он сделал ...
Через несколько долгих секунд я заметил уведомление, спрашивающее меня, можно ли подключиться к предлагаемым сетям, сделанным приложением:
Но все же, когда я выбрал это, я ничего не делал, как раньше.
Я пытался сделать еще один POC,думая, что я мог сделать это неправильно, но тогда он даже не показывал уведомление.Поскольку я думаю, что все это поведение является ошибкой, я сообщил об этом здесь .
Не только это, но я обнаружил, что если это действительно такПредполагается, что сеть будет добавлена тем или иным способом, но у нее все еще есть некоторые серьезные ограничения, такие как максимальное количество добавленных сетей ( здесь ) и удаление при удалении приложения ( здесь )
Вопросы
Каким образом должен обрабатываться Android Q?Неужели больше нет API для добавления сети?
Если WifiNetworkSuggestion
не относится к добавлению сети, для чего конкретно она используется?
Поскольку я недостаточно знаком с тонкостями добавления сети, правильный ли мой код относительно всех возможных способов добавления сети?Я спрашиваю об этом, потому что кто-то написал здесь , что люди должны включить Wi-Fi и убедиться, что pingSupplicant
возвращает true.Это правда?Или было бы достаточно просто позвонить addNetwork
?
Если теперь невозможно добавить сеть с помощью обычного API, возможно, есть решение с использованием взамен корневого устройства?Может быть, какая-то команда adb?