如何使用NearLink Kit(二)星闪扫描连接 原创
在文章如何使用NearLink Kit实现星闪广播-| 华为开发者联盟中对NearLink Kit(星闪服务)做了完整的介绍,其中介绍了手机作为星闪服务端的实现API,本文中将介绍如何使用NearLink Kit中的API实现手机扫描、连接其他星闪设备,即星闪通信的第二种实现方式,如下:
方式二:手机扫描广播,连接外围设备
- 外围设备开启广播,等待被连接。
- 手机终端作为中心设备,通过扫描,发现外围设备,获取其广播数据。
- 外围设备和手机连接之后可以进行相应的数据传输。
效果下图所示:
一、NearLink 扫描
首先实现手机扫描周围星闪广播,通过设置过滤参数,获取到扫描结果。接口说明如下:
接口名 | 描述 |
---|---|
startScan(filters: Array<ScanFilters>, options?: ScanOptions): Promise<void> | 启动星闪扫描。 |
stopScan(): Promise<void> | 停止星闪扫描。 |
on(type: ‘deviceFound’, callback: Callback<Array<ScanResults>>): void | 订阅扫描结果。 |
off(type: ‘deviceFound’, callback?: Callback<Array<ScanResults>>): void | 取消订阅扫描结果。 |
1.接口设计
与星闪广播一样,将星闪扫描的方法添加到NearLinkAdvUtil类,扫描相关的两个方法与框架设计如下:
- 带筛选参数的扫描,并通过回调返回扫描结果
- 关闭星闪扫描
export class NearLinkAdvUtil
{
// 开启扫描,回调返回结果
public NearLinkFilterScan(address:string,deviceName:string,dataCallback: Callback<scan.ScanResults>)
{
}
// 停止扫描
public StopNearLinkScan()
{
}
}
2.接口实现
2.1 配置扫描参数
当前星闪扫描API必须指定扫描参数,否则接口调用会直接返回错误。
在NearLinkFilterScan方法中,可以设置如此参数:
- 指定一个目标设备MAC、设备名称(注意,scan.startScan接口支持添加多个筛选设备。)
- 扫描过滤器至少携带一个过滤条件,否则扫描过滤器无效。
- 过滤器可以配置多组,组之间的条件是或的关系。
- 一组过滤器内的条件是与的关系,如:address和deviceName同时满足才会上报。
- 扫描模式:
- scan.ScanMode.SCAN_MODE_LOW_POWER 低频率的扫描模式,省电
- scan.ScanMode.SCAN_MODE_BALANCED 中等频率的扫描模式,扫描快
// 导入相关模块
import { scan } from '@kit.NearLinkKit';import { BusinessError } from '@ohos.base';
// NearLinkFilterScan
public NearLinkFilterScan(address:string,deviceName:string,dataCallback: Callback<scan.ScanResults>)
{
// -------------------配置扫描参数 start----------------------
let scanFilter1: scan.ScanFilters = {
address: address, // e.g:"01:02:03:04:05:06" 期望扫描到的外围设备的地址
deviceName: deviceName // e.g "sle-server" 期望扫描到的外围设备的名称
};
let scanFilter2: scan.ScanFilters = {
address:"22:33:44:AB:CD:EF", // 期望扫描到的外围设备2的地址
deviceName:"deviceName2" // 期望扫描到的外围设备2的名称
};
let scanOptions: scan.ScanOptions = {
scanMode: scan.ScanMode.SCAN_MODE_LOW_POWER // 低频率的扫描模式,省电
// scanMode: scan.ScanMode.SCAN_MODE_BALANCED // 中等频率的扫描模式,扫描快
}
// ------------------配置扫描参数 end-----------------------
}
2.2 扫描结果回调
开启扫描之前,先实现扫描结果回调,使用接口
scan.on(type: ‘deviceFound’, callback: Callback<Array<ScanResults>>): void实现,
在NearLinkFilterScan方法中,onReceiveEvent作为扫描结果的回调函数,在该回调中,通过dataCallback函数dataCallback(data[0]);返回到外部调用,dataCallback()函数需要外部调用实现。
扫描结果回调实现代码如下:
public NearLinkFilterScan(address:string,deviceName:string,dataCallback: Callback<scan.ScanResults>)
{
// ----------------扫描结果回调 start-------------------
let onReceiveEvent:(data: Array<scan.ScanResults>) => void = (data: Array<scan.ScanResults>) => {
console.info('scan result addr:'+ data[0].address + 'name:' + data[0].deviceName);
dataCallback(data[0]); // 返回扫描值,便于外部调用
}
try {
scan.on("deviceFound", onReceiveEvent);
// 订阅星闪扫描结果。
// 如果应用拥有@ohos.permission.GET_NEARLINK_PEER_MAC权限,
// 则返回的扫描结果中携带远端设备真实地址,否则携带远端设备随机地址。
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ----------------扫描结果回调 end-------------------
}
2.3 开启星闪扫描
开启扫描接口为scan.startScan,调用2.1节配置的参数,开启扫描即可。
继续在NearLinkFilterScan方法中添加星闪扫描代码:
public NearLinkFilterScan(address:string,deviceName:string,dataCallback: Callback<scan.ScanResults>)
{
// ----------------开启星闪扫描 start-------------------
try { // 可以加入多个筛选设备
scan.startScan([scanFilter1, scanFilter2], scanOptions).then(() => {
console.info("start scan success");
});
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
// ----------------开启星闪扫描 end-------------------
}
2.4 停止星闪扫描
开启扫描接口为scan.startScan,调用2.1节配置的参数,开启扫描即可。
public StopNearLinkScan()
{
try {
scan.stopScan().then(() => {
console.info("stop scan success");
});
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
}
2.5 取消订阅扫描结果
如果需要取消订阅,可以使用scan.off实现,其中onReceiveEvent是在中2.2节中注册的扫描结果回调函数。
try {
scan.off("deviceFound", onReceiveEvent);}
catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);}
二、NearLink 连接
本节讲手机作为SSAP(SparkLink Service Access Protocol,星闪服务交互协议)客户端,去连接扫描到的星闪SSAP服务端。涉及的接口如下:
接口名 | 描述 |
---|---|
createClient(address: string): Client | 创建ssap客户端实例。 |
connect(): Promise<void> | 向服务端发起连接。 |
on(type: ‘connectionStateChange’, callback: Callback<ConnectionChangeState>): void | 订阅连接状态变化事件。 |
1.接口设计
与星闪广播一样,将星闪连接的方法添加到NearLinkAdvUtil类,连接相关的两个方法与框架设计如下:
- 使用星闪扫描到的远端设备MAC创建SSAP客户端并发起连接
export class NearLinkAdvUtil
{
// 给定设备信息,创建SSAP客户端并连接远端设备
public NearLinkStartConn(address:string)
{
}
}
2.接口实现
2.1 创建SSAP客户端
ssap.createClient()接口可以创建SSAP客户端实例,输入参数为云端星闪服务端端MAC。实现如下:
public NearLinkStartConn(address:string)
{
// 1.创建SSAP客户端,尝试连接SSAP服务端,并读/写服务端Property
try {
let addr: string = address // e.g '00:11:22:33:AA:FF'; 扫描获取到的远端设备地址
NearLinkAdvUtil.client = ssap.createClient(addr);
console.info('client: ' + JSON.stringify(NearLinkAdvUtil.client));
} catch (err) {
console.error('Create SSAP Error');
}
}
2.2 发起连接并订阅状态
主要有以下两个工作:
- 连接过程中的状态可以通过client.on(‘connectionStateChange’, onReceiveConnEvent);注册onReceiveConnEvent回调函数获取。
- 调用client.connect()连接目标SSAP服务端。
NearLinkStartConn中继续添加如下代码:
//2.连接状态回调
let onReceiveConnEvent:(data: ssap.ConnectionChangeState)
=> void = (data: ssap.ConnectionChangeState) => {
console.info('data:'+ JSON.stringify(data));
}
try {
NearLinkAdvUtil.client.on('connectionStateChange', onReceiveConnEvent);
} catch (err) {
console.error('errCode');
}
//3.发起星闪连接
try {
NearLinkAdvUtil.client.connect().then(() => {
console.info("connect success");
});
} catch (err) {
console.error('connect error');
}
三、Demo UI 实现
为了验证扫描、连接的接口是否正确,编写一个简单的页面验证。在星闪广播的UI基础上新增一个扫描连接的TabContent,该部分UI都放到NearLinkScanConnect自定义组件中。这里主要讲解以下几点核心实现:
- 如何通过List组件显示扫描结果
- 选中对应设备连接
1.通过List组件显示扫描结果
在NearLink扫描一节提到NearLinkAdvUtil.NearLinkFilterScan方法中scanDataCallback回调需要外部实现。
NearLinkAdvUtil.NearLinkFilterScan(this.address,this.deviceName,this.scanDataCallback)
首先,在UI中,定义NearLinkFilterScan方法的入口参数,并实现scanDataCallback,代码如下:
@Link address:string // 筛选地址
@Link deviceName:string // 筛选名称
@State scanDataArray: Array<scan.ScanResults> = [] // 扫描结果
private scanDataCallback: Callback<scan.ScanResults> = (data: scan.ScanResults) => {
if ((!this.scanDataArray.some(item => item.address === data.address)) && data.deviceName !== '') {
this.scanDataArray.push(data)
}
};
其次,在UI中使用按钮绑定扫描函数,点击即开启扫描
Button('开启扫描').onClick(()=>{
NearLinkAdvUtil.NearLinkFilterScan(this.address,this.deviceName,this.scanDataCallback)
})
再次,使用List显示scanDataArray数组。点击列表中的对应设备时,获取目标设备的名称。
@Component
struct NearLinkScanConnect
{
build() {
Column({space:20}){
List({ space: 10 }) {
ForEach(this.scanDataArray, (data: scan.ScanResults, index: number) => {
ListItem() {
Button() {
Column({ space: 5 }) {
Text(`${data.deviceName}`)
.fontSize(14)
.fontColor(Color.Black)
Text(`${data.address}`)
.fontSize(14)
.fontColor(Color.Black)
}
.alignItems(HorizontalAlign.Center)
}
.onClick(() => {
this.address = data.address;
this.deviceName = data.deviceName;
})
}
.width('100%')
})
}
}
}
}
最好,再使用发起连接按钮绑定连接方法。
Button('开启连接').onClick(()=>{
NearLinkAdvUtil.NearLinkStartConn(this.address)
})
连接之后可以获取SSAP服务端的信息,通过读/写相应的Property即可实现数据交互。目前因为没有手机以外的星闪终端产品,暂时无法验证数据传输功能。有条件的小伙伴可以尝试连接星闪鼠标,获取其服务。