杰理 SDK 文档中心
首页
首页
  • 快速开始

    • 环境要求与权限配置
    • 集成SDK依赖
    • 运行示例应用
  • 核心架构与协议

    • RCSP协议与数据通道
    • 蓝牙连接与设备管理
    • TWS双耳功能
    • 基础功能接口与自定义命令
  • 设备功能控制

    • 设备音乐控制与ID3信息
    • 文件浏览与传输
    • FM收音与发射
    • 灯光控制
    • 闹钟与时间管理
    • 查找设备与防丢
    • ANC与噪声处理
    • 按键功能设置
    • 彩屏仓控制
    • AI翻译
  • 音效与音频处理

    • 均衡器音效调节
    • 录音与语音控制
    • Line-in、SPDIF与声卡功能
    • 音频编解码库
  • 扩展功能库

    • OTA固件升级
    • 数据加密与解密
    • 图片与动图格式转换
  • 示例应用 btsmart

    • 应用架构与界面导航
    • 设备功能适配与数据层
    • 设备配置JSON与资源文件
  • 参考与版本

    • 错误码参考
    • 版本历史与更新日志
    • 开发文档中心导航

彩屏仓控制

彩屏仓(Color Screen Charging Case)是杰理(JieLi)TWS 耳机生态中的一种带彩色屏幕的充电仓设备。本文档讲解 Android 端如何通过 ChargingCaseOpImpl 与 RCSP 协议控制彩屏仓的亮度、壁纸、屏保、开机动画、闪光灯、消息推送与天气同步等功能,覆盖从 UI 层(Fragment/ViewModel)到 SDK 操作层、再到 BLE 通道的完整调用链。

Purpose and Scope

本文档覆盖:

  • 彩屏仓功能在 btsmart 应用中的端到端实现:ChargingCaseSettingViewModel、ChargingCaseSettingFragment、ChargingCaseInfoChange 数据模型与 ChargingCaseDemo 示例。
  • SDK 侧 ChargingCaseOpImpl(位于 com.jieli.bluetooth.impl.rcsp.charging_case)的典型用法:获取/设置亮度、闪光灯、壁纸、屏保、开机动画,读取配对设备状态、屏幕信息、SDK 消息,以及资源传输与删除流程。
  • 事件监听机制 OnChargingCaseListener 及其回调语义。

本文档不涉及:ANC 设置、EQ、音量、音乐控制等其它设备功能(各有独立页面);LE Audio、OTA、大文件传输等底层链路也不在本页展开。

Overview

彩屏仓在产品形态上属于"耳机类产品"的配件:耳机本体通过蓝牙与手机连接,充电仓(彩屏仓)则作为 RCSP 协议中的另一个设备端点,可以显示电量、天气、消息通知,并允许用户通过 App 更换壁纸、屏保、开机动画或调节屏幕亮度。README 中将其能力概括为"亮度调节,壁纸更新,屏幕保护程序更新等"(见 README.md)。

从 SDK 版本演进看(见 README.md):

  • V4.1.0:新增 701N 和 707N 彩屏仓 SDK 支持,包括屏幕亮度控制、屏幕保护程序控制、天气同步、消息同步。
  • V4.2.0:修改彩屏仓本地资源(资源管理流程调整)。

关键设计意图:

  1. 单一操作入口:所有彩屏仓操作都收敛到 ChargingCaseOpImpl(单例),由 RCSPController.getRcspOp() 派生,保证指令串行、状态一致。
  2. 缓存优先 + 主动同步:getChargingCaseInfo() 返回的是 SDK 缓存的 ChargingCaseInfo;App 侧通过 syncDeviceState() 在进入设置页时主动拉取全量状态,并用"跳过标志"避免覆盖已缓存资源。
  3. 事件驱动 UI:ViewModel 通过 LiveData 暴露初始化状态、彩屏仓信息变化、功能操作结果、资源删除结果,Fragment 观察这些数据流刷新界面,回调一律回到主线程语义(postValue)。

Architecture

