Android 10 / API 29: как подключить телефон к настроенной сети? - PullRequest
0 голосов
/ 08 ноября 2019

Я работаю над приложением, в котором пользователь должен выполнить следующие действия:

  1. подключить телефон к Wi-Fi;
  2. подключить телефон к выделенной точке доступа изподключенный объект.

Когда пользователь подключен к выделенной точке доступа подключенного объекта, приложение выполняет некоторые HTTP-запросы для его настройки. Затем я хотел бы автоматически повторно подключить приложение к глобальному Wi-Fi шага 1.

От 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.

Кто-то уже достиг этого?

Заранее благодарен за помощь.

1 Ответ

0 голосов
/ 08 ноября 2019

Вы можете указать, к какой сети подключаться, используя следующий код:

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

можно использовать только для запроса локальной сети Wi-Fi (т. Е. Без возможности подключения к Интернету)

В соответствии с документами

Это дает мне запрос на всплывающее окно с устройствами, но затем, в конце концов, показывает мне сеть Wifi, о которой я просил.

...