How to programmatically disable Android data transfer

There is a service that checks in the background which type of network is 4G/3G, and if the type of 3G should be disabled data transmission.

Here is the service code.

public class MyService extends Service {

final String LOG_TAG = "myLogs";
private Handler handler;
private String type;

public void onCreate() {
    super.onCreate();
    Log.d(LOG_TAG, "onCreate");
}

public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(LOG_TAG, "onStartCommand");
    someTask();
    handler = new Handler();
    return super.onStartCommand(intent, flags, startId);
}

public void onDestroy() {
    super.onDestroy();
    Log.d(LOG_TAG, "onDestroy");
}

public IBinder onBind(Intent intent) {
    Log.d(LOG_TAG, "onBind");
    return null;
}

void someTask() {
    new Thread(new Runnable() {
        public void run() {
            while (true) {
                type = getNetworkClass(getBaseContext());
                ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
                NetworkInfo mMobile = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

                if (mMobile.isConnected()) {
                    Log.d(LOG_TAG, "------------------------ isConnected");
                    //if internet connected
                }else {
                    Log.d(LOG_TAG, "++++++++++++++++++++++++ isDisConnected");
                }
                if(type.equals("2G")){
                    Log.d(LOG_TAG, "type 2 - " + type);

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "!!! Тип сигнала сети " + type, Toast.LENGTH_SHORT).show();
                        }
                    });
                }else {
                    if (type.equals("3G")) {
                        Log.d(LOG_TAG, "type 3 - " + type);

                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(getApplicationContext(), "!!! Тип сигнала сети " + type, Toast.LENGTH_SHORT).show();
                            }
                        });


                    }else{if(type.equals("4G")){
                        Log.d(LOG_TAG, "type 4 - " + type);
                    }
                    }
                }

                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
}

public String getNetworkClass(Context context) {
    TelephonyManager mTelephonyManager = (TelephonyManager)
            context.getSystemService(Context.TELEPHONY_SERVICE);
    int networkType = mTelephonyManager.getNetworkType();
    switch (networkType) {
        case TelephonyManager.NETWORK_TYPE_GPRS:
        case TelephonyManager.NETWORK_TYPE_EDGE:
        case TelephonyManager.NETWORK_TYPE_CDMA:
        case TelephonyManager.NETWORK_TYPE_1xRTT:
        case TelephonyManager.NETWORK_TYPE_IDEN:
            return "2G";
        case TelephonyManager.NETWORK_TYPE_UMTS:
        case TelephonyManager.NETWORK_TYPE_EVDO_0:
        case TelephonyManager.NETWORK_TYPE_EVDO_A:
        case TelephonyManager.NETWORK_TYPE_HSDPA:
        case TelephonyManager.NETWORK_TYPE_HSUPA:
        case TelephonyManager.NETWORK_TYPE_HSPA:
        case TelephonyManager.NETWORK_TYPE_EVDO_B:
        case TelephonyManager.NETWORK_TYPE_EHRPD:
        case TelephonyManager.NETWORK_TYPE_HSPAP:
            return "3G";
        case TelephonyManager.NETWORK_TYPE_LTE:
            return "4G";
        default:
            return "Unknown";
    }
}

}

I tried it like this, it doesn't work

final ConnectivityManager conman =
            (ConnectivityManager) getBaseContext().getSystemService(CONNECTIVITY_SERVICE);

    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.class);

    setMobileDataEnabledMethod.setAccessible(true);

    // (true) to enable 3G; (false) to disable it.
    setMobileDataEnabledMethod.invoke(iConnectivityManager, false);
Author: Kromster, 2016-12-28

2 answers

To block it, you can use a ready-made firewall, which you can attach to yourself in the form of a module and run as a service. It can block selectively something from 3G/4G / WiFi https://github.com/M66B/NetGuard (GNUv3 license)

 0
Author: Andrew Grow, 2019-09-11 05:08:33

To enable / disable the Internet, I use this method:

public void setMobileDataState(boolean mobileDataEnabled)
{
    try
    {
        TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        Method setMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("setDataEnabled", boolean.class);

        if (null != setMobileDataEnabledMethod)
        {
            setMobileDataEnabledMethod.invoke(telephonyService, mobileDataEnabled);
        }
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Error setting mobile data state", ex);
    }
}

public boolean getMobileDataState()
{
    try
    {
        TelephonyManager telephonyService = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        Method getMobileDataEnabledMethod = telephonyService.getClass().getDeclaredMethod("getDataEnabled");

        if (null != getMobileDataEnabledMethod)
        {
            boolean mobileDataEnabled = (Boolean) getMobileDataEnabledMethod.invoke(telephonyService);

            return mobileDataEnabled;
        }
    }
    catch (Exception ex)
    {
        Log.e(TAG, "Error getting mobile data state", ex);
    }

    return false;
}

For this code to work correctly, you will need to add the permission in the manifest:

MODIFY_PHONE_STATE

There is also a question on your topic where a completely working method is given (I tested it myself and everything works stably):

ConnectivityManager dataManager;
dataManager  = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
Method dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
dataMtd.setAccessible(true);
dataMtd.invoke(dataManager, true);        //True - to enable data connectivity
 0
Author: Andrew, 2019-09-11 10:28:58