flowchart TD
    subgraph sg_UI["UI 层 (btsmart)"]
        Fragment["ChargingCaseSettingFragment"]
        VM["ChargingCaseSettingViewModel (BtBasicVM)"]
        InfoChange["ChargingCaseInfoChange"]
        LiveData["MutableLiveData (initMLD / chargingCaseInfoMLD / functionResultMLD ...)"]
    end

    subgraph sg_SDK["SDK 层 (com.jieli.bluetooth)"]
        RCSP["RCSPController"]
        OpImpl["ChargingCaseOpImpl (单例)"]
        Listener["OnChargingCaseListener"]
        Info["ChargingCaseInfo (缓存)"]
    end

    subgraph sg_DEVICE["设备端"]
        BLE["BLE 通道 / RCSP 协议"]
        Case["彩屏仓 (701N / 707N)"]
    end

    Fragment -->|"观察"| LiveData
    Fragment -->|"用户操作"| VM
    VM -->|"instance() 派生"| OpImpl
    VM -->|"syncDeviceState / setBrightness..."| OpImpl
    OpImpl -->|"getRcspOp()"| RCSP
    OpImpl -->|"addOnChargingCaseListener"| Listener
    OpImpl -->|"读写"| Info
    Listener -->|"onChargingCaseInfoChange / onInit / onChargingCaseEvent"| VM
    VM -->|"postValue"| LiveData
    RCSP -->|"指令收发"| BLE
    BLE -->|"RCSP 帧"| Case

各组件职责:

  • ChargingCaseSettingFragment:彩屏仓设置界面,负责展示亮度、壁纸、屏保、开机动画列表与操作入口。
  • ChargingCaseSettingViewModel:业务逻辑层,封装 ChargingCaseOpImpl,把 SDK 回调转成 LiveData 流,并负责"进入页面时同步设备状态"。
  • ChargingCaseOpImpl:SDK 提供的彩屏仓功能实现类,通过 ChargingCaseOpImpl.instance(rcspOp) 获取单例(见 ChargingCaseDemo.java)。
  • OnChargingCaseListener:彩屏仓事件监听器,初始化、信息变化、功能事件三类回调。
  • ChargingCaseInfo:SDK 缓存的彩屏仓状态对象,按 @ChargingCaseInfo.Function 区分亮度、闪光灯、屏保、壁纸、开机动画等字段。
  • ChargingCaseInfoChange:App 层包装对象,把"哪个功能变了 + 最新信息"打包发给 UI(见 ChargingCaseInfoChange.java)。

核心实现剖析

1. ViewModel 的初始化与依赖装配

ChargingCaseSettingViewModel 继承自 BtBasicVM(应用层基础 ViewModel,持有 RCSPController 与设备状态),构造时完成两件关键事情:

  1. 通过 ChargingCaseOpImpl.instance(mRCSPController.getRcspOp()) 获取彩屏仓操作单例 —— 传入的 getRcspOp() 是 RCSP 基础操作接口,ChargingCaseOpImpl 在其之上封装彩屏仓专用指令;
  2. 立即注册 OnChargingCaseListener 监听器,保证进入页面即开始接收设备端上报。
public ChargingCaseSettingViewModel() {
    super();
    mChargingCaseOp = ChargingCaseOpImpl.instance(mRCSPController.getRcspOp());
    mChargingCaseOp.addOnChargingCaseListener(mChargingCaseListener);
}

Source: ChargingCaseSettingViewModel.java

设计意图:ChargingCaseOpImpl 是单例,与 RCSPController 的生命周期绑定,任何页面/ViewModel 复用同一个操作实例,避免多实例各自维护状态导致缓存不一致。

2. 缓存读取与兜底创建

getChargingCaseInfo() 优先返回 SDK 缓存;若缓存为空(例如首次进入页面、设备尚未同步过状态),则基于当前连接设备的 EDR 地址构造一个空壳 ChargingCaseInfo 占位,避免上层空指针:

