ITPub博客

首页 > 数据库 > 数据库开发技术 > 《HarmonyOS技术精讲-NearLink Kit(星闪服务)》第2篇:设备发现——星闪设备发现机制与API详解

《HarmonyOS技术精讲-NearLink Kit(星闪服务)》第2篇:设备发现——星闪设备发现机制与API详解

数据库开发技术 作者:CloudEngineer01 时间:2026-07-18 08:17:53 0 删除 编辑

《HarmonyOS技术精讲-NearLink Kit(星闪服务)》第2篇:设备发现——星闪设备发现机制与API详解

在这里插入图片描述

问题

HarmonyOS NEXT 开发里,startDiscovery 这个 API 经常被误用。很多人第一次接触 NearLink Kit 的设备发现能力时,会发现官方示例能运行,但放到实际项目里就遇到各种问题:扫描结果重复、回调不触发、页面离开后扫描还在跑。这个功能本身不复杂,但真正麻烦的是生命周期管理和扫描结果的去重处理。

它解决什么问题

NearLink Kit 是 HarmonyOS 提供的星闪通信服务框架。设备发现是星闪应用的第一步——扫描周边的星闪设备并获取设备的基础信息,比如设备名称、设备ID、信号强度等。

特性传统蓝牙扫描星闪设备发现
扫描模式被动扫描主动+被动混合
发现速度慢(约3-5秒)快(约1-2秒)
设备信息量有限更丰富
过滤能力有限支持多维度过滤

有两个典型场景适合用这个 API:

  • 智能家居设备配网前扫描周边设备
  • 会议系统发现附近的可投屏设备

不适合的场景:如果你只需要连接已知设备,直接使用连接 API 即可,没必要开启扫描。

环境说明

核心实现

1. 准备工作:权限配置

在 module.json5 中添加权限声明。这一步容易漏掉,很多人直接跑示例发现没反应,原因就是权限没配。

注意:NEARLINK_DISCOVERY 权限在 API 23 及以上版本才支持。如果跑在低版本设备上,这个权限不会生效,也不会报错,扫描就直接不回调了。

2. 发起设备发现扫描

这一段代码用于封装星闪发现的核心逻辑。实际项目里建议写成一个单独的服务类,不要直接把扫描逻辑塞进 UI 组件。

关键细节:

  • 防重复逻辑:onFound 回调会反复上报同一个设备,信号强度变化时也会再次回调。使用 deviceId 作为 Map 的 key 去重,只更新已存在设备的 RSSI,不重复添加。
  • discoveryId 管理:startDiscovery 返回一个 id,停止时要传入这个 id。如果页面销毁时没有保存这个 id,后续无法正确停止扫描。
  • filter 配置:不传 filter 会扫描周边所有星闪设备。如果只关心某个制造商的产品,用 DISCOVERY_FILTER_TYPE_MANUFACTURER 过滤效率更高。

3. 在页面中使用

这段代码展示如何在 UI 组件中调用发现服务,并处理生命周期。

注意 aboutToDisappear 中的 stopScan() 调用。实际项目里很多人漏掉这一步,导致页面返回后扫描还在持续,不仅耗电,还可能造成回调在已销毁页面中执行,引发异常。

4. 过滤条件完整示例

如果不希望扫描所有设备,可以用制造商数据过滤。这段代码展示如何只发现特定厂商的设备。

常见问题

问题 1:页面返回后扫描未停止

现象:从扫描页面返回,过一会儿发现手机还在发热,日志显示扫描回调仍在触发。

原因:aboutToDisappear 中没有调用 stopDiscovery。HarmonyOS 不会在页面销毁时自动停止已启动的扫描,需要开发者手动处理。

解决方案:严格在 aboutToDisappear 中停止扫描。如果服务类被多个页面共享,需要在服务类里判断是否有页面还在使用扫描,不要直接 stop。

问题 2:onFound 回调频繁触发同一设备

现象:一个设备在 3 秒内被回调 10 次,页面列表疯狂刷新。

原因:星闪设备会主动广播,每次收到广播都会触发回调。这不是 bug,而是星闪协议本身的特性。

解决方案:使用 deviceId 做去重,如上面的代码所示。注意:只更新 RSSI 等动态数据,不重复添加列表项。

最佳实践

  1. 不要把扫描逻辑直接写在 UI 组件里。扫描涉及状态管理、生命周期、回调处理,拆成独立服务类后测试和复用都更方便。

  2. stopDiscovery 必须在页面销毁时调用。这不是可选的。如果忘记停止,扫描会持续消耗电量,而且回调中操作 UI 时可能因为页面已销毁而崩溃。

  3. 回调中更新 UI 时注意线程。onFound 运行在非 UI 线程,不要直接操作 UI 组件。ArkTS 的 @State 变量是线程安全的,赋值即可触发刷新。但如果有复杂的 UI 操作,建议使用 setTimeout 或 postTask 切回主线程。

FAQ

Q:为什么真机正常,模拟器不生效?

A:星闪能力依赖硬件支持,模拟器不具备星闪硬件,所以 startDiscovery 调用后不会触发任何回调。必须在 real device 上测试。

Q:为什么页面返回后状态丢失?

A:检查 aboutToDisappear 是否正确调用了 stopDiscovery。另外,如果你在页面间切换时使用了 NavStack,注意 onPageShow 和 onPageHide 的生命周期,建议在 onPageHide 中暂停扫描,onPageShow 中恢复。

Q:过滤条件设置后,扫描不到设备怎么办?

A:先去掉 filter,测试是否能看到设备。如果能看见,说明 filter 配置错误。确认你的 filter value 和设备广播的制造商数据完全匹配(包括字节序和长度)。

如果你也遇到类似问题,可以重点检查生命周期和状态同步逻辑。不同设备上的星闪广播行为可能存在差异,建议真机测试。

原文作者:不羁的木木;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2018-11-27

  • 博文量
    15
  • 访问量
    1844