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 系统开发的同行们有所帮助。

相关推荐
mmsx2 小时前
return false 不是拦截:一次按键触发两个动作的事件冒泡陷阱
android·bug
DU_YULIN2 小时前
Camera HAL ThreadManager概述
android·camera hal
淡淡的香烟3 小时前
Android中的MQTT通信原理解析
android·物联网
淡淡的香烟3 小时前
Android Camera开发详解
android·音视频
mmsx4 小时前
基于 Android 的校园信息管理系统源码
android·java·okhttp
YF02115 小时前
如何进入Android工程模式
android
Kevin Coding6 小时前
JsonConvert:适用于 Android、鸿蒙与 Flutter 的 JSON 转 Model 插件
android·flutter·harmonyos
xcLeigh8 小时前
Go入门:基本数据类型全览与选择指南
android·服务器·golang·教程·go热门
alexhilton8 小时前
规范驱动开发:让AI生成符合预期的KMP代码
android·kotlin·android jetpack