RK3568 Android 13 SDK 开机自动开启共享热点实践

目录

前言

一、基本介绍

[1.1 需求场景](#1.1 需求场景)

[1.2 技术选型分析](#1.2 技术选型分析)

[1.3 涉及的关键类](#1.3 涉及的关键类)

二、具体实施

[2.1 源码定位](#2.1 源码定位)

[2.2 实现思路](#2.2 实现思路)

[2.3 代码实现](#2.3 代码实现)

[2.4 关键技术要点](#2.4 关键技术要点)

总结


前言

在嵌入式 Android 设备开发中,经常遇到这样的场景:设备作为无线接入点(AP)使用,需要开机后自动开启共享热点,以便其他设备能够快速连接并进行通信。例如智能家居网关、工业数据采集器、车载娱乐系统等,都需要设备在开机后立即可被发现和连接。

本文将基于 RK3568 平台的 Android 13 SDK,详细介绍如何通过修改 Framework 层代码,实现开机检测 WiFi 状态,在 WiFi 未开启时自动开启共享热点,并设置指定的热点名称和密码。


一、基本介绍

1.1 需求场景

有一台基于 RK3568 的 Android 设备,需要满足以下需求:

  • 开机自启动:设备启动完成后自动执行检测逻辑

  • 状态检测:检测 WiFi 开关是否已经打开

  • 智能决策:如果 WiFi 未打开,则自动开启共享热点

  • 固定配置:热点名称为 BoxControl,密码为 13572468

1.2 技术选型分析

在 Android 系统中,实现开机自动执行任务有几种常见方式:

方案 实现方式 优点 缺点
Shell 脚本 通过 init.rc 执行脚本 快速实现,无需编译系统 权限受限,配置热点困难
系统 App 开发 APK 监听开机广播 灵活可迭代 需要系统签名,启动时序晚
Framework 修改 修改 WifiServiceImpl 最稳定可靠,深度集成 需要编译整个系统

考虑到热点配置需要在系统服务层面完成,且需要稳定的启动时序,修改 Framework 层代码是最佳选择。

1.3 涉及的关键类

  • WifiServiceImpl:WiFi 核心服务类,管理所有 WiFi 相关操作

  • SoftApConfiguration:热点配置类,包含 SSID、密码、安全类型等

  • WifiApConfigStore:热点配置存储类,负责配置的持久化

  • ActiveModeWarden:模式管理器,负责 WiFi 和热点的模式切换

二、具体实施

2.1 源码定位

RK3568 Android 13 SDK 中,WiFi 服务源码位于:

bash 复制代码
packages/modules/Wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

2.2 实现思路

整个实现分为三个关键步骤:

  1. 在服务启动入口添加调用 :在 checkAndStartWifi() 方法中插入自定义逻辑

  2. 实现核心检测方法:检查 WiFi 状态,构建并保存热点配置

  3. 启动热点:调用系统 API 开启共享热点

2.3 代码实现

第一步:在 checkAndStartWifi() 中添加调用

java 复制代码
public void checkAndStartWifi() {
    mWifiThreadRunner.post(() -> {
        // ... 原有初始化代码 ...
        
        mActiveModeWarden.start();
        registerForCarrierConfigChange();
        mWifiInjector.getAdaptiveConnectivityEnabledSettingObserver().initialize();
        
        // 开机自动启动热点
        checkAndStartHotspotIfWifiOff();
        
        mIsWifiServiceStarted = true;
    });
}

第二步:实现核心检测方法

java 复制代码
/**
 * 检查WiFi状态,如果WiFi未开启则自动启动热点
 */
private void checkAndStartHotspotIfWifiOff() {
    final String HOTSPOT_SSID = "BoxControl";
    final String HOTSPOT_PASSWORD = "13572468";
    
    // 延迟5秒执行,等待系统服务完全初始化
    mWifiThreadRunner.postDelayed(() -> {
        try {
            // 1. 检查WiFi是否开启
            int wifiState = mActiveModeWarden.getWifiState();
            boolean isWifiEnabled = (wifiState == WIFI_STATE_ENABLED);
            
            if (!isWifiEnabled) {
                // 2. 检查热点是否已开启
                int apState = mTetheredSoftApTracker.getState();
                if (apState == WIFI_AP_STATE_ENABLED) {
                    Log.w(TAG, "Hotspot already enabled, skip auto-start");
                    return;
                }
                
                // 3. 检查用户限制
                if (mWifiTetheringDisallowed) {
                    Log.w(TAG, "Tethering is disallowed by user restriction");
                    return;
                }
                
                // 4. 构建热点配置
                SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
                        .setSsid(HOTSPOT_SSID)
                        .setPassphrase(HOTSPOT_PASSWORD, 
                                SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
                        .build();
                
                // 5. 保存配置
                mWifiApConfigStore.setApConfiguration(softApConfig);
                Log.i(TAG, "Hotspot configuration saved: SSID=" + HOTSPOT_SSID);
                
                // 6. 启动热点
                boolean started = startTetheredHotspot(null, "android");
                if (!started) {
                    // 备选方案:直接调用内部方法
                    WorkSource requestorWs = new WorkSource(Process.SYSTEM_UID, "android");
                    SoftApCapability capability = mTetheredSoftApTracker.getSoftApCapability();
                    SoftApModeConfiguration apConfig = new SoftApModeConfiguration(
                            WifiManager.IFACE_IP_MODE_TETHERED, 
                            softApConfig,
                            capability);
                    startSoftApInternal(apConfig, requestorWs);
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Error in auto-start hotspot", e);
        }
    }, 5000);
}

2.4 关键技术要点

关于延迟执行

使用 postDelayed(5000) 延迟 5 秒执行,原因如下:

  • WiFi 服务在 checkAndStartWifi() 中初始化,但底层驱动和 HAL 层需要时间准备

  • 热点启动依赖 WifiApConfigStore 等组件就绪

  • 适当延迟可避免时序竞争导致的启动失败

关于配置保存

先调用 mWifiApConfigStore.setApConfiguration(softApConfig) 保存配置,再启动热点。这是因为 startTetheredHotspot(null, "android") 会从 WifiApConfigStore 读取配置,如果不先保存,可能使用旧配置。

关于双方案保障

代码中实现了主备两套启动方案:

  • 主方案 :startTetheredHotspot(null, "android") - 标准 API

  • 备选方案 :startSoftApInternal() - 内部方法,绕过部分权限检查


总结

本文介绍了在 RK3568 Android 13 SDK 中,通过修改 WifiServiceImpl.java 实现开机自动开启共享热点的方法。希望本文对从事 Android 系统开发的同行们有所帮助。

相关推荐
素师良码18 小时前
第5篇:显示驱动必备调试工具浅析
android
维克兜率天19 小时前
【维克】配对交易的季节性:哪些品种适合长拿?
android·开发语言·笔记·python·算法·kotlin·量化
墨天梦19 小时前
B06_XML控件布局与ViewBinding
android·kotlin
晚风叙码20 小时前
MySQL 表的操作:从建表到删表,一篇讲清楚
android·mysql·oracle
事圆则缓21 小时前
Android 性能优化常见工具与使用场景:从症状到证据的排查指南
android·性能优化
avi911121 小时前
Unity 非后台,非自动构建,但统计报表 BuildReport ,构建自动化系统C#
android·webserver·ios打包·admin·c#后台·unity打包系统·unity自动构建
新鲜势力呀21 小时前
PHP 定时任务系统实战:从 Cron 混乱执行到任务调度中心 + Redis队列 + 失败重试
android·java·redis
YF02111 天前
Android 16系统 如何修改 eth0 IP ?
android
其实防守也摸鱼1 天前
渗透测试学习计划(全栈综合 · 零基础进阶)
android·数据库·学习·安全·oracle·自动化·学习方法
释厄6231 天前
BSD 简单真理循环论——简单真理 × 复杂循环=大一统
android·开发语言·kotlin