连接到 Wifi Android Q

Vie*_*ila 5 android android-wifi android-10.0

我正在尝试使用以下代码连接到 wifi

\n\n
 val specifier = WifiNetworkSpecifier.Builder()\n        .setSsid(machineID).build()\n\n    val networkRequest = NetworkRequest.Builder()\n        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)\n        .setNetworkSpecifier(specifier)\n        .build()\n\n    val connectivityManager = context.applicationContext\n        .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?\n\n    connectivityManager?.requestNetwork(networkRequest,object:ConnectivityManager.NetworkCallback(){\n        override fun onUnavailable() {\n            callback.onWifiConnected(WifiConstant.WIFI_IP_ADDRESS_INVALID)\n        }\n\n        override fun onAvailable(network: Network) {\n            val wifiInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)\n\n            if (wifiInfo.isConnected)\n                callback.onWifiConnected("${getWifiManager()?.connectionInfo?.ipAddress!!}")\n            else\n                callback.onWifiConnected(WifiConstant.WIFI_IP_ADDRESS_INVALID)\n        }\n    })\n
Run Code Online (Sandbox Code Playgroud)\n\n

但我总是在这一行收到运行时错误

\n\n
val specifier = WifiNetworkSpecifier.Builder()\n
Run Code Online (Sandbox Code Playgroud)\n\n

错误如下:

\n\n
2019-09-25 13:49:00.718 28556-28556/com.aloha.asiaiot E/AndroidRuntime: FATAL EXCEPTION: main\nProcess: com.aloha.asiaiot, PID: 28556\njava.lang.NoClassDefFoundError: Failed resolution of: Landroid/net/wifi/WifiNetworkSpecifier$Builder;\n    at com.aloha.asiaiot.common.util.wifi.WifiConnectionManager.connectToWifi(WifiConnectionManager.kt:77)\n    at com.aloha.asiaiot.connectivity.devicescan.data.DeviceScanNetworkRepository.connectToWifi(DeviceScanNetworkRepository.kt:48)\n    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanRepository.connectToWifi(DeviceScanRepository.kt:18)\n    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanUseCase.connectToWifi(DeviceScanUseCase.kt:18)\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.viewmodel.DeviceScanViewModel.connectToWifi(DeviceScanViewModel.kt:41)\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.connectToGateway(DeviceScanFragment.kt:139)\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.access$connectToGateway(DeviceScanFragment.kt:29)\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment$onActivityCreated$3.onClick(DeviceScanFragment.kt:72)\n    at android.view.View.performClick(View.java:7339)\n    at android.widget.TextView.performClick(TextView.java:14221)\n    at android.view.View.performClickInternal(View.java:7305)\n    at android.view.View.access$3200(View.java:846)\n    at android.view.View$PerformClick.run(View.java:27787)\n    at android.os.Handler.handleCallback(Handler.java:873)\n    at android.os.Handler.dispatchMessage(Handler.java:99)\n    at android.os.Looper.loop(Looper.java:214)\n    at android.app.ActivityThread.main(ActivityThread.java:7058)\n    at java.lang.reflect.Method.invoke(Native Method)\n    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)\n Caused by: java.lang.ClassNotFoundException: Didn\'t find class "android.net.wifi.WifiNetworkSpecifier$Builder" on path: DexPathList[[zip file "/data/app/com.aloha.asiaiot-k57tcS1ybEKsaCIu13TJnw==/base.apk"],nativeLibraryDirectories=[/data/app/com.aloha.asiaiot-k57tcS1ybEKsaCIu13TJnw==/lib/arm64, /system/lib64]]\n    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)\n    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)\n    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)\n    at com.aloha.asiaiot.common.util.wifi.WifiConnectionManager.connectToWifi(WifiConnectionManager.kt:77)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.data.DeviceScanNetworkRepository.connectToWifi(DeviceScanNetworkRepository.kt:48)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanRepository.connectToWifi(DeviceScanRepository.kt:18)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanUseCase.connectToWifi(DeviceScanUseCase.kt:18)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.viewmodel.DeviceScanViewModel.connectToWifi(DeviceScanViewModel.kt:41)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.connectToGateway(DeviceScanFragment.kt:139)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.access$connectToGateway(DeviceScanFragment.kt:29)\xc2\xa0\n    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment$onActivityCreated$3.onClick(DeviceScanFragment.kt:72)\xc2\xa0\n    at android.view.View.performClick(View.java:7339)\xc2\xa0\n    at android.widget.TextView.performClick(TextView.java:14221)\xc2\xa0\n    at android.view.View.performClickInternal(View.java:7305)\xc2\xa0\n    at android.view.View.access$3200(View.java:846)\xc2\xa0\n    at android.view.View$PerformClick.run(View.java:27787)\xc2\xa0\n    at android.os.Handler.handleCallback(Handler.java:873)\xc2\xa0\n    at android.os.Handler.dispatchMessage(Handler.java:99)\xc2\xa0\n    at android.os.Looper.loop(Looper.java:214)\xc2\xa0\n    at android.app.ActivityThread.main(ActivityThread.java:7058)\xc2\xa0\n    at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\xc2\xa0\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

