Reputation: 161
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
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.
Upvotes: 4
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