@NonNull
public ChargingCaseInfo getChargingCaseInfo() {
    ChargingCaseInfo info = mChargingCaseOp.getChargingCaseInfo(getConnectedDevice());
    if (null == info) {
        final DeviceInfo deviceInfo = getDeviceInfo();
        info = new ChargingCaseInfo(deviceInfo == null ? "" : deviceInfo.getEdrAddr());
    }
    return info;
}

Source: ChargingCaseSettingViewModel.java

3. 设备状态同步(syncDeviceState)

进入设置页时,页面调用 syncDeviceState() 主动拉取设备全量状态。该方法有一个重要细节:跳过标志(skip flags)。ChargingCaseInfo 缓存中如果已经存在当前屏保、当前开机动画、当前壁纸,则同步时跳过这些字段的覆盖式拉取。原因在于资源类字段(壁纸/屏保/开机动画)以"资源列表 + 当前选中项"形式维护,如果本地缓存已有有效值,全量重拉反而可能覆盖用户尚未提交的本地选择:

public void syncDeviceState() {
    if (syncStateWrapper.isSyncing()) return;
    final ChargingCaseInfo info = getChargingCaseInfo();
    syncStateWrapper.reset();
    syncStateWrapper.setSyncing(true)
            .setSkipCurrentScreenSaver(null != info.getCurrentScreenSaver())
            .setSkipCurrentBootAnim(null != info.getCurrentBootAnim())
            .setSkipWallpaper(null != info.getCurrentWallpaper());
    tryToSyncDeviceState(getConnectedDevice());
}

Source: ChargingCaseSettingViewModel.java

SyncStateWrapper 用于防重入:isSyncing() 为真时直接返回,避免用户在慢速 BLE 链路上连续触发同步造成指令风暴。

4. 功能操作模板:以亮度为例

所有功能操作遵循同一模板:调用 ChargingCaseOpImpl 的异步方法,传入设备与 OnRcspActionCallback<T> 回调;回调结果统一封装成 OpResult<Integer>(携带 ChargingCaseInfo.FUNC_* 功能码标识 + 子错误码 + 错误描述)通过 functionResultMLD 投递给 UI:

public void getBrightness() {
    mChargingCaseOp.getBrightness(getConnectedDevice(), new OnRcspActionCallback<Integer>() {
        @Override
        public void onSuccess(BluetoothDevice device, Integer message) {
            JL_Log.d(tag, "getBrightness", "onSuccess ---> " + message);
            functionResultMLD.postValue(new OpResult<Integer>()
                    .setData(ChargingCaseInfo.FUNC_BRIGHTNESS)
                    .setCode(0));
        }

        @Override
        public void onError(BluetoothDevice device, BaseError error) {
            functionResultMLD.postValue(new OpResult<Integer>()
                    .setData(ChargingCaseInfo.FUNC_BRIGHTNESS)
                    .setCode(error.getSubCode())
                    .setMessage(error.getMessage()));
        }
    });
}

Source: ChargingCaseSettingViewModel.java

设计意图:把 SDK 的 BluetoothDevice + 泛型回调转成 App 层统一的 LiveData<OpResult<Integer>>,Fragment 只需观察 functionResultMLD 并按功能码分发 UI 提示,业务与视图解耦。

5. 事件监听链路

OnChargingCaseListener 是设备→App 的主动上报通道,有三类回调:

