OpenHarmony 分布式设备管理基本用法
·
OpenHarmony 分布式设备管理基本用法
本文介绍 OpenHarmony 分布式组网的核心入口 DeviceManager 的基本用法,覆盖组件架构、核心 API、代码实战与常见问题,帮助开发者快速实现设备发现、PIN 码认证与跨设备交互。
flowchart LR
A[创建DeviceManager实例] --> B[注册设备状态监听]
B --> C[获取可信设备列表]
C --> D[扫描发现周边设备]
D --> E[PIN码配对认证]
E --> F[设备加入可信列表]
F --> G[跨设备拉起Ability]
G --> H[分布式数据交互]
一、核心概述
1.1 能力定位
OpenHarmony 所有分布式能力(分布式相机、分布式屏幕、分布式数据管理、跨设备拉起应用等)的前置基础是设备配对与鉴权组网,所有跨设备交互必须建立在可信设备组网的基础上。
1.2 核心组件:DeviceManager(设备管理模块)
DeviceManager 是鸿蒙分布式组网的核心入口,具备无账号依赖的设备组网能力,是开发者实现设备发现、设备监听、设备认证、跨设备交互的核心工具。
| 核心能力 | 说明 |
|---|---|
| 设备上下线监听 | on('deviceStateChange') 实时感知设备状态 |
| 周边设备发现 | 扫描同一网络下的可信/不可信设备 |
| 设备 PIN 码鉴权 | 系统原生配对认证,无需自研页面 |
| 可信设备管理 | 认证通过设备持久化保存,直接获取列表 |
1.3 完整核心工作流程
创建DeviceManager实例
└─ 注册设备状态监听
└─ 获取本地可信设备列表
└─ 扫描发现周边设备
└─ PIN码配对认证
└─ 设备加入可信列表
└─ 跨设备拉起Ability / 分布式交互
二、DeviceManager 组件架构
2.1 源码核心路径
foundation/distributedhardware/devicemanager
2.2 核心目录及功能说明
foundation/distributedhardware/devicemanager
├─ common/ ← 公共头文件、通用工具类
├─ display/ ← PIN码显示HAP页面JS代码
├─ interfaces/
│ ├─ inner_kits/ ← 系统内部接口(Native、IPC、消息通知)
│ └─ kits/ ← 对外暴露的JS API(核心接口层)
└─ services/
├─ devicemanagerservice/ ← 设备管理核心服务
├─ ability/ ← PIN码显示FA拉起与生命周期管理
├─ auth/ ← 设备配对认证交互逻辑
├─ ipc/ ← 跨进程通信
├─ message/ ← 设备交互消息解析封装
├─ requestauth/ ← 设备认证请求核心逻辑
├─ softbus/ ← 对接分布式软总线
└─ timer/ ← 扫描超时、心跳、认证超时定时器
三、核心 API 速查手册(API 9)
3.1 实例管理接口
| API 方法 | 功能说明 |
|---|---|
| createDeviceManager(bundleName, callback) | 异步创建设备管理实例,所有分布式操作的前置入口 |
| release() | 释放 DeviceManager 实例,销毁监听与任务 |
3.2 设备状态与监听接口
| API 方法 | 功能说明 |
|---|---|
| getTrustedDeviceListSync() | 同步获取当前系统中所有已配对的可信设备列表 |
| on('deviceStateChange', cb) | 监听设备上线、下线状态变更事件 |
| on('serviceDie', cb) | 监听设备管理服务异常退出、崩溃回调,用于异常兜底 |
3.3 设备发现与认证接口
| API 方法 | 功能说明 |
|---|---|
| startDeviceDiscovery(info) | 开启周边设备扫描,需传入唯一 subscribeId |
| stopDeviceDiscovery(subscribeId) | 停止设备扫描,必须与开启接口成对调用 |
| authenticateDevice(device, param, cb) | 发起设备 PIN 码认证,配对陌生设备 |
| on('deviceFound', cb) | 扫描到周边设备的结果回调 |
| on('discoverFail', cb) | 设备扫描失败、超时、权限不足的失败回调 |
重要注意事项:startDeviceDiscovery 与 stopDeviceDiscovery 必须成对使用,且全程共用同一个 subscribeId,否则会出现扫描残留、无法停止等问题。
四、核心代码实战(Stage 模型 + API 9)
4.1 初始化 DeviceManager 实例
在页面 aboutToAppear 生命周期中初始化,全局仅需创建一次:
async createDeviceManager() {
// 获取当前应用包名
let bundleName = await globalThis.context.abilityInfo.bundleName;
// 创建设备管理实例
deviceManager.createDeviceManager(bundleName, (err, dm) => {
if (!dm) return;
this.deviceManager_ = dm;
// 监听设备上下线状态变化
dm.on("deviceStateChange", data => {
let device = data.device;
this.trustedDeviceList = [{ ...device }];
this.deviceFoundList = [];
});
// 监听服务异常退出
dm.on("serviceDie", () => {
console.log("设备管理服务异常退出");
});
// 初始化获取本地可信设备列表
let array = dm.getTrustedDeviceListSync();
if (array?.length) {
this.trustedDeviceList = [...array];
}
});
}
4.2 周边设备扫描(开启/停止)
前置条件:设备连接同一 WiFi 网络。
// 开启设备发现
startDeviceDiscovery() {
// 监听发现设备回调
this.deviceManager_.on('deviceFound', (data) => {
console.log("发现设备: ", data.device);
});
// 监听扫描失败回调
this.deviceManager_.on('discoverFail', (data) => {
console.log("设备发现失败: ", data);
});
// 生成唯一订阅ID
this.subscribeId = Math.floor(Math.random() * 10000 + 1000);
// 扫描参数配置
var info = {
"subscribeId": this.subscribeId,
"mode": 0xAA,
"medium": 0,
"freq": 2,
"isSameAccount": false,
"isWakeRemote": true,
"capability": 0
};
// 启动扫描
this.deviceManager_.startDeviceDiscovery(info);
}
// 停止设备发现
stopDeviceDiscovery() {
// 传入对应订阅ID停止扫描
this.deviceManager_.stopDeviceDiscovery(this.subscribeId);
}
4.3 PIN 码设备认证
系统自动弹出 PIN 码弹窗,远端设备展示 6 位 PIN 码,本地设备输入验证,认证通过后设备加入可信列表:
authenticateDevice(device, authParam) {
this.deviceManager_.authenticateDevice(device, authParam, (error, data) => {
if (!error) {
console.log("设备认证成功");
} else {
console.log("设备认证失败: ", error);
}
});
}
4.4 权限配置与动态申请
分布式交互必备权限:ohos.permission.DISTRIBUTED_DATASYNC
1. 模块声明权限(config.json)
{
"requestPermissions": [
{ "name": "ohos.permission.DISTRIBUTED_DATASYNC" }
]
}
2. 动态申请权限代码
async requestPermissions(permissions) {
const appInfo = await bundle.getApplicationInfo(await this.getBundleName(), 0, 100);
let tokenId = appInfo.accessTokenId;
let atManager = abilityAccessCtrl.createAtManager();
// 校验权限是否已授予
let results = await Promise.all(
permissions.map(p => atManager.verifyAccessToken(tokenId, p))
);
// 筛选未授予权限并发起申请
let requestList = permissions.filter((_, i) =>
results[i] == abilityAccessCtrl.GrantStatus.PERMISSION_DENIED
);
if (requestList.length > 0) {
await this.context.requestPermissionsFromUser(requestList);
}
}
4.5 跨设备远程拉起 Ability
认证组网成功后,可通过 want 参数指定远端设备,拉起对应应用并传参。
1. 主动拉起端代码
connectStageAbility(device) {
var want = {
"deviceId": device.deviceId, // 目标远端设备ID
"bundleName": "com.example.myapplication_distributeddevicemanager", // 目标应用包名
"abilityName": "MainAbility", // 目标页面Ability名
parameters: { content: "来自远程设备" } // 跨设备传递参数
};
// 发起远程拉起
globalThis.context.startAbility(want);
}
2. 远端接收端代码
aboutToAppear() {
// 接收远程传参
let parameter = globalThis.content;
if (parameter) {
AlertDialog.show({
title: '当前应用被远程启动',
message: parameter.content
});
}
// 初始化设备管理能力
this.createDeviceManager();
}
五、开发前置必备条件
| 环境/配置项 | 具体要求 |
|---|---|
| 系统版本 | OpenHarmony 3.1 Release 及以上 |
| API 版本 | API 9(适配 Stage 应用模型) |
| 网络环境 | 参与组网的设备必须连接同一 WiFi |
| 必备权限 | ohos.permission.DISTRIBUTED_DATASYNC(需动态申请) |
| 认证方式 | 系统原生 PIN 码配对认证,无需自定义页面 |
| 设备数量 | 至少 2 台 OpenHarmony 设备用于联调测试 |
六、核心学习重难点总结
| 序号 | 重难点 | 说明 |
|---|---|---|
| 1 | 核心入口唯一性 | DeviceManager 是所有分布式能力的唯一前置入口,所有跨设备操作必须先创建并初始化实例 |
| 2 | 固定组网三步曲 | 设备发现 → PIN码认证 → 可信组网,顺序不可颠倒,未认证设备无法进行跨设备交互 |
| 3 | 极简认证机制 | PIN 码配对弹窗、校验逻辑均为系统预置,开发者仅需调用认证 API 即可 |
| 4 | 可信设备持久化 | 认证通过的设备会被系统持久化保存,后续无需重复配对,可直接获取可信列表 |
| 5 | 权限硬性要求 | 跨设备拉起、分布式数据同步必须申请 DISTRIBUTED_DATASYNC 权限 |
| 6 | 跨设备传参规则 | 通过 want.parameters 传递自定义参数,远端页面在 aboutToAppear 中接收解析 |
| 7 | 扫描接口规范 | 设备启停扫描必须成对、共用同一 subscribeId,避免内存泄漏和扫描任务残留 |
七、常见问题小结
| 问题现象 | 排查要点 |
|---|---|
| 扫描不到设备 | 检查设备是否同 WiFi、权限是否开启、扫描参数是否合法、是否未停止上一次扫描任务 |
| 认证失败 | 核对 PIN 码、设备网络连通性、系统分布式开关是否开启 |
| 无法远程拉起应用 | 检查权限是否授予、包名/Ability 名是否匹配、设备是否在可信列表中 |
| 服务异常退出 | 页面销毁时及时调用 release() 释放实例,避免监听残留导致异常 |
八、完整交互时序图
sequenceDiagram
participant App as 应用(App)
participant DM as DeviceManager服务
participant Peer as 远端设备
App->>DM: createDeviceManager(bundleName)
App->>DM: on('deviceStateChange')
App->>DM: getTrustedDeviceListSync()
App->>DM: startDeviceDiscovery(info)
DM-->>App: on('deviceFound') 发现设备
App->>DM: stopDeviceDiscovery(subscribeId)
App->>DM: authenticateDevice(device, param)
DM->>Peer: PIN码配对认证
Peer-->>DM: 认证通过
DM-->>App: 认证成功回调
App->>Peer: startAbility(want) 跨设备拉起
Peer-->>App: 远程应用启动并接收参数
欢迎加入Laval社区
社区规范:仅讨论OpenHarmony相关问题。
更多推荐
所有评论(0)