How to permanently disable 2G connection while retaining others?

Search This thread

LSS4181

Senior Member
Mar 13, 2012
406
132
Google Pixel C
Razer Phone 2
I'm looking for a way to permanently disable 2G connection while retaining 3G/4G connection. I know about the *#*#4636#*#* access to Phone Information where I can manually make my phone to use LTE/WCDMA as opposed to the default LTE/UMTS auto (PRL), as the latter allows downgrading to 2G(GSM) if needed.

As Android apparently doesn't save SIM-related settings in memory, the settings done in the Phone Information will not survive a reboot or a SIM reload (e.g. turning Airplane mode on then off). Apparently, toggling 4G modes there would also revert the settings, although to me it looks like toggling there is equivalent to setting the default ones (such as LTE/UMTS auto (PRL) for 4G) in Phone Information, so the settings defined in Settings -> Mobile Network have a higher priority.

So far the Mobile Networks have only the options to "use 2G only", but what I wanted is the exact opposite. I want to use everything but 2G. Is there any way to extend the Mobile Networks setting to allow choosing every possible option provided in the Phone Information, so it can stay permanent?

The reason for doing so is because 2G is apparently unsafe (unencrypted) and there were reported cases that an attacker could jam the signals to force nearby devices to use 2G, then sniff sensitive information (including but not limited to two-factor verification code SMS) to gain unauthorized access to accounts and such using IMSI catchers. Not having an option to make the setting permanent leaves people vulnerable to such attacks.
 
Last edited:

LSS4181

Senior Member
Mar 13, 2012
406
132
Google Pixel C
Razer Phone 2
Possible solutions.

A very, very late bump of my own thread.

I think I found some possible solutions, and they can be easy to test if you can build a custom ROM for your own device.

1. Setting KEY_PREFER_2G_BOOL to false globally
Go to frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java, look for the key KEY_PREFER_2G_BOOL.
The default is set to true, set this to false, like this:
Code:
sDefaults.putBoolean(KEY_PREFER_2G_BOOL, false);
This would make this parameter defaults to false, even for carriers whose config file didn't explicitly set it to false (will be explained below).

2. Setting KEY_PREFER_2G_BOOL to false only for your carrier
Go to folder packages/apps/CarrierConfig/assets/. Look for a carrier config that matches your carrier's MCC and MNC (carrier_config_310260.xml), add this line into it.
Code:
<boolean name="prefer_2g_bool" value="false"/>
You can also refer to some other carriers' files, as some carriers already have this line defined in it.

For the above two methods, however, some detailed tests are needed to make sure the phone can really never downgrade to 2G signal under such conditions, as on the surface (at least from the looks of the respective source code files), what these do is simply removing the "2G/GSM Only" option from the "Preferred network type" spinner, but it'll still be using the network mode values that would permit 2G/GSM (refer to RILConstants.java for details).

EDIT: Unfortunately, I discovered that it's still possible for the device to fall back to 2G under certain situations, even with the above methods which removed 2G from the options.

3. Modify the values contained in the framework/service packages
If you can decompile/recompile your current ROM's respective framework/service packages, you can modify it this way.
Go to folder packages/services/Telephony/res/values/strings.xml (if you have the source code).
Look for this block (for example). You may need to look for the respective variants depending on your device/SIM type (GSM, CDMA, With or without 4G/LTE, etc).
Code:
<string-array name="enabled_networks_choices" translatable="false">
        <item>@string/network_lte</item>
        <item>@string/network_3G</item>
        <item>@string/network_2G</item>
    </string-array>
    <string-array name="enabled_networks_4g_choices" translatable="false">
        <item>@string/network_4G</item>
        <item>@string/network_3G</item>
        <item>@string/network_2G</item>
    </string-array>
    <string-array name="enabled_networks_values" translatable="false">
        <item>"9"</item>
        <item>"0"</item>
        <item>"1"</item>
    </string-array>
Note the enabled_networks_values part. Change it to match the ones you need. The details can be found frameworks/base/telephony/java/com/android/internal/telephony/RILConstants.java. Change the values to the ones that matches the modes you want. In the above example, the first value is for 4G/LTE, the second value is for 3G, and the last value is for GSM.

