Change mobile network mode (gsm, wcdma, auto)

后端 未结 4 1401
陌清茗
陌清茗 2020-12-09 04:51

I want to change the preferred network mode ie. gsm or wcdma or auto, programmatically, from code, on Android.

Is this possible, and if so how ?

4条回答
  •  一个人的身影
    2020-12-09 05:35

    It is possible, I did it.

    For this to work, your app must be signed with the system key or have carrier privilege. Otherwise the app will throw java.lang.SecurityException: No modify permission or carrier privilege.

    My app runs on Android 5.1 Lollipop(API 22) and is signed with the system key, so this is the only configuration I can confirm for sure that works. I can't confirm the carrier privilege approach.

    AndroidManifest.xml

    Add this permission to your app manifest. If you are using Android Studio, it will probably mark this line as an error because only system apps can have this permission. If you can sign your app with the system keys, don't worry.

    
    

    Get Preferred Network

    The return is defined in RILConstants.java, e.g. RILConstants.NETWORK_MODE_WCDMA_PREF

    public int getPreferredNetwork() {
        Method method = getHiddenMethod("getPreferredNetworkType", TelephonyManager.class, null);
        int preferredNetwork = -1000;
        try {
            preferredNetwork = (int) method.invoke(mTelephonyManager);
            Log.i(TAG, "Preferred Network is ::: " + preferredNetwork);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    
        return preferredNetwork;
    }
    

    Set Preferred Method.

    The parameter must be based on RILConstants.java, e.g.: RILConstants.NETWORK_MODE_LTE_ONLY

    public void setPreferredNetwork(int networkType) {
        try {
            Method setPreferredNetwork = getHiddenMethod("setPreferredNetworkType",
                    TelephonyManager.class, new Class[] {int.class});
            Boolean success = (Boolean)setPreferredNetwork.invoke(mTelephonyManager,
                    networkType);
            Log.i(TAG, "Could set Network Type ::: " + (success.booleanValue() ? "YES" : "NO"));
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    

    This is an utility method to access the hidden API methods.

    /**
     * Get a hidden method instance from a class
     * @param methodName The name of the method to be taken from the class
     * @param fromClass The name of the class that has the method
     * @return A Method instance that can be invoked
     */
    public Method getHiddenMethod(String methodName, Class fromClass, Class[] params) {
        Method method = null;
        try {
            Class clazz = Class.forName(fromClass.getName());
            method = clazz.getMethod(methodName, params);
            method.setAccessible(true);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    
        return method;
    }
    

提交回复
热议问题