Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 4.0 4G toggle

Tags:

android

4g

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.

like image 888
Jimmy D Avatar asked Dec 22 '11 16:12

Jimmy D


3 Answers

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.

like image 63
Tom Avatar answered Oct 14 '22 05:10

Tom


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...

like image 39
yi01 Avatar answered Oct 14 '22 05:10

yi01


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

like image 25
Muzikant Avatar answered Oct 14 '22 06:10

Muzikant