Code:
    /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
    int NETWORK_MODE_WCDMA_PREF     = 0; /* GSM/WCDMA (WCDMA preferred) */
    int NETWORK_MODE_GSM_ONLY       = 1; /* GSM only */
    int NETWORK_MODE_WCDMA_ONLY     = 2; /* WCDMA only */
    int NETWORK_MODE_GSM_UMTS       = 3; /* GSM/WCDMA (auto mode, according to PRL)
                                            AVAILABLE Application Settings menu*/
    int NETWORK_MODE_CDMA           = 4; /* CDMA and EvDo (auto mode, according to PRL)
                                            AVAILABLE Application Settings menu*/
    int NETWORK_MODE_CDMA_NO_EVDO   = 5; /* CDMA only */
    int NETWORK_MODE_EVDO_NO_CDMA   = 6; /* EvDo only */
    int NETWORK_MODE_GLOBAL         = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
                                            AVAILABLE Application Settings menu*/
    int NETWORK_MODE_LTE_CDMA_EVDO  = 8; /* LTE, CDMA and EvDo */
    int NETWORK_MODE_LTE_GSM_WCDMA  = 9; /* LTE, GSM/WCDMA */
    int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
    int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
    int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
    int NETWORK_MODE_TDSCDMA_ONLY            = 13; /* TD-SCDMA only */
    int NETWORK_MODE_TDSCDMA_WCDMA           = 14; /* TD-SCDMA and WCDMA */
    int NETWORK_MODE_LTE_TDSCDMA             = 15; /* TD-SCDMA and LTE */
    int NETWORK_MODE_TDSCDMA_GSM             = 16; /* TD-SCDMA and GSM */
    int NETWORK_MODE_LTE_TDSCDMA_GSM         = 17; /* TD-SCDMA,GSM and LTE */
    int NETWORK_MODE_TDSCDMA_GSM_WCDMA       = 18; /* TD-SCDMA, GSM/WCDMA */
    int NETWORK_MODE_LTE_TDSCDMA_WCDMA       = 19; /* TD-SCDMA, WCDMA and LTE */
    int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA   = 20; /* TD-SCDMA, GSM/WCDMA and LTE */
    int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA  = 21; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
    int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
    int PREFERRED_NETWORK_MODE = Integer.parseInt(TelephonyManager.getTelephonyProperty(0,
            "ro.telephony.default_network", Integer.toString(NETWORK_MODE_WCDMA_PREF)));


EDIT: I confirmed that via method 1 the 2G option would be removed from the "Preferred network type" options, but I still need to test whether the device really can no longer downgrade to 2G. Since method 1 works, method 2 should also work as it's based on the same principle. The system would see the KEY_PREFER_2G_BOOL parameter as false and remove the 2G option from the list.

EDIT 2: After some testing it doesn't seem to work. It seems it's also allowed to specify network settings inside the device trees via overlays (or build.prop parameters, such as ro.telephony.default_network), when building ROM. As such, the values set in device-specific scopes take a higher priority.

EDIT 3: It seems you need to do both: After modifying framework files like that in Method 3, you also need to change the "ro.telephony.default_network" parameter in build.prop (preferrably also in vendor build.prop), in order to let the custom network mode persist.
 
Last edited:
  • Like
Reactions: wzawzdb

