Android 6.0.1 заставляет Wi-Fi соединение без доступа в Интернет

у этого есть много подобных вопросов (google для: "не обнаружен интернет-доступ. не будет автоматически повторно подключаться".: или: соединение с Wi-Fi силой wili программно).

Я думал, что у меня был ответ здесь, но он прекратил работу после установки обновлений 6.0.1 (у меня есть 1 патчи безопасности).

похоже, что это изменение .

У меня есть некоторая нексуса 2013 2013 года с 6.0.1, которая запускает приложение типа киоска и хочет программно подключиться к конкретной беспроводной сети, у которой нет подключения к Интернету. каждая таблетка имеет уникальный статический IP-адрес формы: 192.168.0.xx. Я использую обычные конструкторы сокетов java и проверяю, работает ли интерфейс: NetworkInterface.getNetworkInterfaces().

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

но Wi-Fi говорит: "Неизвестный интернет-доступ не будет автоматически подключаться" после питания маршрутизатора.

выполнение отключения, включения, повторного подключения не работает. в лучшем случае он получает: ip6-localhost/:: 1.

Кому-нибудь удавалось использовать объект запроса или bindProcessToNetwork?

edit: .

edit: проблема, похоже, связана с: CAPTIVE_PORTAL_DETECTION_ENABLED - эта строка, по-видимому, определена в источнике:

public static final String
        CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
    ...
    MOVED_TO_GLOBAL.add(Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED);

но бросает "android.provider.Settings $SettingNotFoundException: captive_portal_detection_enabled при явном использовании и не отображается в студии android.

также, если список настроек global не содержит константу.

edit Выполнение настроек оболочки adb put global captive_portal_detection_enabled 0 похоже на работу, но это невозможно сделать в поле, когда маршрутизатор запускает питание. это значение, по-видимому, сохраняется, когда питание планшета. и теперь это значение отображается в списке настроек global. также, используя необработанную строку: Settings.Global.getInt(getContentResolver(), "captive_portal_detection_enabled" ); теперь возвращает 0.

edit: похоже, что для его установки требуется: android.permission.WRITE_SECURE_SETTINGS, но, конечно, это не удается, если вы помещаете в манифест, так как мы не являемся системным приложением.

edit: пытается выполнить команду командной строки throw: java.lang.SecurityException, поэтому похоже, что вам нужно выдать команду из adb: (

спасибо

Ответ 1

Не удалось установить глобальный параметр captive_portal_detection_enabled в значение 0 (false).

Что на самом деле происходит, так это то, что по умолчанию каждый раз, когда вы подключаетесь к Wi-Fi, FW будет протестировать сервер (как правило, google), чтобы увидеть, является ли он доступным wifi (требуется логин). Поэтому, если ваш Wi-Fi не подключен к Google, эта проверка завершится с ошибкой. После этого устройство знает, что Wi-Fi не имеет подключения к интернету и просто не будет автоподключиться к нему.

Установка этого параметра в 0, позволит избежать этой проверки.

Программно Settings.Global.putInt(getContentResolver(), Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 0);

Вы можете сделать это через adb для тестирования:

adb shell settings put global captive_portal_detection_enabled 0

И получить его значение следующим образом:

adb shell settings list global | grep "captive"

IMHO это не очень приятно делать, так как вы меняете настройку для пользователя, и многие FW не предоставляют даже расширенные настройки для включения/выключения этого самим пользователем. (Google не делает). Но, возможно, это соответствует вашим потребностям.

Надеюсь, что это поможет!

Ответ 2

Решение, отличное от root, которое является своего рода хак-технологией.: P

  • Перезагрузите телефон, подключитесь к интернету без Интернета;
  • Перейдите в раздел "Настройки" и создайте нового пользователя;
  • Продолжайте, продолжайте и продолжайте, пока не увидите "Проверка соединения";
  • Как только вы увидите "проверку соединения", выключите телефон;
  • Включите телефон снова, вы будете в "Владелец", сохраните его,
  • Переключить Wifi, и восклицательный знак должен быстро исчезнуть:)
  • Удалите этого нового пользователя или просто оставьте его там;

Я не знаю почему, но он работает...

Ответ 3

Решение по Котлину

class ConnectWithoutInternetTest constructor(
private val mContext: Context,
private val connectivityManager: ConnectivityManager,
private val wifiManager: WifiManager
) {

private val mWifiBroadcastReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        when (intent.action) {
            WifiManager.NETWORK_STATE_CHANGED_ACTION -> {
                val info = intent.getParcelableExtra<NetworkInfo>(WifiManager.EXTRA_NETWORK_INFO)
                val isConnected = info.isConnected

                val ssid: String? = normalizeAndroidWifiSsid(wifiManager.connectionInfo?.ssid)

                if (isConnected) {
                    val builder = NetworkRequest.Builder()
                    builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    connectivityManager.registerNetworkCallback(
                        builder.build(),
                        object : ConnectivityManager.NetworkCallback() {
                            override fun onAvailable(network: Network) {
                                super.onAvailable(network)
                                val networkInfo = connectivityManager.getNetworkInfo(network)
                                val networkSsid = networkInfo.extraInfo
                                if (networkSsid == ssid) {
                                    connectivityManager.unregisterNetworkCallback(this)
                                }
                            }
                        })
                }
            }
        }
    }
}

private fun init() {
    val intentFilter = IntentFilter()
    intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION)
    mContext.registerReceiver(mWifiBroadcastReceiver, intentFilter)
}

private fun destroy() {
    mContext.unregisterReceiver(mWifiBroadcastReceiver)
}

private fun normalizeAndroidWifiSsid(ssid: String?): String? {
    return ssid?.replace("\"", "") ?: ssid
}

fun connectToWifi(ssidParam: String, password: String?) {
    init()
    val ssid = "\"$ssidParam\""
    val config = wifiManager.configuredNetworks.find { it.SSID == ssid }
    val netId = if (config != null) {
        config.networkId
    } else {
        val wifiConfig = WifiConfiguration()
        wifiConfig.SSID = ssid
        password?.let { wifiConfig.preSharedKey = "\"$password\"" }
        wifiConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
        wifiManager.addNetwork(wifiConfig)
    }

    wifiManager.disconnect()
    val successful = wifiManager.enableNetwork(netId, true)
}

Ответ 4

Работал на меня, спасибо. Nexus 5 с андроидом 6.0.1