How to tell if 'Mobile Network Data' is enabled or disabled (even when connected by WiFi)?

AndroidNetworkingNetwork Connection

Android Problem Overview


I have an app that I want to be able to use to get a connection status report from a remote query.

I want to know if WiFi is connected, and if data access is enabled over mobile network.

If the WiFi goes out of range I want to know if I can rely on the mobile network.

The problem is that data enabled is always returned as true when I am connected by WiFi, and I can only properly query the mobile network when not connected by WiFi.

all the answers I have seen suggest polling to see what the current connection is, but I want to know if mobile network is available should I need it, even though I might be connected by WiFi at present.

Is there anyway of telling whether mobile network data is enabled without polling to see if is connected?

EDIT

So when connected by WiFi If I go to settings and deselect 'Data Enabled' and then in my app I do this:

 boolean mob_avail = 
 conMan.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isAvailable();

mob_avail is returned as 'true', but I have disabled Mobile Network Data, so I would expect it to be 'false'

If I turn off the WiFi, there is (rightly) no connection as I have disabled mobile network data.

so how do I check if mobile network data is enabled when I am connected by WiFi?

UPDATE

I took a look at getAllNetworkInfo() as suggested in the comments by ss1271

I outputted the info returned about the mobile network under the following 3 conditions

WiFi Off - Mobile Data on

WiFi On - Mobile Data off

WiFi On - Mobile Data on

and got the following results:

> With WiFi OFF: > > mobile[HSUPA], state: CONNECTED/CONNECTED, reason: unknown, extra: > internet, roaming: false, failover: false, isAvailable: true, > featureId: -1, userDefault: false > > With WiFi On / Mobile OFF > > NetworkInfo: type: mobile[HSUPA], state: DISCONNECTED/DISCONNECTED, > reason: connectionDisabled, extra: (none), roaming: false, > failover: false, isAvailable: true, featureId: -1, userDefault: > false > > With WiFi On / Mobile On > > NetworkInfo: type: mobile[HSPA], state: DISCONNECTED/DISCONNECTED, > reason: connectionDisabled, extra: (none), roaming: false, > failover: false, isAvailable: true, featureId: -1, userDefault: > false

So as you can see isAvailable returned true each time, and state only showed as Disconnected when WiFi was in affect.

CLARIFICATION

I am NOT looking to see if my phone is currently connected by Mobile Network. I AM trying to establish whether or not the user has enabled / disabled Data access over mobile network. They can turn this on and off by going to Settings -> Wireless and Network Settings ->Mobile Network Settings -> Data enabled

Android Solutions


Solution 1 - Android

The following code will tell you if "mobile data" is enabled or not, regardless of whether or not there is a mobile data connection active at the moment or whether or not wifi is enabled/active or not. This code only works on Android 2.3 (Gingerbread) and later. Actually this code also works on earlier versions of Android as well ;-)

    boolean mobileDataEnabled = false; // Assume disabled
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    try {
        Class cmClass = Class.forName(cm.getClass().getName());
        Method method = cmClass.getDeclaredMethod("getMobileDataEnabled");
        method.setAccessible(true); // Make the method callable
        // get the setting for "mobile data"
        mobileDataEnabled = (Boolean)method.invoke(cm);
    } catch (Exception e) {
        // Some problem accessible private API
        // TODO do whatever error handling you want here
    }

Note: you will need to have permission android.permission.ACCESS_NETWORK_STATE to be able to use this code.

Solution 2 - Android

I've upgraded Allesio's answer. Settings.Secure's mobile_data int has moved to Settings.Global since 4.2.2.

Try This code when you want to know if mobile network is enabled even when wifi is enabled and connected.

Updated to check if SIM Card is available. Thanks for pointing out murat.

boolean mobileYN = false;

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
	if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
	{
    	mobileYN = Settings.Global.getInt(context.getContentResolver(), "mobile_data", 1) == 1;
	}
	else{
		mobileYN = Settings.Secure.getInt(context.getContentResolver(), "mobile_data", 1) == 1;
	}
}

Solution 3 - Android

One way is to check whether the user has mobile data activated in the Settings, which most likely will be used if wifi goes off. This works (tested), and it doesn't use reflection, although it uses an hidden value in the API:

boolean mobileDataAllowed = Settings.Secure.getInt(getContentResolver(), "mobile_data", 1) == 1;

Depending on the API, you need to check Settings.Global instead of Settings.Secure, as pointed out by @user1444325.

Source: https://stackoverflow.com/questions/6591774/android-api-call-to-determine-user-setting-data-enabled

Solution 4 - Android

@sNash's function works great. But in few devices I found it returns true even if data is disabled. So I found one alternate solution which is in Android API.

getDataState() method of TelephonyManager will be very useful.

I updated @snash's function with the above function used. Below function returns false when cellular data is disabled otherwise true.

private boolean checkMobileDataIsEnabled(Context context){
		boolean mobileYN = false;

		TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
		if (tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
			TelephonyManager tel = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
//			if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1)
//			{
//				mobileYN = Settings.Global.getInt(context.getContentResolver(), "mobile_data", 0) == 1;
//			}
//			else{
//				mobileYN = Settings.Secure.getInt(context.getContentResolver(), "mobile_data", 0) == 1;
//			}
			int dataState = tel.getDataState();
			Log.v(TAG,"tel.getDataState() : "+ dataState);
			if(dataState != TelephonyManager.DATA_DISCONNECTED){
				mobileYN = true;
			}

		}

		return mobileYN;
	}

Solution 5 - Android

You can try something like that:

ConnectivityManager conMan = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

//mobile
State mobile = conMan.getNetworkInfo(0).getState();

//wifi
State wifi = conMan.getNetworkInfo(1).getState();


if (mobile == NetworkInfo.State.CONNECTED || mobile == NetworkInfo.State.CONNECTING) 
{
    //mobile
}
else if (wifi == NetworkInfo.State.CONNECTED || wifi == NetworkInfo.State.CONNECTING) 
{
    //wifi
}

If you are interested if you are realy connected, use

NetworkInfo.State.CONNECTED 

only, instead of

NetworkInfo.State.CONNECTED || NetworkInfo.State.CONNECTING

Solution 6 - Android

Since ConnectivityManager.allNetworkInfo is deprecated, Android suggested using getNetworkCapabilities

fun isOnMobileData(): Boolean {
    val connectivityManager =
        context.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
    val all = connectivityManager.allNetworks

    return all.any {
        val capabilities = connectivityManager.getNetworkCapabilities(it)
        capabilities?.hasTransport(TRANSPORT_CELLULAR) == true
    }
}

Solution 7 - Android

use TelephonyManager

TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);

tm.isDataEnabled()

According to android documentation

https://developer.android.com/reference/android/telephony/TelephonyManager.html#isDataEnabled()

Solution 8 - Android

I think using NetworkInfo class and isConnected should work:

ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

return info != NULL || info.isConnected();

And to check mobile data is connected perhaps. I can not be sure until I test it. Which I cannot do until tommorrow.

TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

if(tm .getDataState() == tm .DATA_CONNECTED)
   return true;

Solution 9 - Android

Here is a xamarin solution to this problem:

    public static bool IsMobileDataEnabled()
    {
        bool result = false;

        try
        {
            Context context = //get your context here or pass it as a param

            if (Build.VERSION.SdkInt >= BuildVersionCodes.JellyBeanMr1)
            {
                //Settings comes from the namespace Android.Provider
                result = Settings.Global.GetInt(context.ContentResolver, "mobile_data", 1) == 1;
            }
            else
            {
                result = Settings.Secure.GetInt(context.ContentResolver, "mobile_data", 1) == 1;
            }
        }
        catch (Exception ex)
        {
            //handle exception
        }

        return result;
    }

PS: Make sure you have all the permissions for this code.

Solution 10 - Android

You must use the ConnectivityManager, and NetworkInfo details can be found here

Solution 11 - Android

