You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android Studio中用按钮实现安卓5.0及以上系统移动数据开关

问题排查与解决

现有代码核心问题

  • ConnectivityManager.requestNetwork() API 不是用来操作系统层面移动数据开关的接口:它的作用是在用户已经开启移动数据的前提下,请求系统为你的应用单独分配蜂窝网络通道,允许你的应用优先通过蜂窝传输数据,不会触发系统移动数据开关的状态变更,所以你点击按钮看不到任何系统层面的变化。
  • 你使用了匿名NetworkCallback实例,既没有处理请求结果回调,也没有在页面销毁时释放请求,会产生内存泄漏。

实现移动数据开关的适配方案

首先明确权限限制:Android 系统从高版本开始逐步收紧第三方应用修改移动数据开关的权限,不同版本适配规则如下:

  • Android 5.0 ~ Android 7.1.1(API 21~25):普通应用申请对应权限后,可通过反射调用系统隐藏API实现开关控制
  • Android 8.0 ~ Android 9(API 26~28):需要应用获取WRITE_SECURE_SETTINGS权限(普通应用无法通过应用市场上架流程获取,只能通过adb命令手动授权)
  • Android 10及以上(API 29+):系统完全禁止第三方应用修改移动数据开关,只有系统预装应用、运营商签名应用可使用该能力

适配代码实现

1. 补充Manifest权限

在你现有权限基础上新增:

<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />

2. 移动数据开关工具类

public class MobileDataUtil {
    // 切换移动数据开关状态,不会修改WiFi状态
    public static void setMobileDataEnabled(Context context, boolean enabled) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Android 10及以上第三方应用无法修改,可提示用户手动跳转设置页
            Intent intent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
            context.startActivity(intent);
            return;
        }
        try {
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Method setDataEnabledMethod = TelephonyManager.class.getDeclaredMethod("setDataEnabled", boolean.class);
            setDataEnabledMethod.invoke(telephonyManager, enabled);
        } catch (Exception e) {
            // 权限不足时捕获异常
            e.printStackTrace();
        }
    }

    // 获取当前移动数据开关状态
    public static boolean isMobileDataEnabled(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        try {
            Method getMobileDataEnabledMethod = ConnectivityManager.class.getDeclaredMethod("getMobileDataEnabled");
            return (boolean) getMobileDataEnabledMethod.invoke(cm);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

3. 修正后的MainActivity代码

public class MainActivity extends AppCompatActivity {
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.download);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                boolean currentState = MobileDataUtil.isMobileDataEnabled(MainActivity.this);
                MobileDataUtil.setMobileDataEnabled(MainActivity.this, !currentState);
            }
        });
    }
}

补充说明

如果你的应用仅需要自身业务使用蜂窝网络,不需要修改系统全局的移动数据开关,可以保留原有的requestNetwork逻辑,通过绑定蜂窝网络通道实现应用内流量走蜂窝、其他应用仍走WiFi的效果,且不需要修改系统开关,适配全版本Android系统。

内容的提问来源于stack exchange,提问作者SRI VINOD PALACHARLA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 19:42:03