Можно ли добавить конфигурацию сети на Android Q? - PullRequest
3 голосов
/ 05 июля 2019

Фон

Я заметил, что в 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 ОС.Сеть там не существует с паролем, который я добавил.Так что я действительно не понимаю, что он сделал ...

Через несколько долгих секунд я заметил уведомление, спрашивающее меня, можно ли подключиться к предлагаемым сетям, сделанным приложением:

enter image description here

Но все же, когда я выбрал это, я ничего не делал, как раньше.

Я пытался сделать еще один POC,думая, что я мог сделать это неправильно, но тогда он даже не показывал уведомление.Поскольку я думаю, что все это поведение является ошибкой, я сообщил об этом здесь .

Не только это, но я обнаружил, что если это действительно такПредполагается, что сеть будет добавлена ​​тем или иным способом, но у нее все еще есть некоторые серьезные ограничения, такие как максимальное количество добавленных сетей ( здесь ) и удаление при удалении приложения ( здесь )

Вопросы

  1. Каким образом должен обрабатываться Android Q?Неужели больше нет API для добавления сети?

  2. Если WifiNetworkSuggestion не относится к добавлению сети, для чего конкретно она используется?

  3. Поскольку я недостаточно знаком с тонкостями добавления сети, правильный ли мой код относительно всех возможных способов добавления сети?Я спрашиваю об этом, потому что кто-то написал здесь , что люди должны включить Wi-Fi и убедиться, что pingSupplicant возвращает true.Это правда?Или было бы достаточно просто позвонить addNetwork?

  4. Если теперь невозможно добавить сеть с помощью обычного API, возможно, есть решение с использованием взамен корневого устройства?Может быть, какая-то команда adb?

...