回调语义
onInit(device, state)初始化结果,0 表示成功,其它数值为错误码
onChargingCaseInfoChange(device, func, info)某个功能(亮度/闪光灯/屏保/开机动画/壁纸等)发生变化,携带最新 ChargingCaseInfo
onChargingCaseEvent(device, function)通用功能事件,SDK 说明其同样会经由 onChargingCaseInfoChange 回调,可不重复处理
final OnChargingCaseListener listener = new OnChargingCaseListener() {
    @Override
    public void onInit(BluetoothDevice device, int state) {
        //0 --- 成功,其他数值为错误码
    }

    @Override
    public void onChargingCaseInfoChange(BluetoothDevice device, @ChargingCaseInfo.Function int func, ChargingCaseInfo info) {
        switch (func) {
            case ChargingCaseInfo.FUNC_BRIGHTNESS: info.getBrightness(); break;
            case ChargingCaseInfo.FUNC_FLASHLIGHT: info.isFlashlightOn(); break;
            case ChargingCaseInfo.FUNC_SCREEN_SAVERS: info.getScreenSavers(); break;
            case ChargingCaseInfo.FUNC_CURRENT_SCREEN_SAVER: info.getCurrentScreenSaver(); break;
            case ChargingCaseInfo.FUNC_CURRENT_BOOT_ANIM: info.getCurrentBootAnim(); break;
            case ChargingCaseInfo.FUNC_WALLPAPERS: info.getWallpapers(); break;
            case ChargingCaseInfo.FUNC_CURRENT_WALLPAPER: info.getCurrentWallpaper(); break;
        }
    }

    @Override
    public void onChargingCaseEvent(BluetoothDevice device, SettingFunction function) {
        // 可选处理
    }
};
chargingCaseOp.addOnChargingCaseListener(listener);
// 不再监听时释放:chargingCaseOp.removeListener(listener);

Source: ChargingCaseDemo.java

设计意图:把"功能码 + 全量信息"一起回调,是为了让上层按需增量更新;@ChargingCaseInfo.Function 注解约束功能码取值,编译期即可发现错误。

Core Flow

进入设置页 → 同步 → 操作 → 上报 完整时序

sequenceDiagram
    participant F as ChargingCaseSettingFragment
    participant VM as ChargingCaseSettingViewModel
    participant OP as ChargingCaseOpImpl (SDK)
    participant RC as RCSPController / BLE
    participant D as 彩屏仓设备

    F->>VM: 创建 / onViewCreated
    VM->>OP: instance(rcspOp) + addOnChargingCaseListener
    OP-->>VM: onInit(device, state=0)
    VM-->>F: initMLD.postValue(true)
    F->>VM: syncDeviceState()
    VM->>VM: 检查 SyncStateWrapper 防重入 + 设置 skip 标志
    VM->>OP: 拉取亮度/壁纸/屏保/开机动画状态
    OP->>RC: 组 RCSP 指令帧
    RC->>D: BLE 下发
    D-->>RC: 应答帧
    RC-->>OP: 解析并更新 ChargingCaseInfo 缓存
    OP-->>VM: onChargingCaseInfoChange(func, info)
    VM-->>F: chargingCaseInfoMLD.postValue(ChargingCaseInfoChange)
    F->>VM: 用户操作(如 setBrightness(60))
    VM->>OP: setBrightness(device, 60, callback)
    OP->>RC: 指令帧
    RC->>D: BLE 下发
    D-->>RC: 应答
    RC-->>OP: onSuccess / onError
    OP-->>VM: onChargingCaseInfoChange(FUNC_BRIGHTNESS, info)
    VM-->>F: functionResultMLD.postValue(OpResult)

资源类操作流程(壁纸 / 屏保 / 开机动画)

资源类功能(壁纸、屏保、开机动画)与数值类功能(亮度、闪光灯)不同:它们需要先把本地图片/动画资源推送到设备存储,再设置"当前项"。ViewModel 中引用了 ResourceFile、ConfigureKit、FileUtil、FileStruct、RegFile、SDCardBean、DeleteCallback 等类型,表明其流程为:

  1. 浏览/选择本地资源文件(ResourceFile);
  2. 通过文件浏览/传输通道(RegFile、SDCardBean)把资源推送到设备存储;
  3. 调用设置"当前壁纸/屏保/开机动画"指令,使设备生效;
  4. 删除不再使用的资源,通过 deleteResourceMLD(StateResult<Boolean>)反馈结果。

(本页聚焦彩屏仓控制语义;资源传输底层的文件浏览与大文件传输细节见对应目录页。)

Usage Examples

示例一:获取与设置屏幕亮度

亮度取值范围 0–100%。获取操作返回 Integer,设置操作返回 Boolean:

@Test
public void getBrightness() {
    //Step1. 创建彩屏充电仓实现类
    ChargingCaseOpImpl chargingCaseOp = ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp());
    //Step2. 调用获取屏幕亮度的接口
    chargingCaseOp.getBrightness(RCSPController.getInstance().getUsingDevice(), new OnRcspActionCallback<Integer>() {
        @Override
        public void onSuccess(BluetoothDevice device, Integer message) {
            //message -- 亮度, 范围:0 - 100%
        }
        @Override
        public void onError(BluetoothDevice device, BaseError error) {
            //回调操作失败 和 错误信息
        }
    });
}

@Test
public void setBrightness() {
    ChargingCaseOpImpl chargingCaseOp = ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp());
    //brightness -- 亮度, 范围:0 - 100%
    int brightness = 60;
    chargingCaseOp.setBrightness(RCSPController.getInstance().getUsingDevice(), brightness,
            new OnRcspActionCallback<Boolean>() {
                @Override
                public void onSuccess(BluetoothDevice device, Boolean message) { }
                @Override
                public void onError(BluetoothDevice device, BaseError error) { }
            });
}

Source: ChargingCaseDemo.java

示例二:闪光灯开关

@Test
public void setFlashlightState() {
    ChargingCaseOpImpl chargingCaseOp = ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp());
    //isOn -- 开关
    boolean isOn = true;
    chargingCaseOp.setFlashlightState(RCSPController.getInstance().getUsingDevice(), isOn,
            new OnRcspActionCallback<Boolean>() {
                @Override
                public void onSuccess(BluetoothDevice device, Boolean message) { }
                @Override
                public void onError(BluetoothDevice device, BaseError error) { }
            });
}

Source: ChargingCaseDemo.java

示例三:读取配对设备状态与屏幕信息

@Test
public void getBoundDeviceState() {
    ChargingCaseOpImpl chargingCaseOp = ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp());
    //获取配对设备信息的接口
    chargingCaseOp.getBoundDeviceState(RCSPController.getInstance().getUsingDevice(),
            new OnRcspActionCallback<BoundDeviceState>() {
                @Override
                public void onSuccess(BluetoothDevice device, BoundDeviceState message) {
                    //message -- 配对设备的信息
                }
                @Override
                public void onError(BluetoothDevice device, BaseError error) { }
            });
}

@Test
public void readScreenInfo() {
    ChargingCaseOpImpl chargingCaseOp = ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp());
    //获取设备屏幕信息的接口(分辨率/形状等)
    chargingCaseOp.readScreenInfo(RCSPController.getInstance().getUsingDevice(),
            new OnRcspActionCallback<ScreenInfo>() {
                @Override
                public void onSuccess(BluetoothDevice device, ScreenInfo message) { }
                @Override
                public void onError(BluetoothDevice device, BaseError error) { }
            });
}

Source: ChargingCaseDemo.java

示例四:读取 SDK 消息(消息同步前置)

public void readSDKMessage() {
    ChargingCaseOpImpl chargingCaseOp = ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp());
    //读取 SDK 信息(如消息推送配置)
    chargingCaseOp.readSDKMessage(RCSPController.getInstance().getUsingDevice(),
            new OnRcspActionCallback<SDKMessage>() {
                @Override
                public void onSuccess(BluetoothDevice device, SDKMessage message) { }
                @Override
                public void onError(BluetoothDevice device, BaseError error) {
                    //error.getSubCode() --- 错误码
                    //error.getMessage() --- 错误描述
                }
            });
}

Source: ChargingCaseDemo.java

数据模型

ChargingCaseInfoChange(App 层包装)

