5

This is for the Verizon LTE version of the Samsung Galaxy Nexus.

I am tasked with writing a tiny app that will effectively disable/enable 4G capability. This can be done manually via settings > mobile network > network mode and choosing either LTE/CDMA (4g enabled) or CDMA (3g only).

I have not tried anything yet because Android development isn't my strong suit. I am looking for guidance... examples, code samples etc. I am assuming this should almost be a one-liner, but it has been my experience that with Android development nothing is as simple as it appears.

Any help will be greatly appreciated.

manlio
  • 18,345
  • 14
  • 76
  • 126
Jimmy D
  • 5,282
  • 16
  • 54
  • 70
  • AFAIK, ordinary Android SDK applications cannot change this. – CommonsWare Dec 22 '11 at 17:01
  • Ah, very interesting. I hope that's not the case. Researching now. I heard a widget exists for HTC phones, which leads me to believe it *can* be done. – Jimmy D Dec 22 '11 at 17:13
  • 1
    If the app widget in question ships with HTC phones, that is not an ordinary Android SDK application. – CommonsWare Dec 22 '11 at 17:15
  • @CommonsWare, correct. However my point was only to say that this is POSSIBLE to do programatically. – Jimmy D Dec 23 '11 at 13:59
  • SixHouse, did you ever find an easy way to do this? I am looking for same and, like you, assumed it would be a one liner. Any help? – Doug Mar 03 '12 at 14:18
  • I too am looking for this same thing, have been for some time. This looks promising, and I know personally, I wouldn't mind having to have root access. Please let us know if you got this working. – BriCo84 Jan 31 '13 at 12:58

4 Answers4

5

There is a preference in the Settings.Secure class that is hidden from the SDK:

    /**
     * The preferred network mode   7 = Global
     *                              6 = EvDo only
     *                              5 = CDMA w/o EvDo
     *                              4 = CDMA / EvDo auto
     *                              3 = GSM / WCDMA auto
     *                              2 = WCDMA only
     *                              1 = GSM only
     *                              0 = GSM / WCDMA preferred
     * @hide
     */
    public static final String PREFERRED_NETWORK_MODE =
            "preferred_network_mode";

You could use Reflection on this or just localize the constant to your project. The problem with this is that you cannot change the value of this setting (as with all secure settings), you can only read it. The aforementioned values are not the only possible ones, there are actually a few more located in com.android.internal.telephony.RILConstants, which is again hidden from the SDK and would require Reflection to access.

There is another hidden method in TelephonyManager, but again it is read only there is no other method for setting this constant. This would tell you exactly what you want to know, whether the device is set to "LTE/ CDMA" (LTE_ON_CDMA_TRUE) or "CDMA only" (LTE_ON_CDMA_FALSE):

/**
 * Return if the current radio is LTE on CDMA. This
 * is a tri-state return value as for a period of time
 * the mode may be unknown.
 *
 * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE}
 * or {@link Phone#LTE_ON_CDMA_TRUE}
 *
 * @hide
 */
public int getLteOnCdmaMode() {
    try {
        return getITelephony().getLteOnCdmaMode();
    } catch (RemoteException ex) {
        // Assume no ICC card if remote exception which shouldn't happen
        return Phone.LTE_ON_CDMA_UNKNOWN;
    } catch (NullPointerException ex) {
        // This could happen before phone restarts due to crashing
        return Phone.LTE_ON_CDMA_UNKNOWN;
    }
}

From my research you could not make such an application without root access and using something like setprop from the command line, but even then you may need to restart the entire Telephony process in order for this setting to take effect.

Finally, if you are still interested see com.android.phone.Settings to see how the system handles this toggle. It is rather elaborate, and as I mentioned would require permissions that a normal Android application would not be granted.

Tom
  • 6,947
  • 7
  • 46
  • 76
2

I'm also interested in changing the settings WCDMA-only, WCDMA/LTE, ...

I found the way to change Settings.secure.* with root privilege as is shown the below.

    new ExecuteAsRootBase() {
        @Override
        protected ArrayList<String> getCommandsToExecute() {
            ArrayList<String> cmds = new ArrayList<String>();
            cmds.add("su -c 'chmod 755 "+mySqlite+"'");
            cmds.add("echo \"UPDATE secure SET value='"+ value +"' WHERE name='"+ key +"'; \" | "+mySqlite+" /data/data/com.android.providers.settings/databases/settings.db");
            //TODO: SQL injection can be done!!!
            return cmds;
        }
    }.execute();

ExecuteAsRootBase is introduced here, and mySqlite is "/data/data/"+context.getPackageName()+"/files/sqlite3" where sqlite3 is put in advance.

However, it seems that we have to call com.android.internal.telephony.Phone.setPreferredNetworkType() for switching (WCDMA only<=>WCDMA/LTE) after setting Settings.secure.PREFERRED_NETWORK_MODE. My phone (even set Settings.secure.PREFERRED_NETWORK_MODE = 2) attached to LTE network...

yi01
  • 21
  • 1
1

All the other answers are correct that this requires access to Settings.Secure. Take a look at how the phone app handles this setting https://github.com/dzo/packages_apps_phone/blob/master/src/com/android/phone/Use2GOnlyCheckBoxPreference.java

or take a look at the Toggle2G app source: https://github.com/TheMasterBaron/Toggle-2G

Muzikant
  • 8,070
  • 5
  • 54
  • 88
-1

http://developer.android.com/reference/android/provider/Settings.System.html

Aside from writing the code in your Activity.java, you will probably have to ask for permission to access these settings in the AndroidManifest.xml. So it's annoying but should be simple enough.