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

如何在Flutter应用中通过按钮启用/禁用网络连接?

在Flutter中实现按钮控制网络连接的启用与禁用

Flutter本身没有提供直接控制系统网络连接的API,需要通过MethodChannel调用原生平台(Android/iOS)的系统API来实现。但要注意,两大平台对应用控制网络都有严格的权限限制,普通应用可能无法直接完成开关操作,以下是具体实现方案和限制说明:

一、Flutter端核心代码

创建一个带切换按钮的页面,通过MethodChannel与原生通信,同时处理权限不足的场景:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:url_launcher/url_launcher.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('网络连接控制')),
        body: const NetworkToggleButton(),
      ),
    );
  }
}

class NetworkToggleButton extends StatefulWidget {
  const NetworkToggleButton({super.key});

  @override
  State<NetworkToggleButton> createState() => _NetworkToggleButtonState();
}

class _NetworkToggleButtonState extends State<NetworkToggleButton> {
  static const _channel = MethodChannel('com.yourpackage.network/control');
  bool _isNetworkEnabled = true;

  Future<void> _toggleNetwork() async {
    try {
      final bool success = await _channel.invokeMethod(
        'toggleNetwork',
        {'enabled': !_isNetworkEnabled},
      );
      if (success) {
        setState(() => _isNetworkEnabled = !_isNetworkEnabled);
      } else {
        _showPermissionError();
      }
    } on PlatformException catch (_) {
      _showPermissionError();
    }
  }

  void _showPermissionError() {
    showDialog(
      context: context,
      builder: (ctx) => AlertDialog(
        title: const Text('操作失败'),
        content: const Text('应用无权限直接控制网络,是否跳转到系统设置手动操作?'),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(ctx),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () {
              Navigator.pop(ctx);
              _openNetworkSettings();
            },
            child: const Text('去设置'),
          ),
        ],
      ),
    );
  }

  Future<void> _openNetworkSettings() async {
    final uri = Uri.parse(
      Theme.of(context).platform == TargetPlatform.android
          ? 'app-settings:network'
          : 'prefs:root=MOBILE_DATA_SETTINGS_ID',
    );
    if (await canLaunchUrl(uri)) {
      await launchUrl(uri);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        onPressed: _toggleNetwork,
        style: ElevatedButton.styleFrom(
          padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
          textStyle: const TextStyle(fontSize: 18),
        ),
        child: Text(_isNetworkEnabled ? '禁用网络' : '启用网络'),
      ),
    );
  }
}

二、Android端原生实现

1. 添加权限

在android/app/src/main/AndroidManifest.xml中添加必要权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<!-- 注意:MODIFY_PHONE_STATE为系统权限,普通应用无法获取 -->

2. 实现MethodChannel逻辑

修改MainActivity.kt(或Java版本):

import android.content.Context
import android.net.ConnectivityManager
import android.os.Build
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "com.yourpackage.network/control"

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "toggleNetwork") {
                val targetState = call.argument<Boolean>("enabled") ?: true
                val success = toggleMobileData(targetState)
                result.success(success)
            } else {
                result.notImplemented()
            }
        }
    }

    private fun toggleMobileData(enable: Boolean): Boolean {
        val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return try {
            // 兼容不同Android版本的API调用
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val method = ConnectivityManager::class.java.getMethod(
                    "setMobileDataEnabled", Boolean::class.javaPrimitiveType
                )
                method.invoke(cm, enable)
                true
            } else {
                val method = cm.javaClass.getMethod(
                    "setMobileDataEnabled", Boolean::class.javaPrimitiveType
                )
                method.invoke(cm, enable)
                true
            }
        } catch (e: Exception) {
            e.printStackTrace()
            false
        }
    }
}

Android平台限制

  • 从Android 6.0开始,CHANGE_NETWORK_STATE需要动态申请,但setMobileDataEnabled方法在API 24后被标记为废弃,且调用需要MODIFY_PHONE_STATE系统权限——普通应用无法通过常规渠道获取该权限,只有系统应用或拥有系统签名的应用才能使用。
  • 无法直接控制WiFi的启用/禁用,只能引导用户到系统设置页面操作。

三、iOS端说明

iOS系统严格限制第三方应用的权限,不允许任何非系统应用控制网络连接的启用与禁用。只能通过connectivity_plus等插件检测网络状态,无法主动切换。如果需要操作,只能引导用户到系统设置页面(代码已包含在Flutter端示例中)。

替代方案

如果普通应用无法获取系统权限,最佳实践是:

  1. 检测当前网络状态;
  2. 当用户点击按钮时,弹窗提示无权限,并提供跳转至系统设置页面的入口,引导用户手动操作。

内容的提问来源于stack exchange,提问作者sourabhBav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:50:25