classDiagram
    class ChargingCaseInfoChange {
        -func int "ChargingCaseInfo.Function"
        -chargingCaseInfo ChargingCaseInfo
        +getFunc() int
        +getChargingCaseInfo() ChargingCaseInfo
        +toString() String
    }
    class ChargingCaseInfo {
        <<SDK 缓存对象>>
        +FUNC_BRIGHTNESS int
        +FUNC_FLASHLIGHT int
        +FUNC_SCREEN_SAVERS int
        +FUNC_CURRENT_SCREEN_SAVER int
        +FUNC_CURRENT_BOOT_ANIM int
        +FUNC_WALLPAPERS int
        +FUNC_CURRENT_WALLPAPER int
        +getBrightness() int
        +isFlashlightOn() boolean
        +getScreenSavers() List
        +getCurrentScreenSaver() ResourceInfo
        +getCurrentBootAnim() ResourceInfo
        +getWallpapers() List
        +getCurrentWallpaper() ResourceInfo
        +printFunction(int) String
    }
    ChargingCaseInfoChange --> ChargingCaseInfo : "包装"

ChargingCaseInfoChange 的 toString() 借助 ChargingCaseInfo.printFunction(func) 输出可读的功能名,便于日志排查(见 ChargingCaseInfoChange.java)。

功能码速查(@ChargingCaseInfo.Function)

功能码常量含义对应读取方法
FUNC_BRIGHTNESS屏幕亮度(0–100%)getBrightness()
FUNC_FLASHLIGHT闪光灯开关isFlashlightOn()
FUNC_SCREEN_SAVERS屏保资源列表getScreenSavers()
FUNC_CURRENT_SCREEN_SAVER当前屏保getCurrentScreenSaver()
FUNC_CURRENT_BOOT_ANIM当前开机动画getCurrentBootAnim()
FUNC_WALLPAPERS壁纸资源列表getWallpapers()
FUNC_CURRENT_WALLPAPER当前壁纸getCurrentWallpaper()

Configuration Options

彩屏仓控制模块本身没有独立的配置文件;其行为受 SDK 全局配置影响:

配置项类型默认值说明
芯片平台支持固件能力701N / 707N彩屏仓 SDK 功能(亮度/屏保/天气/消息)在 V4.1.0 起支持
ChargingCaseInfo 缓存内存缓存随连接设备由 ChargingCaseOpImpl 维护,getChargingCaseInfo() 读取
同步跳过标志布尔按缓存决定syncDeviceState() 时是否跳过当前屏保/开机动画/壁纸拉取
同步防重入锁布尔falseSyncStateWrapper.isSyncing() 防止并发同步

API Reference

以下方法均来自 SDK 的 ChargingCaseOpImpl(通过 ChargingCaseOpImpl.instance(RCSPController.getInstance().getRcspOp()) 获取),回调统一使用 OnRcspActionCallback<T>。

getChargingCaseInfo(BluetoothDevice device): ChargingCaseInfo

返回指定设备的彩屏仓缓存信息。非异步,直接读取内存缓存;缓存不存在时返回 null(App 层需自行兜底,如 ViewModel 中的空壳创建逻辑)。

addOnChargingCaseListener(OnChargingCaseListener listener): void

注册彩屏仓事件监听。回调包括:

  • onInit(BluetoothDevice device, int state) — state 为 0 表示初始化成功,其它为错误码。
  • onChargingCaseInfoChange(BluetoothDevice device, @ChargingCaseInfo.Function int func, ChargingCaseInfo info) — 功能变化通知。
  • onChargingCaseEvent(BluetoothDevice device, SettingFunction function) — 通用功能事件(可选处理)。

对应注销方法:removeListener(OnChargingCaseListener listener),页面销毁时必须调用以防泄漏。

数值类操作

方法签名回调类型说明
getBrightness(device, OnRcspActionCallback<Integer>)Integer获取屏幕亮度,范围 0–100%
setBrightness(device, int brightness, OnRcspActionCallback<Boolean>)Boolean设置屏幕亮度,范围 0–100%
getFlashlightState(device, OnRcspActionCallback<Boolean>)Boolean获取闪光灯开关状态
setFlashlightState(device, boolean isOn, OnRcspActionCallback<Boolean>)Boolean设置闪光灯开关

信息读取类操作

