Android 9 在没有互联网连接的情况下连接到 Wifi
Android 9 Connect to Wifi without internet connection
我为 Android 9 编写了一个 Android 应用程序,它向用户显示可用 wifi 网络列表并让用户连接到它们。连接到提供互联网连接的网络工作正常。但在大多数情况下,我必须在没有互联网连接的情况下连接到网络。对于我的项目,我必须在 linux 机器上创建自己的访问权限 points/hotspots,因此希望我的应用能够连接到它。
如果我选择我创建的网络之一,我将重新连接到已知且已配置的 wifi,我的设备知道它提供互联网连接(例如我们的办公室 wifi)。
我已经详细了解了 Whosebug,但大多数遇到此问题的人似乎都在使用 Android Marshmallow 或 Lollipop,实际上他们的设备正在使用移动数据 send/receive 连接到非互联网 wifi 时的数据。
AFAIK Android 可能会拒绝不提供互联网接入的 wifi 网络。我怎样才能告诉系统连接到它们呢?通过设置应用程序连接到这些网络工作正常。它在我的应用程序中不起作用。
到目前为止,这是我的连接代码:
private fun connectToSelectedNetwork(networkSSID: String){
try {
val conf = WifiConfiguration()
conf.SSID = "\"" + networkSSID + "\""
conf.preSharedKey = "\"" + PASSPHRASE + "\""
val network = wifiManager?.addNetwork(conf)
wifiManager?.disconnect()
wifiManager?.enableNetwork(network!!, true)
wifiManager?.reconnect()
} catch (ex: Exception) {
println(Arrays.toString(ex.stackTrace))
}
}
谢谢!
对于可能遇到相同问题的任何人,以下是我的解决方法:
为了确保您的设备不会重新连接到您上次连接的 wifi 网络,只需在尝试连接到新的(可能 non-internet 可用之前禁用当前连接的网络) 无线网络。此外,我首先检查我要连接的网络是否已为设备所知,这使我们无需创建新的 wifi 配置。
但有时,连接到网络可能需要一分钟以上的时间。老实说,我不知道为什么,但我也找到了解决方法。
每当我尝试使用上述解决方案连接到新网络时,我都会启动一个计时器,该计时器会在一段时间后超时(在我的例子中是 5 秒)。一旦连接建立成功,我就会停止计时器。但是如果在超时后还没有建立连接,我只是重试连接到我想要的网络。
在大多数情况下 (>95%),连接会在 <10 秒内成功。
这是我的工作代码:
private lateinit var timeoutCoroutine: Job
private fun connectToSelectedNetwork(SSID: String) {
// Figure out if the network is known to the device and in this case connect to it
if (!connectToKnownNetwork(SSID)){
// If the network is unknown, we first have to configure it before connecting
val network = configureNetwork(SSID)
connect(network)
}
startConnectionEstablishmentTimeoutCoroutine(SSID)
}
private fun connectToKnownNetwork(SSID: String): Boolean {
for (c in wifiManager.configuredNetworks) {
if (SSID == c.SSID.removeSurrounding("\"")){
if (connect(c.networkId)){
return true
}
}
}
return false
}
private fun configureNetwork(SSID: String): Int {
val conf = WifiConfiguration()
conf.SSID = "\"" + SSID + "\""
conf.preSharedKey = "\"" + PASSPHRASE + "\""
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
return wifiManager.addNetwork(conf)
}
private fun connect(network: Int): Boolean {
wifiManager.disableNetwork(wifiManager.connectionInfo.networkId)
wifiManager.disconnect()
val success = wifiManager.enableNetwork(network, true)
wifiManager.reconnect()
wifiManager.reassociate()
return success
}
// For unknown reasons connecting to a network takes up to a minute when the user has not
// interacted with the device for a while (>~15 seconds).
// To prevent this we set a timeout after which the connection establishment shall be retried.
private fun startConnectionEstablishmentTimeoutCoroutine(SSID: String){
timeoutCoroutine = CoroutineScope(IO).launch {
delay(CONNECTION_ESTABLISHMENT_TIMEOUT)
connectToNetwork(SSID)
}
}
我为 Android 9 编写了一个 Android 应用程序,它向用户显示可用 wifi 网络列表并让用户连接到它们。连接到提供互联网连接的网络工作正常。但在大多数情况下,我必须在没有互联网连接的情况下连接到网络。对于我的项目,我必须在 linux 机器上创建自己的访问权限 points/hotspots,因此希望我的应用能够连接到它。
如果我选择我创建的网络之一,我将重新连接到已知且已配置的 wifi,我的设备知道它提供互联网连接(例如我们的办公室 wifi)。
我已经详细了解了 Whosebug,但大多数遇到此问题的人似乎都在使用 Android Marshmallow 或 Lollipop,实际上他们的设备正在使用移动数据 send/receive 连接到非互联网 wifi 时的数据。
AFAIK Android 可能会拒绝不提供互联网接入的 wifi 网络。我怎样才能告诉系统连接到它们呢?通过设置应用程序连接到这些网络工作正常。它在我的应用程序中不起作用。
到目前为止,这是我的连接代码:
private fun connectToSelectedNetwork(networkSSID: String){
try {
val conf = WifiConfiguration()
conf.SSID = "\"" + networkSSID + "\""
conf.preSharedKey = "\"" + PASSPHRASE + "\""
val network = wifiManager?.addNetwork(conf)
wifiManager?.disconnect()
wifiManager?.enableNetwork(network!!, true)
wifiManager?.reconnect()
} catch (ex: Exception) {
println(Arrays.toString(ex.stackTrace))
}
}
谢谢!
对于可能遇到相同问题的任何人,以下是我的解决方法:
为了确保您的设备不会重新连接到您上次连接的 wifi 网络,只需在尝试连接到新的(可能 non-internet 可用之前禁用当前连接的网络) 无线网络。此外,我首先检查我要连接的网络是否已为设备所知,这使我们无需创建新的 wifi 配置。
但有时,连接到网络可能需要一分钟以上的时间。老实说,我不知道为什么,但我也找到了解决方法。 每当我尝试使用上述解决方案连接到新网络时,我都会启动一个计时器,该计时器会在一段时间后超时(在我的例子中是 5 秒)。一旦连接建立成功,我就会停止计时器。但是如果在超时后还没有建立连接,我只是重试连接到我想要的网络。 在大多数情况下 (>95%),连接会在 <10 秒内成功。
这是我的工作代码:
private lateinit var timeoutCoroutine: Job
private fun connectToSelectedNetwork(SSID: String) {
// Figure out if the network is known to the device and in this case connect to it
if (!connectToKnownNetwork(SSID)){
// If the network is unknown, we first have to configure it before connecting
val network = configureNetwork(SSID)
connect(network)
}
startConnectionEstablishmentTimeoutCoroutine(SSID)
}
private fun connectToKnownNetwork(SSID: String): Boolean {
for (c in wifiManager.configuredNetworks) {
if (SSID == c.SSID.removeSurrounding("\"")){
if (connect(c.networkId)){
return true
}
}
}
return false
}
private fun configureNetwork(SSID: String): Int {
val conf = WifiConfiguration()
conf.SSID = "\"" + SSID + "\""
conf.preSharedKey = "\"" + PASSPHRASE + "\""
conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
return wifiManager.addNetwork(conf)
}
private fun connect(network: Int): Boolean {
wifiManager.disableNetwork(wifiManager.connectionInfo.networkId)
wifiManager.disconnect()
val success = wifiManager.enableNetwork(network, true)
wifiManager.reconnect()
wifiManager.reassociate()
return success
}
// For unknown reasons connecting to a network takes up to a minute when the user has not
// interacted with the device for a while (>~15 seconds).
// To prevent this we set a timeout after which the connection establishment shall be retried.
private fun startConnectionEstablishmentTimeoutCoroutine(SSID: String){
timeoutCoroutine = CoroutineScope(IO).launch {
delay(CONNECTION_ESTABLISHMENT_TIMEOUT)
connectToNetwork(SSID)
}
}