NearLink Kit(星闪服务)在 HarmonyOS 7/API 26 中提供设备广播、扫描、连接管理和数据传输能力。官方 API 26 广播模块从 @kit.ConnectivityKit 导入,支持配置广播间隔、发射功率、是否可连接以及 Service/Manufacturer Data。产品页面还给出了 SSAP 与基于 Port 的高速数据传输场景。

星闪接入最容易犯的错误,是把“扫描到设备”当作完成。真正产品化必须处理权限、设备身份、去重、连接状态机、分包、流控、幂等、断线重连、固件版本与功耗。本文以智能手写笔配对为例给出完整链路。

HarmonyOS 7 新特性(五十)封面

一、从能力与权限门禁开始

入口显示前查询设备是否支持星闪、开关状态和应用权限。不支持时提供蓝牙、USB 或手动配对回退。

interface NearLinkReadiness {
  supported: boolean
  enabled: boolean
  permission: 'GRANTED' | 'DENIED' | 'NOT_REQUESTED'
}

type EntryState = 'READY' | 'ASK_PERMISSION' | 'OPEN_SETTINGS' | 'FALLBACK'

function entryState(r: NearLinkReadiness): EntryState {
  if (!r.supported) return 'FALLBACK'
  if (r.permission !== 'GRANTED') return 'ASK_PERMISSION'
  if (!r.enabled) return 'OPEN_SETTINGS'
  return 'READY'
}

权限只在用户主动进入配对流程后申请,拒绝时解释用途,不循环弹窗。

二、设计稳定的广播协议

广播包空间有限,适合携带协议版本、产品类型、短设备 ID、能力位和配对状态,不应放姓名、位置或长期密钥。

interface PenAdvertisementV1 {
  version: 1
  productType: number
  deviceIdShort: number
  capabilityBits: number
  pairingMode: boolean
  nonce: number
}

function encodeAd(data: PenAdvertisementV1): ArrayBuffer {
  // 使用确定的字节序和长度编码,附带版本与校验。
  return new ArrayBuffer(16)
}

协议文档要明确字节序、字段长度、保留位和未知版本处理。

三、API 26 广播参数与功耗平衡

官方参考显示 advertising.startAdvertising 使用的配置包含间隔、功率和 isConnectable 等。广播越频繁、功率越高,发现更快但耗电更大。

import { advertising } from '@kit.ConnectivityKit'

const settings: advertising.AdvertisingSettings = {
  interval: 5000,  // 1 slot = 0.125ms,5000 对应 625ms
  power: advertising.TxPowerMode.ADV_TX_POWER_LOW,
  isConnectable: true
}

枚举名称和对象完整字段以目标 API 26 d.ts 为准。配对页前台可缩短间隔,退出页面立即停止;普通后台不持续高频广播。

四、广播数据最小化

const params: advertising.AdvertisingParams = {
  advertisingSettings: settings,
  advertisingData: {
    serviceUuids: ['xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'],
    includeDeviceName: false,
    manufacturerData: [{
      manufacturerId: 1001,
      manufacturerData: encodeAd(localAdvertisement)
    }]
  }
}

示例展示结构思路。生产中不要广播真实设备名,短 ID 定期轮换,Nonce 防止简单重放和长期跟踪。

HarmonyOS 7 新特性(五十)核心链路

五、扫描结果先过滤、去重、聚合

同一设备会多次上报,信号强度也会抖动。UI 不应不断插入新行或按瞬时强度跳动排序。

interface ScanItem {
  rotatingId: string
  productType: number
  rssi: number
  lastSeen: number
  samples: number[]
}

function stableRssi(samples: number[]): number {
  const recent = samples.slice(-5).sort((a, b) => a - b)
  return recent[Math.floor(recent.length / 2)]
}

只接收目标 Service UUID 和合法厂商协议,超时设备淡出而不是永久保留。

六、设备身份不能依赖显示名称

显示名称可重复、可伪造。配对时需要设备长期公钥或受信凭据,广播短 ID 只用于发现。

interface DeviceIdentity {
  rotatingId: string
  publicKeyFingerprint: string
  productId: string
  firmwareVersion: string
  attestation?: string
}

首次配对展示用户可核对的信息,完成挑战响应后才写入信任列表。

七、连接使用显式状态机

type ConnectionState =
  | 'IDLE' | 'SCANNING' | 'CONNECTING' | 'AUTHENTICATING'
  | 'NEGOTIATING' | 'READY' | 'RECONNECTING' | 'DISCONNECTING' | 'FAILED'

interface ConnectionEvent {
  type: string
  deviceId: string
  attempt: number
  reason?: string
}

每次状态迁移记录原因和超时。READY 之前不开放业务命令,用户取消后阻止晚到的连接成功回调重新激活会话。

