【Android学习-wifi局域网配网开发】

wifi局域网配网开发


如题,项目软件需要配网(wifi),每次现场安装都需要使用鼠标键盘进行配网的操作。影响安装效率,在参考市面上的大多数类似设备后,决定添加通过wifi热点进行局域网配网的功能。
为实现该功能,需要做一些准备工作

准备工作

  1. 权限

① 配网的功能需要使用到定位和wifi权限。
注意事项:不同的安卓版本需要的权限不同,博主是安卓14的版本,14-17应该差不多,安卓8等较低版本权限可能有所不同,可以问AI;定位权限只开放不启动就行

    <!-- 网络基础权限 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    
    <!-- WiFi扫描权限(Android 10+-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
        android:usesPermissionFlags="neverForLocation" />

②开关wifi需要系统级的权限,要么联系厂家拿系统签名,然后打包。要么找厂家要相关的jar/aar包,通过该包调用相应的api。没有系统权限的app打包了也无法正常使用wifi相关的功能

逻辑

由于大部分代码都是AI(ds,gpt,claude都用了)写的,因此只说明大致流程。下面是大概的功能描述

Android IoT 设备设计的 WiFi 配网库,实现了:

  • 零键鼠配网:通过 AP 热点 + Web 配网页面完成 WiFi 配置,无需键鼠/显示器
  • AP 热点常驻:AP 热点永久开启,方便随时访问配网服务
  • 双模式支持:WiFi 连接成功后自动尝试 AP+STA 双模式
  • Captive Portal:手机连接热点后自动弹窗进入配网页面
  • 状态监控:WiFi 断开自动恢复,AP 热点保持运行

获得权限后先判断设备是否已经连接wifi,是则无需开启热点相关的服务;否则通过开启局域网和热点服务,让用户通过手机等设备连接相应的wifi,然后找到wifi,输入密码。即可完成配网的操作

注意事项:配网的前端服务需要固定好ip和端口号,否则默认是动态的,如果不看日志就不知道ip和端口号是哪个了

优化

当前放置在项目中运行,暂时没有什么问题。实际遇到可以优化的就是关于wifi修改密码的问题,如果用户直接通过键鼠的方式强行修改过系统的wifi密码,并且是错误的,此时项目中的就失效了。系统输入的wifi密码权限如果没有系统签名的话会被拒绝
提示类似下图的信息,导致无法正常修改密码。该问题当前还在联系厂家
在这里插入图片描述

根本原因 :Android 10+ 限制应用只能修改自己创建的WiFi配置。用户在系统设置中输入错误密码后,配置由系统Settings创建,我们的app无权删除、修改或通过 connect() API 连接。

解决方案:使用 su 命令绕过权限限制,先忘记旧网络再连接。

/**
     * 使用 wpa_cli 命令连接WiFi(cmd wifi的后备方案)
     */
    private static boolean connectWithWpaCli(String ssid, String password) {
        try {
            Process process = Runtime.getRuntime().exec("su");
            java.io.DataOutputStream os = new java.io.DataOutputStream(process.getOutputStream());

            // wpa_cli 命令序列
            os.writeBytes("wpa_cli add_network\n");
            // 等待add_network返回ID比较复杂,直接用一个固定的流程
            // 先remove所有匹配SSID的网络,再添加新的
            os.writeBytes("wpa_cli list_networks\n");

            if (password == null || password.isEmpty()) {
                os.writeBytes("wpa_cli set_network 0 ssid '\"" + ssid + "\"'\n");
                os.writeBytes("wpa_cli set_network 0 key_mgmt NONE\n");
            } else {
                os.writeBytes("wpa_cli set_network 0 ssid '\"" + ssid + "\"'\n");
                os.writeBytes("wpa_cli set_network 0 psk '\"" + password + "\"'\n");
            }
            os.writeBytes("wpa_cli enable_network 0\n");
            os.writeBytes("wpa_cli select_network 0\n");
            os.writeBytes("wpa_cli save_config\n");
            os.writeBytes("exit\n");
            os.flush();
            os.close();

            java.io.BufferedReader reader = new java.io.BufferedReader(
                new java.io.InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                Log.i(TAG, "wpa_cli: " + line);
            }

            int result = process.waitFor();
            Log.i(TAG, "wpa_cli 结果: " + result);
            return result == 0;
        } catch (Exception e) {
            Log.e(TAG, "wpa_cli连接失败", e);
            return false;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

淳杰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值