方法签名回调类型说明
getBoundDeviceState(device, OnRcspActionCallback<BoundDeviceState>)BoundDeviceState读取与彩屏仓配对的设备信息
readScreenInfo(device, OnRcspActionCallback<ScreenInfo>)ScreenInfo读取设备屏幕信息(分辨率、形状等)
readSDKMessage(device, OnRcspActionCallback<SDKMessage>)SDKMessage读取 SDK 消息/推送配置

回调契约(OnRcspActionCallback<T>)

  • onSuccess(BluetoothDevice device, T message) — 操作成功,message 为结果数据。
  • onError(BluetoothDevice device, BaseError error) — 操作失败;error.getSubCode() 为子错误码,error.getMessage() 为可读描述。

失败模式、边界情况与并发

设备未连接 / 缓存为空

  • getChargingCaseInfo() 返回 null 时,ViewModel 用 DeviceInfo.getEdrAddr() 构造空 ChargingCaseInfo,保证 UI 层拿到非空对象;但字段值均为默认值,界面应显示加载中/占位,直到 onInit 成功。
  • 所有异步指令在设备断开时会在 onError 中返回连接类错误码,UI 通过 OpResult.code != 0 统一提示。

慢速链路与指令风暴

  • BLE 链路带宽低、往返时延长。syncDeviceState() 通过 SyncStateWrapper.isSyncing() 防重入:同步未完成前再次调用直接丢弃,避免多帧指令在链路上堆积。
  • 资源推送(壁纸/屏保/开机动画)体积较大,底层依赖文件传输通道,App 层用 deleteResourceMLD / functionResultMLD 分别反馈传输与设置结果,避免 UI 误判。

资源状态覆盖风险

  • 若本地缓存已有"当前屏保/开机动画/壁纸",全量同步可能覆盖用户尚未提交的选择,因此 syncDeviceState() 显式设置 skip 标志跳过这些字段。开发者在扩展同步逻辑时必须保留该语义,否则会出现"界面刚改完又被设备旧值刷回"的竞态。

监听器泄漏

  • addOnChargingCaseListener 注册的监听器必须配对调用 removeListener;ChargingCaseOpImpl 为进程级单例,若 Fragment/ViewModel 不注销,会造成跨页面回调与内存泄漏。Demo 中以注释形式强调(见 ChargingCaseDemo.java)。

性能与运维

  • 缓存优先:所有读取走 ChargingCaseInfo 内存缓存,避免高频 UI 刷新触发 BLE 指令;只有进入页面/显式刷新时才 syncDeviceState()。
  • 单例复用:ChargingCaseOpImpl 全局唯一,指令发送由其内部串行化,减少重入与乱序。
  • 日志:ViewModel 使用 JL_Log.d(tag, ...) 记录关键回调(如 getBrightness onSuccess ---> 60),排查问题时可先检索 tag 对应日志。
  • 版本注意:V4.2.0 修改了彩屏仓本地资源处理,升级 SDK 后需回归验证资源推送/删除流程(见 README.md)。

扩展点

  1. 新增彩屏仓功能:在 ChargingCaseInfo 中扩展 @ChargingCaseInfo.Function 常量与字段,ChargingCaseOpImpl 增加对应读写方法;OnChargingCaseListener.onChargingCaseInfoChange 的 switch 分支随之扩展。
  2. 自定义资源推送:壁纸/屏保/开机动画的资源准备(如 ResourceFile 选择、ConfigureKit 配置)可替换为应用自己的素材来源,只要最终通过 SDK 的资源设置指令生效即可。
  3. 多设备支持:所有 API 均以 BluetoothDevice 为第一参数,天然支持连接设备切换;切换后缓存按设备地址(EdrAddr)区分。

Related Links

  • ChargingCaseSettingViewModel.java(核心逻辑)
  • ChargingCaseSettingFragment.java(设置界面)
  • ChargingCaseInfoChange.java(信息变化包装对象)
  • ChargingCaseDemo.java(官方示例代码)
  • README.md(功能清单与版本记录)
  • 相关目录页:ANC 设置(噪声处理模式)、AI 翻译、音乐控制、文件浏览/资源传输。
Prev
按键功能设置
Next
AI翻译