八、SSAP 与 Port 按流量类型分工

控制命令、小型属性读写适合服务交互;笔迹流、音频或固件等高吞吐数据可评估基于 Port 的传输。业务层定义统一通道接口。

interface DeviceChannel {
  sendCommand(request: CommandEnvelope): Promise<ResponseEnvelope>
  openStream(kind: 'PEN_POINTS' | 'FIRMWARE'): Promise<StreamChannel>
  close(reason: string): Promise<void>
}

这样底层从 SSAP 切换到 Port 不会污染页面和领域逻辑。

九、应用层协议必须分包、校验和幂等

无线传输可能出现分片、重试、重复和断线。每条消息携带协议版本、会话、序号、类型、长度和校验。

interface FrameHeader {
  protocolVersion: number
  sessionId: number
  sequence: number
  messageType: number
  payloadLength: number
  checksum: number
}

interface CommandEnvelope {
  requestId: string
  command: string
  payload: ArrayBuffer
}

同一 requestId 的重试返回已有结果,避免“设置参数”或“升级开始”重复执行。

十、流控与背压不可缺少

笔的采样速度可能高于应用消费速度。无限缓冲最终导致内存上涨和高延迟。

interface FlowWindow {
  maxInFlight: number
  highestAck: number
  nextSequence: number
}

function canSend(w: FlowWindow): boolean {
  return w.nextSequence - w.highestAck <= w.maxInFlight
}

控制命令优先于大文件;实时笔迹过期后宁可丢弃可预测点,也不要持续堆积旧数据。

十一、断线重连恢复会话而非盲目重发

interface ResumeToken {
  deviceFingerprint: string
  sessionId: number
  lastAckSequence: number
  expiresAt: number
}

function reconnectDelay(attempt: number): number {
  const base = Math.min(30_000, 500 * 2 ** attempt)
  return base + Math.floor(Math.random() * 300)
}

重连先重新认证并确认设备身份,再协商从哪个序号恢复。达到上限后停止后台重试,把控制权交给用户。

十二、固件升级是高风险事务

升级前确认电量、版本、包签名、空间和连接质量;传输可断点续传,设备侧只有验签成功后才能切换分区。

interface FirmwareManifest {
  productId: string
  version: string
  size: number
  sha256: string
  signature: string
  minimumBattery: number
}

失败时设备保持旧版本可启动。应用明确展示阶段和不可断电提示,但不能假装 100% 后继续长时间等待。

十三、隐私与日志

扫描结果可能反映附近设备,属于敏感环境信息。只在配对前台采集,退出即停止;日志使用短期哈希,不记录原始广播负载和长期设备 ID。

interface SafeNearLinkLog {
  deviceHash: string
  state: ConnectionState
  errorCode?: number
  protocolVersion: number
  firmwareVersion?: string
  timestamp: number
}

诊断包导出需要用户确认并设置有效期。

十四、真机与干扰测试

const scenarios = [
  'single-device-pair', 'ten-device-scan', 'duplicate-name',
  'walk-out-of-range', 'toggle-nearlink', 'app-background',
  'packet-loss', 'replay-frame', 'firmware-resume', 'low-battery'
]

在不同距离、遮挡、Wi-Fi/蓝牙共存和多设备拥挤环境下测试。记录发现时延、连接成功率、重连时间、吞吐、功耗与温升。

HarmonyOS 7 新特性(五十)检查清单

十五、上线检查清单

  • 支持性、开关和权限有明确门禁与回退;
  • 广播协议带版本且不包含长期身份或敏感数据;
  • 广播间隔、功率随前后台场景调整;
  • 扫描结果按协议过滤、去重和稳定排序;
  • 配对使用可验证设备身份;
  • 连接状态机具备取消和超时;
  • SSAP 控制与 Port 大流量通道职责分开;
  • 消息分包、校验、序号与请求幂等完整;
  • 背压、断线恢复和重试上限经过验证;
  • 固件升级可验签、断点续传与安全回滚。

结语

NearLink Kit 提供了从发现、连接到传输的底层能力,但高质量设备体验来自上层协议工程。用轮换广播 ID 降低跟踪风险,用可信身份完成配对,用状态机和序号处理异步与断线,再让 SSAP 与 Port 按流量分工,星闪连接才能从演示走向可靠产品。扫描到设备只是起点,可恢复、可审计、低功耗地完成任务才是终点。

官方参考

  • NearLink Kit 产品介绍:https://developer.huawei.com/consumer/cn/sdk/nearlink-kit/
  • NearLink Kit 开发指南:https://developer.huawei.com/consumer/cn/doc/doccenter-capabilities/nearlink-kit-guide
  • API 26 星闪广播参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-nearlink-advertising
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