5

我需要我的应用程序来重置设备的移动网络信号。这与切换飞行模式的效果相同,其中连接暂时丢失,重新连接时分配一个新的 IP 地址,状态栏中的 LTE/信号图标应该消失,然后在重新连接时重新出现。我在 Play Store 上找到了一个应用程序,我在运行 Android 4.4.4 和 CyanogenMod 的手机上进行了测试,它确实做到了这一点,但我不确定如何在我自己的应用程序中实现它。我认为这与CHANGE_NETWORK_STATE许可有关。我正在寻找将重置网络连接的文档或一些简单的示例代码。

请注意,我并不是专门尝试切换飞行模式,而是以上面链接的应用程序的方式重置移动数据,因为我已经测试过它确实可以工作,甚至不需要 root 权限。

4

2 回答 2

3

Lollipop 支持需要新的系统级权限android.permission.MODIFY_PHONE_STATE才能工作。

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;
}

需要许可。

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
于 2015-01-27T00:47:42.437 回答
1

从 4.4.2 开始,无法再获得切换飞行模式或移动数据的权限。但是,使用反射,可以解决这个限制。

以下是切换飞行模式的方法: 在 Android 中切换飞行模式

这是在 4.4.2 之前切换移动数据和发布(使用反射)的方法: 在 Android 4.4.2 上以编程方式切换移动数据

请注意,我通过在我最喜欢的搜索引擎上搜索“android 切换飞行模式”和“android 切换移动数据”在不到 3 分钟的时间内找到了所有这些。

注意 2:您也可以使用反射来切换飞行模式,但您可能需要进行一些挖掘以找到必要的 ASOP API 或查看其他人(如 CyanogenMod)是否已经完成了它。

于 2015-01-26T23:27:33.760 回答