To identify which SIM or slot is making data connection active in mobile, we need to register action android:name="android.net.conn.CONNECTIVITY_CHANGE"  with permission 	
uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" &    uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"

    public void onReceive(Context context, Intent intent) 
 if (android.net.conn.CONNECTIVITY_CHANGE.equalsIgnoreCase(intent
                .getAction())) {

IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
 IConnectivityManager service =  IConnectivityManager.Stub.asInterface(b);
NetworkState[] states = service.getAllNetworkState();

 for (NetworkState state : states) {

                if (state.networkInfo.getType() == ConnectivityManager.TYPE_MOBILE
                        && state.networkInfo.isConnected()) {

 TelephonyManager mTelephonyManager = (TelephonyManager) context
                        .getSystemService(Context.TELEPHONY_SERVICE);
         int slotList =  { 0, 1 };
          int[] subId = SubscriptionManager.getSubId(slotList[0]);
          if(mTelephonyManager.getDataEnabled(subId[0])) {
             // this means data connection is active for SIM1 similary you 
             //can chekc for SIM2 by slotList[1]
               .................
          }
}

}

Solution 12 - Android

    ConnectivityManager cm = (ConnectivityManager) activity
                        .getSystemService(Context.CONNECTIVITY_SERVICE);
                NetworkInfo info = cm.getActiveNetworkInfo();
                String networkType = "";
    if (info.getType() == ConnectivityManager.TYPE_WIFI) {
                    networkType = "WIFI";
                } 
else if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
    
                    networkType = "mobile";
    }

Solution 13 - Android

According to android documentation https://developer.android.com/training/monitoring-device-state/connectivity-monitoring#java

ConnectivityManager cm =
     (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null &&
                      activeNetwork.isConnectedOrConnecting();

Solution 14 - Android

Here is a simple solution from two other answers:

		TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
		
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
			return tm.isDataEnabled();
			
		} else {
			return tm.getSimState() == TelephonyManager.SIM_STATE_READY && tm.getDataState() != TelephonyManager.DATA_DISCONNECTED;
		}

Solution 15 - Android

Well there is a workaround to check if the data connection is on. But I am not sure whether it will work on every device. You need to check that. (It worked on Android one device)

long data = TrafficStats.getMobileRxBytes();
if(data > 0){
    //Data is On
}
else{
    //Data is Off
}

If you are not aware about this method, it returns the total of bytes recieved through mobile network since the device boot up. When you turn off the mobile data connection, it will return Zero (0). When you turn on, it will return the total of bytes again. But you need to aware that there is a problem which can happen when using this workaround.

  • This method will also return 0 when you reboot the phone because the calculation starts from 0 bytes.

Solution 16 - Android

private boolean haveMobileNetworkConnection() {
        boolean haveConnectedMobile = false;

        ConnectivityManager cm = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo[] netInfo = cm.getAllNetworkInfo();

        for (NetworkInfo ni : netInfo) {

            if (ni.getTypeName().equalsIgnoreCase("MOBILE"))
                if (ni.isConnected())
                    haveConnectedMobile = true;
        }
        return haveConnectedMobile;
    }

Note: you will need to have permission android.permission.ACCESS_NETWORK_STATE to be able to use this code

Solution 17 - Android

There is simple API that seems to be working

TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return tm.isDataEnabled();
             

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKevin BradshawView Question on Stackoverflow
Solution 1 - AndroidDavid WasserView Answer on Stackoverflow
Solution 2 - AndroidsNashView Answer on Stackoverflow
Solution 3 - AndroidAlessioView Answer on Stackoverflow
Solution 4 - AndroidMohKView Answer on Stackoverflow
Solution 5 - AndroidMilos CuculovicView Answer on Stackoverflow
Solution 6 - AndroidJanjan MedinaView Answer on Stackoverflow
Solution 7 - AndroidRalph ChenView Answer on Stackoverflow
Solution 8 - AndroidtozkaView Answer on Stackoverflow
Solution 9 - AndroidSubqueryCrunchView Answer on Stackoverflow
Solution 10 - AndroidCAM-DevView Answer on Stackoverflow
Solution 11 - AndroidamitView Answer on Stackoverflow
Solution 12 - AndroidSrishti RoyView Answer on Stackoverflow
Solution 13 - AndroidRémyView Answer on Stackoverflow
Solution 14 - AndroidBrian HongView Answer on Stackoverflow
Solution 15 - AndroidThamidu de HarshithaView Answer on Stackoverflow
Solution 16 - AndroidAnnas Bin WaheedView Answer on Stackoverflow
Solution 17 - AndroidEvgeny PisView Answer on Stackoverflow