首页 > 解决方案 > Android Q、R 中的 WiFiManager API

问题描述

我正在编写一个示例应用程序,它正在扫描可用的 wifis 并以编程方式连接到它们

对于该建议,我使用的是WiFiManager,但最近 Google 弃用了大多数允许扫描 WiFi 并以编程方式连接到它们的方法。是的,从谷歌的角度来看,不允许任何人尝试以编程方式连接到任何 WiFi 似乎是合乎逻辑的。但我的问题将随之而来

在新的 API 中,我找到了一种建议用户连接到 WiFi 的方法

wifiManager.addNetworkSuggestions(listOf(WifiNetworkSuggestion
                   .Builder()
                   .setSsid("testWiFi")
                   .setWpa2Passphrase("test1234")
                   .build()))

但这真的无法预测,当我第一次运行我的所有并调用此方法时,在 Android Q 上显示通知,在 Android R 上显示对话框询问用户是否允许在应用程序以某种方式连接时连接到 WiFi-s到 WiFi 但之后为另一个 WiFi 调用相同的函数什么都不做,并且应用程序不再显示任何蚂蚁通知或对话框(这是一个错误吗?)

我也试过requestNetwoerk方法

val specifier = WifiNetworkSpecifier
        .Builder()
        .setSsid("testWiFi")
        .setBssid(MacAddress.fromString("testWiFiMac"))
        .build()

val request = NetworkRequest
        .Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        .setNetworkSpecifier(specifier)
        .build()

connectivityManager.requestNetwork(request, networkCallback)

但在这种情况下,是否可以连接到受密码保护的 WiFi,以及如果可以,如何连接还不是很清楚。

因此,如果有一些示例或解释,请告诉我。

标签: androidwifiandroid-10.0

解决方案


即使开始扫描已被弃用,谷歌仍然建议使用它。

这里的三个步骤是:

  1. 为 SCAN_RESULTS_AVAILABLE_ACTION 注册一个广播接收器。
  2. 使用 WifiManager.startScan() 请求扫描
  3. 使用 WifiManager.getScanResults() 获取扫描结果。请注意,如果您在接收广播结果之前使用这些扫描结果,则这些结果可能比以前的扫描结果要旧一些。

示例代码可能如下所示:

val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager

val wifiScanReceiver = object : BroadcastReceiver() {

  override fun onReceive(context: Context, intent: Intent) {
    val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
    if (success) {
      scanSuccess()
    } else {
      scanFailure()
    }
  }
}

val intentFilter = IntentFilter()
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)

val success = wifiManager.startScan()
if (!success) {
  // scan failure handling
  scanFailure()
}

....

private fun scanSuccess() {
  val results = wifiManager.scanResults
  ... use new scan results ...
}

private fun scanFailure() {
  // handle failure: new scan did NOT succeed
  // consider using old scan results: these are the OLD results!
  val results = wifiManager.scanResults
  ... potentially use older scan results ...
}

对于在 Android Q 或更高版本上运行的设备,正确连接到不打算作为对等网络的公共或私有 wifi 的唯一方法是使用 NetworkSuggestionAPI,正如您在问题中已经显示的那样。

有时您看不到网络建议的原因如下:“如果用户使用 Wi-Fi 选择器在连接到其中一个网络建议时明确断开连接,则该网络将在 24 小时内被忽略。在在此期间,即使应用程序删除并重新添加与网络对应的网络建议,该网络也不会被考虑自动连接。”,引自谷歌文档网站。

有关 wifi 扫描的更多信息,请查看官方文档: https ://developer.android.com/guide/topics/connectivity/wifi-scan#kotlin

更多关于 WifiNetworkSuggestion API 的信息可以在这里找到: https ://developer.android.com/guide/topics/connectivity/wifi-suggest


推荐阅读