3

我正在使用新的 API 29 将设备连接到 Android 10 设备中的 wifi 网络:

    private val connectivityManager: ConnectivityManager by inject()

    override fun connectToNetwork(ssid: String, password: String) {
        val networkRequest = buildNetworkRequest(ssid, password)

        val networkCallback =
            object : NetworkCallback() {
                override fun onAvailable(network: Network) {
                    super.onAvailable(network)
                    Timber.d("Connected to network $ssid")
                }

                override fun onUnavailable() {
                    super.onUnavailable()
                    Timber.e("Unable to connect to network $ssid")
                }
            }

        connectivityManager.requestNetwork(networkRequest, networkCallback, CONNECTION_TIME_OUT)

    }

    private fun buildNetworkRequest(ssid: String, password: String) =
        NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
            .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
            .setNetworkSpecifier(buildWifiNetworkSpecifier(ssid, password))
            .build()

    private fun buildWifiNetworkSpecifier(ssid: String, password: String) =
        WifiNetworkSpecifier.Builder()
            .setSsid(ssid)
            .setWpa2Passphrase(password)
            .build()

将出现一个对话框,其中包含“要使用的设备”,其中列出了指定的 wifi 网络。该对话框有两个“取消”和“连接”按钮。当我点击“连接”时,设备连接到 wifi 网络(我可以在系统设置中看到)并且连接按钮被禁用。

但是对话框并没有消失,并且没有调用 requestNetwork 回调中的任何方法。最终我达到了指定的超时时间,另一个对话框出现了“出现问题。应用程序已取消选择设备的请求”。

这里发生了什么?我想连接到网络并调用回调中的“onAvailable”或“onUnavailable”方法。

4

2 回答 2

1

在尝试了几乎所有事情之后,我终于设法按预期完成了这项工作。不知道为什么,但是当我进入设备的系统设置并忘记了我试图以编程方式连接的 wifi 网络时,这开始起作用了。

我很高兴我摆脱了这个问题,但我不知道是什么原因造成的,而且同样的事情也可能发生在未来的用户身上。

于 2020-01-17T13:09:46.087 回答
1

我有同样的问题。通过反复试验,我发现这是由于请求在网络最终连接之前发生的事实。如果您在网络可用后发送请求,那么一切正常。这是解决我的问题的代码示例:

override fun onAvailable(network: Network) {                
            GlobalScope.launch(Dispatchers.IO) {
                while (!isNetworkAvailable(ctx)) {
                    delay(200)
                }
                launch(Dispatchers.Main) {
                    // begin request....
                }
            }
            cm.unregisterNetworkCallback(this)
        }

 private fun isNetworkAvailable(ctx: Context): Boolean {
    val connectivityManager = ctx.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val nw = connectivityManager.activeNetwork ?: return false
        val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
        return actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
    } else {
        val nwInfo = connectivityManager.activeNetworkInfo ?: return false
        return nwInfo.isConnected
    }
}

此外,在连接之前,您必须清除 ssid 才能正确连接:

private fun removeSsid(ctx : Context, ssid : String, pass : String){
    val suggestion = WifiNetworkSuggestion.Builder()
        .setSsid(ssid)
        .setWpa2Passphrase(pass)
        .build()
    val wifiManager = ctx.getSystemService(WIFI_SERVICE) as WifiManager
    val sList = ArrayList<WifiNetworkSuggestion>()
    sList.add(suggestion)
    wifiManager.removeNetworkSuggestions(sList)
}
于 2020-05-30T21:51:41.733 回答