Top Liked Posts

  • There are no posts matching your filters.
  • 1
    Possible solutions.

    A very, very late bump of my own thread.

    I think I found some possible solutions, and they can be easy to test if you can build a custom ROM for your own device.

    1. Setting KEY_PREFER_2G_BOOL to false globally
    Go to frameworks/base/telephony/java/android/telephony/CarrierConfigManager.java, look for the key KEY_PREFER_2G_BOOL.
    The default is set to true, set this to false, like this:
    Code:
    sDefaults.putBoolean(KEY_PREFER_2G_BOOL, false);
    This would make this parameter defaults to false, even for carriers whose config file didn't explicitly set it to false (will be explained below).

    2. Setting KEY_PREFER_2G_BOOL to false only for your carrier
    Go to folder packages/apps/CarrierConfig/assets/. Look for a carrier config that matches your carrier's MCC and MNC (carrier_config_310260.xml), add this line into it.
    Code:
    <boolean name="prefer_2g_bool" value="false"/>
    You can also refer to some other carriers' files, as some carriers already have this line defined in it.

    For the above two methods, however, some detailed tests are needed to make sure the phone can really never downgrade to 2G signal under such conditions, as on the surface (at least from the looks of the respective source code files), what these do is simply removing the "2G/GSM Only" option from the "Preferred network type" spinner, but it'll still be using the network mode values that would permit 2G/GSM (refer to RILConstants.java for details).

    EDIT: Unfortunately, I discovered that it's still possible for the device to fall back to 2G under certain situations, even with the above methods which removed 2G from the options.

    3. Modify the values contained in the framework/service packages
    If you can decompile/recompile your current ROM's respective framework/service packages, you can modify it this way.
    Go to folder packages/services/Telephony/res/values/strings.xml (if you have the source code).
    Look for this block (for example). You may need to look for the respective variants depending on your device/SIM type (GSM, CDMA, With or without 4G/LTE, etc).
    Code:
    <string-array name="enabled_networks_choices" translatable="false">
            <item>@string/network_lte</item>
            <item>@string/network_3G</item>
            <item>@string/network_2G</item>
        </string-array>
        <string-array name="enabled_networks_4g_choices" translatable="false">
            <item>@string/network_4G</item>
            <item>@string/network_3G</item>
            <item>@string/network_2G</item>
        </string-array>
        <string-array name="enabled_networks_values" translatable="false">
            <item>"9"</item>
            <item>"0"</item>
            <item>"1"</item>
        </string-array>
    Note the enabled_networks_values part. Change it to match the ones you need. The details can be found frameworks/base/telephony/java/com/android/internal/telephony/RILConstants.java. Change the values to the ones that matches the modes you want. In the above example, the first value is for 4G/LTE, the second value is for 3G, and the last value is for GSM.

    Code:
        /* NETWORK_MODE_* See ril.h RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE */
        int NETWORK_MODE_WCDMA_PREF     = 0; /* GSM/WCDMA (WCDMA preferred) */
        int NETWORK_MODE_GSM_ONLY       = 1; /* GSM only */
        int NETWORK_MODE_WCDMA_ONLY     = 2; /* WCDMA only */
        int NETWORK_MODE_GSM_UMTS       = 3; /* GSM/WCDMA (auto mode, according to PRL)
                                                AVAILABLE Application Settings menu*/
        int NETWORK_MODE_CDMA           = 4; /* CDMA and EvDo (auto mode, according to PRL)
                                                AVAILABLE Application Settings menu*/
        int NETWORK_MODE_CDMA_NO_EVDO   = 5; /* CDMA only */
        int NETWORK_MODE_EVDO_NO_CDMA   = 6; /* EvDo only */
        int NETWORK_MODE_GLOBAL         = 7; /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL)
                                                AVAILABLE Application Settings menu*/
        int NETWORK_MODE_LTE_CDMA_EVDO  = 8; /* LTE, CDMA and EvDo */
        int NETWORK_MODE_LTE_GSM_WCDMA  = 9; /* LTE, GSM/WCDMA */
        int NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA = 10; /* LTE, CDMA, EvDo, GSM/WCDMA */
        int NETWORK_MODE_LTE_ONLY       = 11; /* LTE Only mode. */
        int NETWORK_MODE_LTE_WCDMA      = 12; /* LTE/WCDMA */
        int NETWORK_MODE_TDSCDMA_ONLY            = 13; /* TD-SCDMA only */
        int NETWORK_MODE_TDSCDMA_WCDMA           = 14; /* TD-SCDMA and WCDMA */
        int NETWORK_MODE_LTE_TDSCDMA             = 15; /* TD-SCDMA and LTE */
        int NETWORK_MODE_TDSCDMA_GSM             = 16; /* TD-SCDMA and GSM */
        int NETWORK_MODE_LTE_TDSCDMA_GSM         = 17; /* TD-SCDMA,GSM and LTE */
        int NETWORK_MODE_TDSCDMA_GSM_WCDMA       = 18; /* TD-SCDMA, GSM/WCDMA */
        int NETWORK_MODE_LTE_TDSCDMA_WCDMA       = 19; /* TD-SCDMA, WCDMA and LTE */
        int NETWORK_MODE_LTE_TDSCDMA_GSM_WCDMA   = 20; /* TD-SCDMA, GSM/WCDMA and LTE */
        int NETWORK_MODE_TDSCDMA_CDMA_EVDO_GSM_WCDMA  = 21; /*TD-SCDMA,EvDo,CDMA,GSM/WCDMA*/
        int NETWORK_MODE_LTE_TDSCDMA_CDMA_EVDO_GSM_WCDMA = 22; /* TD-SCDMA/LTE/GSM/WCDMA, CDMA, and EvDo */
        int PREFERRED_NETWORK_MODE = Integer.parseInt(TelephonyManager.getTelephonyProperty(0,
                "ro.telephony.default_network", Integer.toString(NETWORK_MODE_WCDMA_PREF)));


    EDIT: I confirmed that via method 1 the 2G option would be removed from the "Preferred network type" options, but I still need to test whether the device really can no longer downgrade to 2G. Since method 1 works, method 2 should also work as it's based on the same principle. The system would see the KEY_PREFER_2G_BOOL parameter as false and remove the 2G option from the list.

    EDIT 2: After some testing it doesn't seem to work. It seems it's also allowed to specify network settings inside the device trees via overlays (or build.prop parameters, such as ro.telephony.default_network), when building ROM. As such, the values set in device-specific scopes take a higher priority.

    EDIT 3: It seems you need to do both: After modifying framework files like that in Method 3, you also need to change the "ro.telephony.default_network" parameter in build.prop (preferrably also in vendor build.prop), in order to let the custom network mode persist.