Connect To Wifi Android Q

混江龙づ霸主 提交于 2020-12-29 07:36:51

问题


I'm trying to connect to wifi with below code

 val specifier = WifiNetworkSpecifier.Builder()
        .setSsid(machineID).build()

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

    val connectivityManager = context.applicationContext
        .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?

    connectivityManager?.requestNetwork(networkRequest,object:ConnectivityManager.NetworkCallback(){
        override fun onUnavailable() {
            callback.onWifiConnected(WifiConstant.WIFI_IP_ADDRESS_INVALID)
        }

        override fun onAvailable(network: Network) {
            val wifiInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI)

            if (wifiInfo.isConnected)
                callback.onWifiConnected("${getWifiManager()?.connectionInfo?.ipAddress!!}")
            else
                callback.onWifiConnected(WifiConstant.WIFI_IP_ADDRESS_INVALID)
        }
    })

But I'm always getting runtime error in this line

val specifier = WifiNetworkSpecifier.Builder()

The error is something as below :

2019-09-25 13:49:00.718 28556-28556/com.aloha.asiaiot E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.aloha.asiaiot, PID: 28556
java.lang.NoClassDefFoundError: Failed resolution of: Landroid/net/wifi/WifiNetworkSpecifier$Builder;
    at com.aloha.asiaiot.common.util.wifi.WifiConnectionManager.connectToWifi(WifiConnectionManager.kt:77)
    at com.aloha.asiaiot.connectivity.devicescan.data.DeviceScanNetworkRepository.connectToWifi(DeviceScanNetworkRepository.kt:48)
    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanRepository.connectToWifi(DeviceScanRepository.kt:18)
    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanUseCase.connectToWifi(DeviceScanUseCase.kt:18)
    at com.aloha.asiaiot.connectivity.devicescan.presentation.viewmodel.DeviceScanViewModel.connectToWifi(DeviceScanViewModel.kt:41)
    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.connectToGateway(DeviceScanFragment.kt:139)
    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.access$connectToGateway(DeviceScanFragment.kt:29)
    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment$onActivityCreated$3.onClick(DeviceScanFragment.kt:72)
    at android.view.View.performClick(View.java:7339)
    at android.widget.TextView.performClick(TextView.java:14221)
    at android.view.View.performClickInternal(View.java:7305)
    at android.view.View.access$3200(View.java:846)
    at android.view.View$PerformClick.run(View.java:27787)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7058)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
 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]]
    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:134)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
    at com.aloha.asiaiot.common.util.wifi.WifiConnectionManager.connectToWifi(WifiConnectionManager.kt:77) 
    at com.aloha.asiaiot.connectivity.devicescan.data.DeviceScanNetworkRepository.connectToWifi(DeviceScanNetworkRepository.kt:48) 
    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanRepository.connectToWifi(DeviceScanRepository.kt:18) 
    at com.aloha.asiaiot.connectivity.devicescan.domain.DeviceScanUseCase.connectToWifi(DeviceScanUseCase.kt:18) 
    at com.aloha.asiaiot.connectivity.devicescan.presentation.viewmodel.DeviceScanViewModel.connectToWifi(DeviceScanViewModel.kt:41) 
    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.connectToGateway(DeviceScanFragment.kt:139) 
    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment.access$connectToGateway(DeviceScanFragment.kt:29) 
    at com.aloha.asiaiot.connectivity.devicescan.presentation.DeviceScanFragment$onActivityCreated$3.onClick(DeviceScanFragment.kt:72) 
    at android.view.View.performClick(View.java:7339) 
    at android.widget.TextView.performClick(TextView.java:14221) 
    at android.view.View.performClickInternal(View.java:7305) 
    at android.view.View.access$3200(View.java:846) 
    at android.view.View$PerformClick.run(View.java:27787) 
    at android.os.Handler.handleCallback(Handler.java:873) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7058) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965) 

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

I tried also with below code for solving lower SDK :

 if (Build.VERSION.SDK_INT< Build.VERSION_CODES.Q) {
        val wifiConfiguration = WifiConfiguration()
    wifiConfiguration.SSID = String.format("\"%s\"", machineID)
    wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
    wifiConfiguration.status = WifiConfiguration.Status.ENABLED
    wifiConfiguration.priority = 40

    val wifiManager = getWifiManager()
    val netID = wifiManager?.addNetwork(wifiConfiguration)!!

    wifiManager.disconnect()
    wifiManager.enableNetwork(netID,true)
    wifiManager.reconnect()


    if (isWifiConnected(machineID))
        callback.onWifiConnected("${wifiManager.dhcpInfo.ipAddress}")
    else
        callback.onWifiConnected(WifiConstant.WIFI_IP_ADDRESS_INVALID)
    }

and below my isWifiConnected :

private fun isWifiConnected (machineID: String) : Boolean{
    if (getWifiManager()?.isWifiEnabled!!) {
        val wifiInfo = getWifiManager()?.connectionInfo
        if (wifiInfo?.ssid==machineID)
            return true
    }

    return false
}

But in this part I always getting false :

    wifiManager.disconnect()
    wifiManager.enableNetwork(netID,true)
    wifiManager.reconnect()

An as per documentation it says :

This method was deprecated in API level 29. a) See WifiNetworkSpecifier.Builder#build() for new mechanism to trigger connection to a Wi-Fi network. b) See addNetworkSuggestions(java.util.List), removeNetworkSuggestions(java.util.List) for new API to add Wi-Fi networks for consideration when auto-connecting to wifi. Compatibility Note: For applications targeting Build.VERSION_CODES.Q or above, this API will always return false.

I'm testing in real device with OS version 9. But code running fine in emulator. Kindly advise what is possible cause. Thank you for any kind help.


回答1:


This is my code :

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)
    }

Then in onDestroy connectivityManager?.unregisterNetworkCallback(networkCallback)

Permissions needed :

 <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"/>



回答2:


The class has been added in Api level 29 so if you are testing on android Pie it won't work. You need to wrap your code checking the build version and apply it only on android 10+.



来源:https://stackoverflow.com/questions/58091968/connect-to-wifi-android-q

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!