How to switch from 3G and 2G/EDGE vice versa?

前端 未结 2 1527
终归单人心
终归单人心 2021-02-10 16:20

I am trying to switch the network preference from 3G to 2G/EDGE through code and vice versa. I can able to switch on and off the mobile data connection. Now i need know how to s

相关标签:
2条回答
  • 2021-02-10 16:39

    As far as I know cannot do this as it is a restricted setting. You need a special permission, to change it. Take a look at this post.

    edit: Updated link, working now

    0 讨论(0)
  • I've stumbled upon a way to solve this with reflection and system call commands, and decided to report it even though the thread is old and there are some caveats:

    1. Root required
    2. Hackish and maybe ROM-specific (tested on CM 12.1 titan)
    3. Probably not working on all android versions (tested on 5.1.1)

    Much of the code is borrowed from / inspired by this answer by ChuongPham.

    First we need to get the correct transaction code by getting the value of a declared field of the ITelephony class. Since I suspect the name of the field might be slightly different depending on the platform (for mine the field name is "TRANSACTION_setPreferredNetworkType_96"), I provide a solution that is as flexible as possible:

    private static String get3gTransactionCode(Context context) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException {
        final TelephonyManager mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        final Class<?> mTelephonyClass = Class.forName(mTelephonyManager.getClass().getName());
        final Method mTelephonyMethod = mTelephonyClass.getDeclaredMethod("getITelephony");
        mTelephonyMethod.setAccessible(true);
        final Object mTelephonyStub = mTelephonyMethod.invoke(mTelephonyManager);
        final Class<?> mTelephonyStubClass = Class.forName(mTelephonyStub.getClass().getName());
        final Class<?> mClass = mTelephonyStubClass.getDeclaringClass();
        for (Field f:mClass.getDeclaredFields()) {
            if (f.getName().contains("setPreferredNetworkType")) {
                final Field field = mClass.getDeclaredField(f.getName());
                field.setAccessible(true);
                return String.valueOf(field.getInt(null));
            }
        }
        throw new NoSuchFieldException();
    }
    

    Next we can use the transaction code in a system call via su:

    private static void setPreferredNetworkType(Context context, int preferredType) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException, IllegalAccessException, InvocationTargetException {
        String transactionCode = get3gTransactionCode(context);
        String command = "service call phone " + transactionCode + " i32 " + preferredType;
        executeCommandViaSu(context, "-c", command);
    }
    

    In my case, I call that method with the 2nd parameter being 1 for 2G, and 10 for 3G preference. The constants for different network types can be found here.

    For convenience and completeness I also copy-paste the executeCommandViaSu method from ChuongPham's answer here:

    private static void executeCommandViaSu(Context context, String option, String command) {
        boolean success = false;
        String su = "su";
        for (int i=0; i < 3; i++) {
            // Default "su" command executed successfully, then quit.
            if (success) {
                break;
            }
            // Else, execute other "su" commands.
            if (i == 1) {
                su = "/system/xbin/su";
            } else if (i == 2) {
                su = "/system/bin/su";
            }
            try {
                // Execute command as "su".
                Runtime.getRuntime().exec(new String[]{su, option, command});
            } catch (IOException e) {
                success = false;
                // Oops! Cannot execute `su` for some reason.
                // Log error here.
            } finally {
                success = true;
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题