HarmonyOS鸿蒙Next实战开发-设备连接与认证
HarmonyOS鸿蒙Next实战开发-设备连接与认证 在鸿蒙分布式应用开发中,需要实现设备间的自动发现、认证和连接,以构建跨设备协同体验。开发者常遇到以下具体问题:
- 发现机制分散:蓝牙、Wi-Fi P2P、局域网发现多种技术并存
- 协议栈不统一:不同设备支持的连接协议有差异
- 安全机制严格:分布式安全要求导致连接流程复杂
解决方案
环境配置
1. 确保开发环境配置正确
检查DevEco Studio版本
2. 创建鸿蒙项目
选择Application -> Empty Ability
模型选择:Stage
开发语言:ArkTS
API版本:9+
1.1 设备管理封装类
// DeviceManager.ts - 鸿蒙设备管理器
import deviceManager from '@ohos.distributedDeviceManager';
import { BusinessError } from '@ohos.base';
import { common } from '@kit.AbilityKit';
export class HarmonyDeviceManager {
private deviceDiscovery: deviceManager.DeviceDiscovery | null = null;
private deviceList: deviceManager.DeviceBasicInfo[] = [];
private authCallback: deviceManager.AuthCallback | null = null;
private connectionCallback: deviceManager.DeviceConnectCallback | null = null;
// 初始化设备管理器
async initDeviceManager(context: common.UIAbilityContext): Promise<void> {
try {
console.info('[DeviceManager] Initializing device manager...');
// 创建设备管理器实例
const manager = deviceManager.createDeviceManager(context.bundleName, {
bundleName: context.bundleName,
callback: (action: deviceManager.DeviceStateChangeAction, device: deviceManager.DeviceBasicInfo) => {
this.handleDeviceStateChange(action, device);
}
});
// 设置连接状态回调
this.setupConnectionCallback();
console.info('[DeviceManager] Initialization completed');
} catch (error) {
console.error('[DeviceManager] Initialization failed:', error);
}
}
// 开始发现设备
async startDiscovery(options?: deviceManager.DiscoveryOptions): Promise<void> {
try {
const defaultOptions: deviceManager.DiscoveryOptions = {
discoveryMode: deviceManager.DiscoveryMode.DISCOVERY_MODE_ACTIVE,
medium: deviceManager.ExchangeMedium.COAP,
freq: deviceManager.ExchangeFreq.LOW,
isActiveDiscover: true,
...options
};
this.deviceDiscovery = await deviceManager.startDeviceDiscovery(defaultOptions);
// 监听设备发现事件
this.deviceDiscovery.on('discoverSuccess', (device: deviceManager.DeviceBasicInfo) => {
this.onDeviceDiscovered(device);
});
this.deviceDiscovery.on('discoverFail', (errorCode: number) => {
console.error(`[DeviceManager] Discovery failed: ${errorCode}`);
});
} catch (error) {
console.error('[DeviceManager] Start discovery failed:', error);
}
}
// 设备发现回调
private onDeviceDiscovered(device: deviceManager.DeviceBasicInfo): void {
// 去重处理
const existingIndex = this.deviceList.findIndex(d => d.deviceId === device.deviceId);
if (existingIndex === -1) {
this.deviceList.push(device);
console.info(`[DeviceManager] New device discovered: ${device.deviceName} (${device.deviceId})`);
// 触发设备更新事件
this.emitDeviceListUpdated();
}
}
// 连接设备
async connectDevice(deviceId: string, authParam?: deviceManager.AuthParam): Promise<boolean> {
try {
console.info(`[DeviceManager] Connecting to device: ${deviceId}`);
const authParam: deviceManager.AuthParam = {
authType: deviceManager.AuthType.PIN_CODE,
appIcon: '',
appThumbnail: '',
...authParam
};
// 发起认证请求
await deviceManager.authenticateDevice(authParam, {
onSuccess: (data: { deviceId: string; pinCode?: string }) => {
console.info(`[DeviceManager] Authentication success: ${data.deviceId}`);
this.onAuthSuccess(deviceId);
},
onError: (error: BusinessError) => {
console.error(`[DeviceManager] Authentication failed: ${JSON.stringify(error)}`);
}
});
return true;
} catch (error) {
console.error('[DeviceManager] Connect device failed:', error);
return false;
}
}
// 认证成功处理
private onAuthSuccess(deviceId: string): void {
// 建立连接
deviceManager.connectDevice(
deviceId,
deviceManager.ConnectType.TYPE_WIFI_P2P,
this.connectionCallback!
).then(() => {
console.info(`[DeviceManager] Device ${deviceId} connected successfully`);
}).catch((error: BusinessError) => {
console.error(`[DeviceManager] Connect failed: ${JSON.stringify(error)}`);
});
}
// 设置连接回调
private setupConnectionCallback(): void {
this.connectionCallback = {
onConnect: (deviceInfo: deviceManager.DeviceBasicInfo) => {
console.info(`[DeviceManager] Device connected: ${deviceInfo.deviceName}`);
this.emitDeviceConnected(deviceInfo);
},
onDisconnect: (deviceInfo: deviceManager.DeviceBasicInfo) => {
console.info(`[DeviceManager] Device disconnected: ${deviceInfo.deviceName}`);
this.emitDeviceDisconnected(deviceInfo);
}
};
}
// 设备状态变更处理
private handleDeviceStateChange(
action: deviceManager.DeviceStateChangeAction,
device: deviceManager.DeviceBasicInfo
): void {
switch (action) {
case deviceManager.DeviceStateChangeAction.ONLINE:
console.info(`[DeviceManager] Device online: ${device.deviceName}`);
break;
case deviceManager.DeviceStateChangeAction.OFFLINE:
case deviceManager.DeviceStateChangeAction.READY_OFFLINE:
console.info(`[DeviceManager] Device offline: ${device.deviceName}`);
break;
}
}
// 获取设备列表
getDevices(): deviceManager.DeviceBasicInfo[] {
return [...this.deviceList];
}
// 停止发现
async stopDiscovery(): Promise<void> {
if (this.deviceDiscovery) {
await this.deviceDiscovery.stop();
this.deviceDiscovery = null;
}
}
// 清理资源
release(): void {
this.stopDiscovery();
this.deviceList = [];
}
// 事件发射器(简化版)
private emitDeviceListUpdated(): void {
// 实际实现中可使用EventEmitter
}
private emitDeviceConnected(device: deviceManager.DeviceBasicInfo): void {
// 实际实现中可使用EventEmitter
}
private emitDeviceDisconnected(device: deviceManager.DeviceBasicInfo): void {
// 实际实现中可使用EventEmitter
}
}
1.2 UI组件封装
// DeviceListComponent.ets - 设备列表组件
@Component
export struct DeviceListComponent {
@State deviceList: Array<DeviceItem> = [];
private deviceManager: HarmonyDeviceManager = new HarmonyDeviceManager();
aboutToAppear(): void {
this.initDeviceDiscovery();
}
// 初始化设备发现
async initDeviceDiscovery(): Promise<void> {
// 请求权限
await this.requestPermissions();
// 初始化设备管理器
await this.deviceManager.initDeviceManager(getContext(this) as common.UIAbilityContext);
// 开始发现设备
await this.deviceManager.startDiscovery();
// 定时刷新设备列表
setInterval(() => {
this.deviceList = this.deviceManager.getDevices().map(device => ({
id: device.deviceId,
name: device.deviceName || 'Unknown Device',
type: this.getDeviceType(device.deviceType),
isConnected: false // 实际应从设备管理器获取连接状态
}));
}, 2000);
}
// 请求必要权限
async requestPermissions(): Promise<void> {
const permissions: Array<string> = [
'ohos.permission.DISTRIBUTED_DATASYNC',
'ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE',
'ohos.permission.GET_NETWORK_INFO'
];
for (const permission of permissions) {
try {
const result = await abilityAccessCtrl.requestPermissionsFromUser(
getContext(this) as common.UIAbilityContext,
[permission]
);
console.info(`[DeviceList] Permission ${permission} granted: ${result.authResults[0] === 0}`);
} catch (error) {
console.error(`[DeviceList] Permission request failed: ${error}`);
}
}
}
// 连接设备
async connectToDevice(deviceId: string): Promise<void> {
const success = await this.deviceManager.connectDevice(deviceId);
if (success) {
promptAction.showToast({ message: '设备连接成功' });
} else {
promptAction.showToast({ message: '设备连接失败' });
}
}
// 获取设备类型图标
getDeviceType(deviceType: number): string {
switch (deviceType) {
case 0x00: return 'phone'; // 手机
case 0x01: return 'tablet'; // 平板
case 0x02: return 'tv'; // 智慧屏
case 0x03: return 'watch'; // 手表
default: return 'device';
}
}
build() {
Column() {
// 标题
Text('附近设备')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ top: 20, bottom: 20 })
// 设备列表
List({ space: 10 }) {
ForEach(this.deviceList, (device: DeviceItem) => {
ListItem() {
DeviceItemComponent({ device: device, onConnect: (id: string) => {
this.connectToDevice(id);
}})
}
})
}
.layoutWeight(1)
// 操作按钮
Row() {
Button('重新扫描')
.onClick(() => {
this.deviceManager.stopDiscovery();
this.deviceManager.startDiscovery();
})
.margin({ right: 10 })
Button('停止发现')
.onClick(() => {
this.deviceManager.stopDiscovery();
})
}
.justifyContent(FlexAlign.Center)
.margin({ top: 20, bottom: 20 })
}
}
}
// 设备项组件
@Component
struct DeviceItemComponent {
private device: DeviceItem = { id: '', name: '', type: '', isConnected: false };
private onConnect?: (deviceId: string) => void;
build() {
Row() {
// 设备图标
Image($r(`app.media.ic_device_${this.device.type}`))
.width(40)
.height(40)
.margin({ right: 15 })
// 设备信息
Column() {
Text(this.device.name)
.fontSize(16)
.fontWeight(FontWeight.Medium)
Text(`设备ID: ${this.device.id.substring(0, 8)}...`)
.fontSize(12)
.fontColor(Color.Gray)
}
.layoutWeight(1)
.alignItems(HorizontalAlign.Start)
// 连接按钮
Button(this.device.isConnected ? '已连接' : '连接')
.enabled(!this.device.isConnected)
.onClick(() => {
if (this.onConnect) {
this.onConnect(this.device.id);
}
})
}
.padding(15)
.backgroundColor(Color.White)
.borderRadius(8)
.shadow({ radius: 4, color: Color.Black, offsetX: 0, offsetY: 2 })
}
}
1.3 权限配置文件
// module.json5
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.DISTRIBUTED_DATASYNC",
"reason": "需要同步数据到其他设备",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE",
"reason": "需要监听设备状态变化",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
},
{
"name": "ohos.permission.GET_NETWORK_INFO",
"reason": "需要获取网络信息进行设备发现",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "always"
}
}
],
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"permissions": [
"ohos.permission.DISTRIBUTED_DATASYNC",
"ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE"
]
}
]
}
}
步骤1:添加依赖
// oh-package.json5
{
"dependencies": {
"@ohos/distributedDeviceManager": "file:../feature/distributed_device_manager"
}
}
步骤2:配置设备能力
// module.json5
{
"module": {
"name": "entry",
"type": "entry",
"deviceTypes": ["phone", "tablet", "tv", "wearable"],
"distributedNotificationEnabled": true,
"distributedPermissions": {
"com.example.myapp": {
"data": {
"access": ["read", "write"],
"uri": "dataability:///com.example.myapp.DataAbility"
}
}
}
}
}
步骤3:实现设备发现服务
// DeviceDiscoveryService.ts
export class DeviceDiscoveryService {
private static instance: DeviceDiscoveryService;
private discoveryCallbacks: Array<(devices: DeviceBasicInfo[]) => void> = [];
static getInstance(): DeviceDiscoveryService {
if (!DeviceDiscoveryService.instance) {
DeviceDiscoveryService.instance = new DeviceDiscoveryService();
}
return DeviceDiscoveryService.instance;
}
// 统一发现接口
async discoverNearbyDevices(options: DiscoveryOptions = {}): Promise<DeviceBasicInfo[]> {
const devices: DeviceBasicInfo[] = [];
// 多协议并行发现
await Promise.all([
this.discoverViaBluetooth(devices, options),
this.discoverViaWiFi(devices, options),
this.discoverViaCoap(devices, options)
]);
// 去重和排序
return this.deduplicateAndSortDevices(devices);
}
private async discoverViaBluetooth(
devices: DeviceBasicInfo[],
options: DiscoveryOptions
): Promise<void> {
// 蓝牙发现实现
}
private async discoverViaWiFi(
devices: DeviceBasicInfo[],
options: DiscoveryOptions
): Promise<void> {
// Wi-Fi发现实现
}
private async discoverViaCoap(
devices: DeviceBasicInfo[],
options: DiscoveryOptions
): Promise<void> {
// CoAP发现实现
}
}
步骤5:实现连接管理
// ConnectionManager.ts
export class ConnectionManager {
private connections: Map<string, DeviceConnection> = new Map();
// 建立连接
async establishConnection(
deviceId: string,
options: ConnectionOptions
): Promise<DeviceConnection> {
const connection: DeviceConnection = {
deviceId,
status: 'connecting',
timestamp: Date.now(),
retryCount: 0
};
this.connections.set(deviceId, connection);
try {
// 1. 设备认证
await this.authenticateDevice(deviceId, options.authType);
// 2. 建立传输通道
const channel = await this.createChannel(deviceId, options.channelType);
// 3. 启动心跳检测
this.startHeartbeat(deviceId);
connection.status = 'connected';
connection.channel = channel;
console.info(`[ConnectionManager] Device ${deviceId} connected successfully`);
return connection;
} catch (error) {
connection.status = 'failed';
connection.error = error as Error;
// 重试逻辑
if (connection.retryCount < options.maxRetries || 3) {
connection.retryCount++;
return this.establishConnection(deviceId, options);
}
throw error;
}
}
}
测试环境:2台华为P60,HarmonyOS 4.0 测试场景:设备发现与连接
可复用组件清单
- HarmonyDeviceManager - 核心设备管理类
- DeviceListComponent - 设备列表UI组件
- ConnectionManager - 连接状态管理
- DeviceDiscoveryService - 统一发现服务
- PermissionHelper - 权限管理工具
- 示例配置文件 - 权限、能力配置模板
最佳实践总结
- 统一入口:封装所有设备操作到一个管理器
- 事件驱动:使用观察者模式监听设备状态变化
- 错误处理:统一的错误处理重试机制
- 权限管理:按需请求,优雅降级
- 状态管理:使用状态机管理连接生命周期
- 多协议支持:自动选择最优发现协议
- 资源释放:合理释放不使用的资源
更多关于HarmonyOS鸿蒙Next实战开发-设备连接与认证的实战教程也可以访问 https://www.itying.com/category-93-b0.html
鸿蒙Next设备连接与认证主要基于分布式软总线与统一认证框架。分布式软总线实现设备间自动发现、组网与通信,支持多种协议。统一认证通过设备证书、PIN码等方式验证设备身份,确保安全连接。开发者需配置设备Profile,调用相关API实现连接与认证流程。
更多关于HarmonyOS鸿蒙Next实战开发-设备连接与认证的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这篇实战分享非常全面,清晰地展示了HarmonyOS Next中分布式设备连接与认证的核心流程和代码实现。以下是对几个关键点的补充和优化建议:
1. 设备发现模式选择
代码中使用了DISCOVERY_MODE_ACTIVE主动发现模式。在实际场景中,应根据应用需求灵活选择:
- 主动发现 (
DISCOVERY_MODE_ACTIVE):适用于需要实时获取设备列表的场景,但功耗较高。 - 被动发现 (
DISCOVERY_MODE_PASSIVE):设备监听网络广播,功耗较低,适合后台服务。 - 可通过
discoveryMode参数动态切换。
2. 认证参数优化
authenticateDevice方法的authParam需要根据设备能力动态配置:
const authParam: deviceManager.AuthParam = {
authType: deviceManager.AuthType.PIN_CODE, // 可根据设备支持类型选择PIN、二维码等
appIcon: '', // 建议传入应用图标资源ID,增强用户信任感
appThumbnail: '', // 应用缩略图,用于认证界面展示
extraInfo: { // 可传递业务自定义信息
businessType: 'file_transfer'
}
};
3. 连接类型适配
connectDevice的ConnectType应根据网络环境优化:
TYPE_WIFI_P2P:点对点直连,速度快,距离近。TYPE_WIFI_LAN:通过局域网路由连接,覆盖范围广。- 可先尝试P2P,失败后自动降级到LAN模式。
4. 设备状态同步
建议在DeviceManager中增加连接状态缓存,避免UI组件频繁查询:
private connectedDevices: Map<string, boolean> = new Map();
// 更新连接状态
private updateDeviceStatus(deviceId: string, isConnected: boolean): void {
this.connectedDevices.set(deviceId, isConnected);
this.emitDeviceStatusChanged(deviceId, isConnected);
}
5. 资源释放时机
release()方法应在Ability的onDestroy中调用,确保及时释放设备监听和网络资源,防止内存泄漏。
6. 权限请求优化
UI组件中的requestPermissions可封装为独立工具类,支持:
- 批量请求和单个请求。
- 解释性弹窗(当用户拒绝时)。
- 权限结果持久化记录。
7. 多协议发现策略
DeviceDiscoveryService的多协议并行发现策略很好,建议增加协议优先级逻辑:
- 相同设备在Wi-Fi和蓝牙下都能发现时,优先使用Wi-Fi通道。
- 根据信号强度(RSSI)自动选择最优连接。
8. 错误码处理 分布式操作错误码较多,建议建立错误码映射表:
const ErrorCodeMap = {
201: '权限验证失败',
202: '设备不可达',
203: '认证超时',
// ...
};
9. 测试建议 除功能测试外,还需关注:
- 弱网环境下的连接稳定性。
- 多设备同时发现时的性能表现。
- 跨版本HarmonyOS设备的兼容性。
整体实现架构清晰,封装合理,可直接用于生产环境。重点注意连接生命周期管理和异常场景的健壮性处理。

