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

如何用Flutter(非WebView)开发安卓应用控制路由器设置

解决方案:Flutter直接对接路由器管理接口实现设置功能

不用WebView的核心思路是直接调用路由器的管理API——路由器的Web管理后台本质也是通过HTTP请求和路由器通信,我们可以跳过前端页面,直接发送这些请求。以下是针对新手的分步实现指南:

1. 先抓包分析路由器的具体接口

首先需要搞清楚你的路由器提供哪些管理接口,步骤如下:

  • 用电脑连接路由器WiFi,打开路由器Web管理页(比如http://192.168.1.1)
  • 用Charles、Fiddler或者Android自带的网络抓包工具,录制你操作"修改密码"、"查看在线用户"时的HTTP请求
  • 记录下每个操作对应的:请求URL、请求方法(GET/POST)、请求参数、响应格式,以及登录时的认证信息(Cookie/Token)

2. 在Flutter中发起HTTP请求

推荐使用dio包(比原生http包更易用),先在pubspec.yaml添加依赖:

dependencies:
  dio: ^5.4.0+1

示例1:获取在线用户列表

先完成登录认证,再请求用户列表(以Cookie认证为例):

import 'package:dio/dio.dart';

Future<List<dynamic>> fetchOnlineUsers() async {
  final dio = Dio();
  try {
    // 第一步:登录获取会话Cookie
    await dio.post(
      'http://192.168.1.1/api/login', // 替换成你抓包到的登录接口
      data: {'username': 'admin', 'password': '你的初始密码'}
    );
    // 第二步:请求在线用户列表(dio会自动携带登录后的Cookie)
    final response = await dio.get('http://192.168.1.1/api/online_users'); // 替换成实际接口
    return response.data['user_list'] ?? []; // 替换成响应里的用户列表字段
  } catch (e) {
    print('获取用户失败:$e');
    return [];
  }
}

示例2:修改路由器密码

Future<bool> changeRouterPassword(String oldPwd, String newPwd) async {
  final dio = Dio();
  try {
    // 确保已完成登录(或者在这里重新登录)
    final response = await dio.post(
      'http://192.168.1.1/api/change_pwd', // 替换成抓包到的改密接口
      data: {'old_pwd': oldPwd, 'new_pwd': newPwd}
    );
    return response.data['status'] == 'success'; // 根据响应判断是否成功
  } catch (e) {
    print('修改密码失败:$e');
    return false;
  }
}

3. 用Flutter组件构建设置UI

把接口数据和用户操作结合,构建原生Flutter界面:

import 'package:flutter/material.dart';

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

  @override
  State<RouterSettingsScreen> createState() => _RouterSettingsScreenState();
}

class _RouterSettingsScreenState extends State<RouterSettingsScreen> {
  final _oldPwdCtrl = TextEditingController();
  final _newPwdCtrl = TextEditingController();
  List<dynamic> _onlineUsers = [];

  @override
  void initState() {
    super.initState();
    _loadOnlineUsers();
  }

  void _loadOnlineUsers() async {
    final users = await fetchOnlineUsers();
    setState(() => _onlineUsers = users);
  }

  void _onChangePassword() async {
    final success = await changeRouterPassword(
      _oldPwdCtrl.text,
      _newPwdCtrl.text
    );
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text(success ? '密码修改成功' : '密码修改失败'))
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('路由器设置')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              '在线设备',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
            ),
            const SizedBox(height: 8),
            Expanded(
              child: ListView.builder(
                itemCount: _onlineUsers.length,
                itemBuilder: (ctx, idx) {
                  final user = _onlineUsers[idx];
                  return ListTile(
                    title: Text(user['device_name'] ?? '未知设备'),
                    subtitle: Text('IP: ${user['ip_address'] ?? '未知'}'),
                  );
                },
              ),
            ),
            const SizedBox(height: 20),
            const Text(
              '修改管理员密码',
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
            ),
            TextField(
              controller: _oldPwdCtrl,
              obscureText: true,
              decoration: const InputDecoration(labelText: '原密码'),
            ),
            TextField(
              controller: _newPwdCtrl,
              obscureText: true,
              decoration: const InputDecoration(labelText: '新密码'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _onChangePassword,
              child: const Text('确认修改'),
            ),
          ],
        ),
      ),
    );
  }
}

关键注意事项

  • 路由器兼容性:不同品牌(小米、TP-Link、华硕等)的API完全不同,必须针对你的路由器型号抓包,没有通用代码
  • 局域网限制:手机必须和路由器在同一WiFi下,且路由器的管理端口(默认80)未被禁用
  • 认证机制:部分路由器用Token而非Cookie,抓包时要注意在后续请求的Header里带上Authorization字段
  • 测试优先:先在Postman里验证请求是否有效,再写到Flutter代码中,避免踩坑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:45:11