Android - Connecting your app to a Wi-Fi connection without internet

Radhika S
Canopas
Published in
3 min readNov 11, 2020

--

This post shows steps to programmatically connect your app to wifi. We will use Wifi Manager to manage wi-fi connectivity and Connectivity Manager to handle network state and connectivity changes.

First and foremost, add permissions in your manifest file. These 4 permissions are required to make changes in your device network connectivity.

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

Setup configuration to connect one specific wifi using WifiConfiguration.

public static WifiConfiguration buildWifiConfig() {
WifiConfiguration config = new WifiConfiguration();
config.SSID = "\"networkSSID\"";
config.wepKeys[0] = "\"networkPassword\"";
// have to set a very high number in order to ensure that //Android doesn't immediately drop this connection and reconnect to //the a different AP.
config.priority = 999999;
return config;
}

To connect to the Wi-Fi network, register a BroadcastReceiver that listens for WifiManager.NETWORK_STATE_CHANGED_ACTION

public class WifiChangeBroadcastReceiver extends BroadcastReceiver {
private WifiChangeBroadcastListener listener;
public WifiChangeBroadcastReceiver(WifiChangeBroadcastListener listener){
this.listener=listener;
}
@Override
public void onReceive(Context context, Intent intent) {
listener.onWifiChangeBroadcastReceived(context, intent);
}
public interface WifiChangeBroadcastListener {
void onWifiChangeBroadcastReceived(Context context, Intent intent);
}
}

Register broadcast receiver from your activity’s onStart and don’t forget to unregister it in onStop.

private WifiChangeBroadcastReceiver wifiStateChangeReceiver;
@Override
protected void onStart() {
super.onStart();
wifiStateChangeReceiver = new WifiChangeBroadcastReceiver(this);
registerReceiver(wifiStateChangeReceiver,
new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION));
}@Override
protected void onStop() {
super.onStop();
unregisterReceiver(wifiStateChangeReceiver);
}

Now it is time to connect your app to wifi.

public void connectToAccessPoint() {
WifiConfiguration wifiConfig = buildWifiConfig();
String targetNetworkSSID = wifiConfig.SSID;
//Check whether we are connected to specific wifi or not
WifiInfo currentConnectionInfo= wifiManager.getConnectionInfo();
if(currentConnectionInfo.getSSID().equals(targetNetworkSSID)) {
// we're already connected to this AP, nothing to do.
} else {
// If network is configured, we can obtain the network ID from // the WifiConfiguration object.
int networkId= getIdForConfiguredNetwork("networkSSID");
if (networkId == -1) {
// Add network to configured network list.
networkId = wifiManager.addNetwork(wifiConfig);
}
//after enableNetwork call we will receive network change broadcast.
wifiManager.enableNetwork(networkId, true);
}
}
@Override
public void onWifiChangeBroadcastReceived(Context context,
Intent intent)
{
WifiConfiguration wifiConfig = buildWifiConfig();
WifiInfo wifiInfo = intent.getParcelableExtra(WifiManager.EXTRA_WIFI_INFO);
if (wifiInfo == null || wifiInfo.getSSID() == null) {
// no WifiInfo or SSID means we're not interested.
return;
}
String newlyConnectedSSID = wifiInfo.getSSID();
if (newlyConnectedSSID.equals(wifiConfig.SSID)) {
bindProcessToNetwork();
}
}
public int getIdForConfiguredNetwork(String ssid) {
List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks();
for (WifiConfiguration configNetwork : configuredNetworks) {
if (configNetwork.SSID.equals(ssid)) {
return configNetwork.networkId;
}
}
return -1;
}

Here is our bindProcessToNetwork method to bind current process to network, this will route all network request to specific network

public void bindProcessToNetwork() {
if (Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
Network network= getNetworkObjectForCurrentWifiConnection();
if (Build.VERSION.SDK_INT >= VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
}
@Nullable
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public Network getNetworkObjectForCurrentWifiConnection() {
List<Network> networks = Arrays.asList(connectivityManager.getAllNetworks());
for (Network network : networks) {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities.hasTransport
(NetworkCapabilities.TRANSPORT_WIFI)) {
return network;
}
}
return null;
}

Hurray! We just connected our app to a wifi connection which does not have internet connectivity. It’s very useful in IOT devices where devices host wifi to allow communication with other devices but it might not have internet connectivity.

You can find complete code HERE !!

Thanks for your support!
If you like what you read, be sure to 👏 it below — as a writer it means the world!
Follow Canopas Software to get updates on interesting tech articles!

Happy coding!

--

--

Android developer | Sharing knowledge of Jetpack Compose & android development