Revanth Kovuri
Revanth Kovuri

Reputation: 161

How to connect to Other Wi-fi Network Programmatically in and above Android API level 29 (>= 29)

Usecase: Connect to other specified Wi-fi networks successfully and disconnect from the existing Wi-fi network.

I tried WifiNetworkSpecifier and WifiNetworkSuggestion to connect to Other Wi-fi programmatically in Android. When I tried using WifiNetworkSpecifier, I can see the dialog asking the user to connect to the specified network. But, after clicking connect I can not access the internet and disconnects from the Wi-fi network when I close/kill my application. Whereas WifiNetworkSuggestion is not working for me with the below code(location permission garanted).

Code used for WifiNetworkSpecifier:

    WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
    builder.setSsid(MY_SSID);
    builder.setWpa2Passphrase(MY_PASSWORD);

    WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();

    NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder();
    networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);
    }

    NetworkRequest networkRequest = networkRequestBuilder1.build();
    ConnectivityManager cm = (ConnectivityManager)
            getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
    ConnectivityManager.NetworkCallback networkCallback = new
            ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    Log.d(TAG, "onAvailable:" + network);
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        cm.bindProcessToNetwork(network);
                    }
                }
            };
    cm.requestNetwork(networkRequest, networkCallback);

Code used for WifiNetworkSuggestion (I think for my usecase I need to use this one as per the android documentation):

   WifiNetworkSuggestion suggestion1 = new WifiNetworkSuggestion.Builder()
            .setSsid(MY_SSID)
            .setWpa2Passphrase(MY_PASSWORD)
            .setIsAppInteractionRequired(true) // Optional (Needs location permission)
            .build();


    List<WifiNetworkSuggestion> suggestionsList = new ArrayList<WifiNetworkSuggestion>();
    suggestionsList.add(suggestion1);

    int status = wifiManager.addNetworkSuggestions(suggestionsList);

    if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
        showToast("Failure");
    } else {
        showToast("Success");
    }

    final IntentFilter intentFilter = new IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

    final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (!intent.getAction().equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
                return;
            }
            // Post connection
            showToast("post connection");
        }
    };
    getApplicationContext().registerReceiver(broadcastReceiver, intentFilter);

Permissions used:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

Any suggestions or help is much appreciated. Thank you!

Upvotes: 1

Views: 2313

Answers (2)

Revanth Kovuri
Revanth Kovuri

Reputation: 161

In my case the above code is working but I disconnected the network from wifi picker so it blocked me for 24 hours. That is the reason above din’t worked for me at that time. Few limitations which I observed.

  • Location Permission is Mandatory
  • A user declining the network suggestion notification removes the CHANGE_WIFI_STATE permission from the app i.e; When the user click “No” in notification. They cannot able to connect to Wi-fi. The user can grant this approval later by going into the Wi-Fi control menu (Settings > Apps & notifications > Special App access > Wi-Fi Control > App name)- Android Documentation. 
  • After successfully connected to wifi uninstalling the app will leads to disconnection in WifiNetwork

Upvotes: 4

kabayaba
kabayaba

Reputation: 204

You need to register NetworkCallbck() onResume:

override fun onResume() {
    super.onResume()
    getConnectivityManager().registerDefaultNetworkCallback(networkCallback)
}

and networkCallback:

private val networkCallback: NetworkCallback = object : NetworkCallback() {
    override fun onAvailable(network: Network) {
        super.onAvailable(network)
        getConnectivityManager().bindProcessToNetwork(network)

        if (wifiManager.connectionInfo.ssid == "\"" + MY_SSID + "\"") { //take note of this string
           //connection succesfull. todo
        }
    }

    override fun onUnavailable() {
        super.onUnavailable()
    }

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

As for the wifiManager.addNetworkSuggestions do add these:

private fun checkNetworkSuggestion() {
    when (wifiManager.addNetworkSuggestions(getWifiSuggestionList()!!)) {
        WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS -> {
            //all ok so wait for network callback
        }
        WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE -> {
            //there is a duplicate. remove the suggestion
            wifiManager.removeNetworkSuggestions(getWifiSuggestionList()!!)
            checkNetworkSuggestion()
        }
        else -> //todo error
    }
}

If all goes well, a notification will be displayed to allow your app to connect to the network. Click yes and wait for networkcallback to return. This may take some time. In my case i have to wait 1 min for the wifi to be connected. Also imo there isn't a need to register the broadcast receiver. Lastly do unregister your networkcallback.

override fun onDestroy() {
    try {
        getConnectivityManager().unregisterNetworkCallback(networkCallback)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    super.onDestroy()
}

Do try these out.

Upvotes: 2

Related Questions