Search code examples
androidconnectivity

Detecting "use only 2G networks" setting


Is there a way of returning the value of Android's mobile network setting for "use only 2G networks"?

The app being developed measures the internet speed at a certain location, but in order for this to be relevant, it must know if the user is deliberately restricting mobile internet to 2G.

I've taken a look at ConnectivityManager, but it only provides information about the background data setting or all networks. Iterating through them reveals that despite the setting being enabled, HSPA and UMTS return true for isAvailable():

for (NetworkInfo netInfo : cm.getAllNetworkInfo()) {
    Log.i(TAG, netInfo.getSubtypeName() + ": " + netInfo.isAvailable());
}

The only hint I've found amidst all this is that netInfo.getReason() returns "connectionDisabled" on HSPA and UMTS when the setting is enabled. The trouble is, when the setting is disabled, those network types don't necessarily appear in the list at all. It doesn't seem right to me to use a string comparison specifically on HSPA and UMTS for "connectionDisabled".

What's the right way of tackling this?


Solution

  • For a small subset of devices (specifically for the LG Optimus 2X Speed, LG-P990), an answer seems to be:

    int enabled = Settings.Secure.getInt(getContentResolver(),
            "preferred_network_mode", -1);
    Log.d("MYAPP", "2G only enabled: " + enabled);
    

    Where the "use only 2G networks" setting is specified as:

    • 0 indicates the setting is disabled
    • 1 indicates the setting is enabled
    • -1 indicates the setting is not set (some devices?)

    How I discovered this? I gathered all the key/value pairs from Settings.Secure using the following:

    ContentResolver cr = getContentResolver();
    Cursor cursor = cr.query(Settings.Secure.CONTENT_URI, null, null, null, null);
    if (cursor.moveToFirst()) {
        while (!cursor.isAfterLast()) {
            Log.d("MYAPP", "cursor: "
                    + cursor.getString(0) + ", "
                    + cursor.getString(1) + ", "
                    + cursor.getString(2));
            cursor.moveToNext();
        }
    }
    

    I compared results between enabling and disabling the setting, and sure enough I got:

    07-08 00:15:20.991: DEBUG/MYAPP(13813): cursor: 5154, preferred_network_mode, 1

    Do NOT use the index column (5154 in the example above), as I've noticed it changes between toggling the setting.

    Although this correlates with some documentation for Settings.Secure I found online, this value isn't respected by all phones.

    If your device returns -1, perhaps listing the key value pairs will reveal which setting you need. Please comment if you encounter it!