Reset Android mobile network signal?
Asked Answered
B

2

6

I need my app to reset the device's mobile network signal. This would have the same effect as toggling airplane mode where connectivity is temporarily lost, a new IP address is assigned upon reconnection, and the LTE/signal icon in the status bar should disappear and then reappear upon reconnection. I found an app on the Play Store that I tested on my phone running Android 4.4.4 with CyanogenMod and it does exactly this, but I am unsure as to how I can implement this in my own app. I think it's related to the CHANGE_NETWORK_STATE permission. I am seeking documentation or some simple example code that will reset the network connection.

Note that I am not specifically trying to toggle airplane mode, but rather to reset the mobile data in the way that the app linked above does, as I have tested that it indeed works without even requiring root privileges.

Botel answered 24/1, 2015 at 23:12 Comment(5)
Would you please provide a comment explaining your downvote so that I can improve the question? I see that you have marked it as "Too Broad" in your close vote. I feel that my question is well-focused and asks how to achieve a very specific task for which I gave given examples (connection temporarily lost, new IP, signal icon changes). I have added a concluding sentence that better asks what kind of answer I am seeking (docs or example code). Does this change narrow its broadness? If not, how could I improve it?Botel
One improvement would be to show us some code of your current attemptsFlorrie
@Florrie I have looked though about 10 different StackOverflow questions and other posts on Google, most of them about about toggling airplane mode which isn't possible in newer versions of Android, and attempted to use the code mentioned in those, but they're all out of date or they don't work. I really don't have any code that I've attempted because I don't know what part of the API to use. I did, however, find the app linked to in the original question which works without requiring root to reset the signal, which means it is possible, but I don't know what part of the API to use with it.Botel
Has anybody found a way to do this on Marshmallow 6.0 or newer? The app linked to in the question works on android 6/7 but the provided answer does not without root.Visser
@Keavon, Even i need to implement a similar scenario in Android 10. I have different buttons to select a preferred mobile network type like 4g, 3g and 2g. I want that once when we select the button mobile network should refresh and change to select that network type. but as an initial step i want to refresh network. Need your helpGewgaw
R
3

Lollipop support requires a new System level privledge android.permission.MODIFY_PHONE_STATE to work.

private static boolean setMobileConnectionEnabled(Context context, boolean enabled)
{
    try{
        // Requires: android.permission.CHANGE_NETWORK_STATE
        if(Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD){
            // pre-Gingerbread sucks!
            final TelephonyManager telMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            final Method getITelephony = telMgr.getClass().getDeclaredMethod("getITelephony");
            getITelephony.setAccessible(true);
            final Object objITelephony = getITelephony.invoke(telMgr);
            final Method toggleDataConnectivity = objITelephony.getClass()
                .getDeclaredMethod(enabled ? "enableDataConnectivity" : "disableDataConnectivity");
            toggleDataConnectivity.setAccessible(true);
            toggleDataConnectivity.invoke(objITelephony);
        }
        // Requires: android.permission.CHANGE_NETWORK_STATE
        else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
            final ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
            // Gingerbread to KitKat inclusive
            final Field serviceField = connMgr.getClass().getDeclaredField("mService");
            serviceField.setAccessible(true);
            final Object connService = serviceField.get(connMgr);
            try{
                final Method setMobileDataEnabled = connService.getClass()
                    .getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
                setMobileDataEnabled.setAccessible(true);
                setMobileDataEnabled.invoke(connService, Boolean.valueOf(enabled));
            }
            catch(NoSuchMethodException e){
                // Support for CyanogenMod 11+
                final Method setMobileDataEnabled = connService.getClass()
                    .getDeclaredMethod("setMobileDataEnabled", String.class, Boolean.TYPE);
                setMobileDataEnabled.setAccessible(true);
                setMobileDataEnabled.invoke(connService, context.getPackageName(), Boolean.valueOf(enabled));
            }
        }
        // Requires: android.permission.MODIFY_PHONE_STATE (System only, here for completions sake)
        else{
            // Lollipop and into the Future!
            final TelephonyManager telMgr = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
            final Method setDataEnabled = telMgr.getClass().getDeclaredMethod("setDataEnabled", Boolean.TYPE);
            setDataEnabled.setAccessible(true);
            setDataEnabled.invoke(telMgr, Boolean.valueOf(enabled));
        }
        return true;
    }
    catch(NoSuchFieldException e){
        Log.e(TAG, "setMobileConnectionEnabled", e);
    }
    catch(IllegalAccessException e){
        Log.e(TAG, "setMobileConnectionEnabled", e);
    }
    catch(IllegalArgumentException e){
        Log.e(TAG, "setMobileConnectionEnabled", e);
    }
    catch(NoSuchMethodException e){
        Log.e(TAG, "setMobileConnectionEnabled", e);
    }
    catch(InvocationTargetException e){
        Log.e(TAG, "setMobileConnectionEnabled", e);
    }
    return false;
}

Permission required.

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
Recital answered 27/1, 2015 at 0:47 Comment(1)
Does this change only refresh the state(enable and disable) mobile data or refresh the mobile network itself as it happens in Airplane mode where mobile network is disabled and then made available again???Gewgaw
M
1

Starting with 4.4.2, one can no longer acquire permissions to toggle airplane mode or mobile data. However, using reflection, one can work around that limitation.

Here's how to toggle airplane mode: Toggle airplane mode in Android

Here's a method to toggle mobile data pre 4.4.2 and post (using reflection): Toggle mobile data programmatically on Android 4.4.2

Note, I found all that in less than 3 minutes by searching on my favorite search engine for "android toggle airplane mode" and "android toggle mobile data".

Note 2: You can use reflection for airplane mode toggling too, but you may need to do some digging to find the necessary ASOP API or see if someone else (like CyanogenMod) has already done it.

Marj answered 26/1, 2015 at 23:27 Comment(2)
Maybe you could provide a link to your search engine. If I use your search terms in Google I don't get results for coding (as almost always on Android topics if I don't add something from SDK/API). The terms are much to general.Korman
@TheincredibleJan I used google. Also, I wrote that answer two years ago so search results may have changed slightly Nevertheless, today, with the first search term, the very first result is still the link I have for "Here's how to toggle airplane mode". Using the second search term, I didn't get my link. However, adding the word "programmatically" got me the same link in my answer as the first result. The point was that it was trivially easy to find the answer to the question using a search engine. If you need help learning how to craft search terms. . .use your favorite search engine.Marj

© 2022 - 2024 — McMap. All rights reserved.