Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connect To Wifi Android Q

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.

like image 730
Vierda Mila Nartila Avatar asked Oct 15 '22 11:10

Vierda Mila Nartila


1 Answers

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"/>
like image 68
ROHIT LIEN Avatar answered Oct 21 '22 00:10

ROHIT LIEN