How to Check and Toggle WiFi or 3G/4G State in Android
Overview
- Check if WiFi or 3G/4G is Enabled (by User)
- Check if WiFi or 3G/4G is Connected
- Toggle WiFi or 3G/4G Programmatically
At some point, we want to know whether the device is connected to network so that we can do some network processes. Also we want to know if user make WiFi or 3G/4G disabled on purpose. Both things are able to know.
1. Check if WiFi or 3G/4G is Enabled (by User)
WiFi
ACCESS_WIFI_STATE
permission must be added to AndroidManifest.xml
.
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Checking code is simple. In activity, WifiManager has a handy method.
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
boolean wifiEnabled = wifiManager.isWifiEnabled();
3G/4G
This is more complicated. As WiFi case, we have to add ACCESS_NETWORK_STATE
permission.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Then we get NetworkInfo from ConnectivityManager.
ConnectivityManager connectivityManager =
(ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mobileInfo =
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
See getState() overview.
Reports the current coarse-grained state of the network.
There are 6 types of NetworkInfo.State.
CONNECTED
CONNECTING
DISCONNECTED
DISCONNECTING
SUSPENDED
UNKNOWN
Also this is getReason() overview.
Report the reason an attempt to establish connectivity failed, if one is available.
We can realize that when NetworkInfo.State
is DISCONNECTED
, getReason()
reports to us why mobile data is disconnected.
Also I tested several times with getState()
and getReason()
.
Enable WiFi and 3G/4G
When WiFi is connected, mobile data connection automatically closed.
mobileInfo.getState() // => DISCONNECTED mobileInfo.getReason() // => "dataDisabled"
Enable WiFi only
mobileInfo.getState() // => DISCONNECTED mobileInfo.getReason() // => "specificDisabled"
Enable 3G/4G only
mobileInfo.getState() // => CONNECTED
Disable both
mobileInfo.getState() // => DISCONNECTED mobileInfo.getReason() // => "specificDisabled"
So the code would be like this.
String reason = mobileInfo.getReason();
boolean mobileDisabled = mobileInfo.getState() == NetworkInfo.State.DISCONNECTED
&& (reason == null || reason.equals("specificDisabled"));
2. Check if WiFi or 3G/4G is Connected
WiFi or 3G/4G may not be connected even if the user enables them. Checking connectivity is useful when we are going to do some network communication.
WiFi
NetworkInfo wifiInfo =
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean wifiConnected = wifiInfo.getState() == NetworkInfo.State.CONNECTED;
3G/4G
NetworkInfo mobileInfo =
connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean mobileConnected = mobileInfo.getState() == NetworkInfo.State.CONNECTED;
3. Toggle WiFi or 3G/4G Programmatically
WiFi
CHANGE_WIFI_STATE
permission must be added to AndroidManifest.xml
.
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Enabling or disabling WiFi is easy.
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
wifiManager.setWifiEnabled(isWifiEnabled);
3G/4G
There is an workaround with reflection on “How can i turn off 3G/Data programmatically on Android?”.
For Android 2.3 and above:
private void setMobileDataEnabled(Context context, boolean enabled) {
final ConnectivityManager conman =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
final Class conmanClass = Class.forName(conman.getClass().getName());
final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
iConnectivityManagerField.setAccessible(true);
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
final Class iConnectivityManagerClass = Class.forName(
iConnectivityManager.getClass().getName());
final Method setMobileDataEnabledMethod = iConnectivityManagerClass
.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
setMobileDataEnabledMethod.setAccessible(true);
setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
It requires to CHANGE_NETWORK_STATE
permission.
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
In Activity:
setMobileDataEnabled(this, isMobileDataEnabled);
Codes for Android 2.2 and below are also in the same answer, but it requires MODIFY_PHONE_STATE
permission that can be used by system applications only.