2019-09-25 13:49:00.747 28556-28556/com.aloha.asiaiot

\n\n

我还尝试使用以下代码来解决较低的 SDK 问题:

\n\n
 if (Build.VERSION.SDK_INT< Build.VERSION_CODES.Q) {\n        val wifiConfiguration = WifiConfiguration()\n    wifiConfiguration.SSID = String.format("\\"%s\\"", machineID)\n    wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)\n    wifiConfiguration.status = WifiConfiguration.Status.ENABLED\n    wifiConfiguration.priority = 40\n\n    val wifiManager = getWifiManager()\n    val netID = wifiManager?.addNetwork(wifiConfiguration)!!\n\n    wifiManager.disconnect()\n    wifiManager.enableNetwork(netID,true)\n    wifiManager.reconnect()\n\n\n    if (isWifiConnected(machineID))\n        callback.onWifiConnected("${wifiManager.dhcpInfo.ipAddress}")\n    else\n        callback.onWifiConnected(WifiConstant.WIFI_IP_ADDRESS_INVALID)\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

下面是我的 isWifiConnected :

\n\n
private fun isWifiConnected (machineID: String) : Boolean{\n    if (getWifiManager()?.isWifiEnabled!!) {\n        val wifiInfo = getWifiManager()?.connectionInfo\n        if (wifiInfo?.ssid==machineID)\n            return true\n    }\n\n    return false\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但在这部分我总是犯错:

\n\n
    wifiManager.disconnect()\n    wifiManager.enableNetwork(netID,true)\n    wifiManager.reconnect()\n
Run Code Online (Sandbox Code Playgroud)\n\n

根据文档它说:

\n\n
\n

此方法在 API 级别 29 中已弃用。\na) 请参阅 WifiNetworkSpecifier.Builder#build() 了解触发 Wi-Fi 网络连接的新机制。b) 请参阅 addNetworkSuggestions(java.util.List)、removeNetworkSuggestions(java.util.List) 了解用于添加 Wi-Fi 网络的新 API,以供自动连接到 wifi 时考虑。兼容性注意:对于面向 Build.VERSION_CODES.Q 或更高版本的应用程序,此 API 将始终返回 false

\n
\n\n

我正在使用操作系统版本 9 的真实设备中进行测试。但是代码在模拟器中运行良好。请告知可能的原因是什么。感谢您的帮助。

\n

ROH*_*IEN 4

这是我的代码:

val wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager?
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
        try {
            val wifiConfig = WifiConfiguration()
            wifiConfig.SSID = "\"" + yourSsid + "\""
            wifiConfig.preSharedKey = "\"" + password + "\""
            val netId = wifiManager!!.addNetwork(wifiConfig)
            wifiManager.disconnect()
            wifiManager.enableNetwork(netId, true)
            wifiManager.reconnect()
            if (isWifiConnected("\"" + deviceId + "\"")) {
                doSomethingHere()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    } else {
        val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
                .setSsid( yourSsid!! )
                .setWpa2Passphrase(password)
                .build()

        val networkRequest = NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .setNetworkSpecifier(wifiNetworkSpecifier)
                .build()

        connectivityManager = Boron.instance.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?

        networkCallback = object : ConnectivityManager.NetworkCallback() {
            override fun onUnavailable() {
                super.onUnavailable()
            }

            override fun onLosing(network: Network, maxMsToLive: Int) {
                super.onLosing(network, maxMsToLive)

            }

            override fun onAvailable(network: Network) {
                super.onAvailable(network)
                connectivityManager?.bindProcessToNetwork(network)
            }

            override fun onLost(network: Network) {
                super.onLost(network)

            }
        }
        connectivityManager?.requestNetwork(networkRequest,networkCallback)
    }
Run Code Online (Sandbox Code Playgroud)

然后在 onDestroyconnectivityManager?.unregisterNetworkCallback(networkCallback)

所需权限:

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-feature android:name="android.permission.WRITE_SETTINGS"
    android:required="false"/>
Run Code Online (Sandbox Code Playgroud)