【HarmonyOS】鸿蒙应用蓝牙功能实现 (二)

GeorgeGcs
• 阅读 3

##鸿蒙开发能力 ##HarmonyOS SDK 应用服务 ##鸿蒙金融类应用 (金融理财 # 前言 蓝牙一般分为传统蓝牙(BR/EDR),低功耗蓝牙(BLE)两种。 鸿蒙将蓝牙的功能模块分的非常细。 基本上我们会用到access进行蓝牙状态的开启和关闭,以及状态查询。 在使用connection进行传统蓝牙模式的扫描和配对。 或者再使用ble低功耗蓝牙模式进行广播,发起广播,传输数据,以及消息订阅。

Demo示例: import { access } from '@kit.ConnectivityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { BlueToothMgr } from '../manager/BlueToothMgr'; import { abilityAccessCtrl, common } from '@kit.AbilityKit'; import { connection } from '@kit.ConnectivityKit'; import { map } from '@kit.ConnectivityKit'; import { pbap } from '@kit.ConnectivityKit';

@Entry @Component struct Index {

private TAG: string = "BlueToothTest";

// 蓝牙状态 @State @Watch('onChangeBlueTooth') isStartBlueTooth: boolean = false; @State userGrant: boolean = false;

@State mListDevice: Array = [];

async aboutToAppear() { await this.requestBlueToothPermission();

let state = access.getState();
console.log(this.TAG, "getState state: " + state);
if(state == 2){
  this.isStartBlueTooth = true;
}else{
  this.isStartBlueTooth = false;
}

}

private onChangeBlueTooth(){ if(!this.isStartBlueTooth){ return; } // 当前设备的蓝牙可发现状态 try { let res: boolean = connection.isBluetoothDiscovering(); console.info(this.TAG, 'isBluetoothDiscovering: ' + res); } catch (err) { console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message); }

// 访问信息相关功能
try {
  let mapMseProfile = map.createMapMseProfile();
  console.info(this.TAG, 'MapMse success:' + JSON.stringify(mapMseProfile));
} catch (err) {
  console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

// 访问电话簿相关功能
try {
  let pbapServerProfile = pbap.createPbapServerProfile();
  console.info(this.TAG, 'pbapServer success:' + JSON.stringify(pbapServerProfile));
} catch (err) {
  console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

try {
  connection.on('bluetoothDeviceFind', (data: Array<string>)=> {
    console.info(this.TAG, 'data length' + JSON.stringify(data));
    // 获取扫描可配对的设备列表
    this.mListDevice = data;
  });
  connection.startBluetoothDiscovery();
} catch (err) {
  console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}

}

// 用户申请权限 async reqPermissionsFromUser(): Promise<number[]> { let context = getContext() as common.UIAbilityContext; let atManager = abilityAccessCtrl.createAtManager(); let grantStatus = await atManager.requestPermissionsFromUser(context, ['ohos.permission.ACCESS_BLUETOOTH']); return grantStatus.authResults; }

// 用户申请蓝牙权限 async requestBlueToothPermission() { let grantStatus = await this.reqPermissionsFromUser(); for (let i = 0; i < grantStatus.length; i++) { if (grantStatus[i] === 0) { // 用户授权,可以继续访问目标操作 this.userGrant = true; } } }

setBlueToothState =()=>{ try { if(!this.isStartBlueTooth){ BlueToothMgr.Ins().setBlueToothAccess(true); }else{ BlueToothMgr.Ins().setBlueToothAccess(false); } let state = access.getState(); if(state == 2){ this.isStartBlueTooth = true; }else{ this.isStartBlueTooth = false; } console.log(this.TAG, "getState state: " + state); } catch (err) { console.error(this.TAG,'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message); } }

build() { RelativeContainer() { if(this.userGrant){ Text("蓝牙状态:" + this.isStartBlueTooth ? "开启" : "关闭") .id('HelloWorld') .fontSize(50) .fontWeight(FontWeight.Bold) .alignRules({ center: { anchor: 'container', align: VerticalAlign.Center }, middle: { anchor: 'container', align: HorizontalAlign.Center } }) .onClick(this.setBlueToothState)

    Text("蓝牙状态:" + this.isStartBlueTooth ? "开启" : "关闭")
      .id('HelloWorld')
      .fontSize(50)
      .fontWeight(FontWeight.Bold)
      .alignRules({
        center: { anchor: '__container__', align: VerticalAlign.Center },
        middle: { anchor: '__container__', align: HorizontalAlign.Center }
      })
      .onClick(this.setBlueToothState)


  }
}
.height('100%')
.width('100%')

}

@Builder ListView(){ List() { ForEach(this.mListDevice, (item: string, index: number) => { ListItem() { Row() { Text(item).fontSize(px2fp(22)).fontColor(Color.Black) } .width('100%') .height(px2vp(100)) .justifyContent(FlexAlign.Start) } }, (item: string, index: number) => JSON.stringify(item) + index) } .width('100%') .height('100%') } }

import { access, ble } from '@kit.ConnectivityKit'; import { BusinessError } from '@kit.BasicServicesKit';

export class BlueToothMgr {

private TAG: string = "BlueToothTest";

private static mBlueToothMgr: BlueToothMgr | undefined = undefined;

private advHandle: number = 0xFF; // default invalid value

public static Ins(){ if(!BlueToothMgr.mBlueToothMgr){ BlueToothMgr.mBlueToothMgr = new BlueToothMgr(); } return BlueToothMgr.mBlueToothMgr; }

// STATE_OFF 0 表示蓝牙已关闭。 // STATE_TURNING_ON 1 表示蓝牙正在打开。 // STATE_ON 2 表示蓝牙已打开。 // STATE_TURNING_OFF 3 表示蓝牙正在关闭。 // STATE_BLE_TURNING_ON 4 表示蓝牙正在打开LE-only模式。 // STATE_BLE_ON 5 表示蓝牙正处于LE-only模式。 // STATE_BLE_TURNING_OFF 6 表示蓝牙正在关闭LE-only模式。

/**

  • 设置蓝牙访问(开关状态)

  • @param isAccess true: 打开蓝牙

  • / setBlueToothAccess(isAccess: boolean){ try { if(isAccess){

    console.info(this.TAG, 'bluetooth enableBluetooth 1');
    access.enableBluetooth();
    console.info(this.TAG, 'bluetooth enableBluetooth ');
    access.on('stateChange', (data: access.BluetoothState) => {
      let btStateMessage = this.switchState(data);
      if (btStateMessage == 'STATE_ON') {
        access.off('stateChange');
      }
      console.info(this.TAG, 'bluetooth statues: ' + btStateMessage);
    })

    }else{

    console.info(this.TAG, 'bluetooth disableBluetooth 1');
    access.disableBluetooth();
    console.info(this.TAG, 'bluetooth disableBluetooth ');
    access.on('stateChange', (data: access.BluetoothState) => {
      let btStateMessage = this.switchState(data);
      if (btStateMessage == 'STATE_OFF') {
        access.off('stateChange');
      }
      console.info(this.TAG, "bluetooth statues: " + btStateMessage);
    })

    } } catch (err) { console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message); } }

    private switchState(data: access.BluetoothState){ let btStateMessage = ''; switch (data) { case 0:

    btStateMessage += 'STATE_OFF';
    break;

    case 1:

    btStateMessage += 'STATE_TURNING_ON';
    break;

    case 2:

    btStateMessage += 'STATE_ON';
    break;

    case 3:

    btStateMessage += 'STATE_TURNING_OFF';
    break;

    case 4:

    btStateMessage += 'STATE_BLE_TURNING_ON';
    break;

    case 5:

    btStateMessage += 'STATE_BLE_ON';
    break;

    case 6:

    btStateMessage += 'STATE_BLE_TURNING_OFF';
    break;

    default:

    btStateMessage += 'unknown status';
    break;

    } return btStateMessage; }

    /**

  • 主播蓝牙广播

  • / public registerBroadcast(){ try { ble.on('advertisingStateChange', (data: ble.AdvertisingStateChangeInfo) => {

    console.info(this.TAG, 'bluetooth advertising state = ' + JSON.stringify(data));
    AppStorage.setOrCreate('advertiserState', data.state);

    }); } catch (err) { console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message); } }

    /**

  • 开启蓝牙广播

  • / public async startBroadcast(valueBuffer: Uint8Array){

    // 表示发送广播的相关参数。 let setting: ble.AdvertiseSetting = { // 表示广播间隔,最小值设置160个slot表示100ms,最大值设置16384个slot,默认值设置为1600个slot表示1s。 interval: 160, // 表示发送功率,最小值设置-127,最大值设置1,默认值设置-7,单位dbm。推荐值:高档(1),中档(-7),低档(-15)。 txPower: 0, // 表示是否是可连接广播,默认值设置为true,表示可连接,false表示不可连接。 connectable: true };

    // BLE广播数据包的内容。 let manufactureDataUnit: ble.ManufactureData = { // 表示制造商的ID,由蓝牙SIG分配。 manufactureId: 4567, manufactureValue: valueBuffer.buffer };

    let serviceValueBuffer = new Uint8Array(4); serviceValueBuffer[0] = 5; serviceValueBuffer[1] = 6; serviceValueBuffer[2] = 7; serviceValueBuffer[3] = 8;

    // 广播包中服务数据内容。 let serviceDataUnit: ble.ServiceData = { serviceUuid: "00001888-0000-1000-8000-00805f9b34fb", serviceValue: serviceValueBuffer.buffer };

    // 表示广播的数据包内容。 let advData: ble.AdvertiseData = { serviceUuids: ["00001888-0000-1000-8000-00805f9b34fb"], manufactureData: [manufactureDataUnit], serviceData: [serviceDataUnit], includeDeviceName: false // 表示是否携带设备名,可选参数。注意带上设备名时广播包长度不能超出31个字节。 };

    // 表示回复扫描请求的响应内容。 let advResponse: ble.AdvertiseData = { serviceUuids: ["00001888-0000-1000-8000-00805f9b34fb"], manufactureData: [manufactureDataUnit], serviceData: [serviceDataUnit] };

    // 首次启动广播设置的参数。 let advertisingParams: ble.AdvertisingParams = { advertisingSettings: setting, advertisingData: advData, advertisingResponse: advResponse, // 表示发送广播持续的时间。单位为10ms,有效范围为1(10ms)到65535(655350ms),如果未指定此参数或者将其设置为0,则会连续发送广播。 duration: 0 // 可选参数,若大于0,则广播发送一段时间后,则会临时停止,可重新启动发送 }

    // 首次启动广播,且获取所启动广播的标识ID try { this.registerBroadcast(); this.advHandle = await ble.startAdvertising(advertisingParams); } catch (err) { console.error(this.TAG, 'errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message); } }

}

点赞
收藏
评论区
推荐文章
GeorgeGcs GeorgeGcs
16小时前
【 HarmonyOS 5 入门系列 】鸿蒙HarmonyOS示例项目讲解
【HarmonyOS5入门系列】鸿蒙HarmonyOS示例项目讲解\鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言:移动开发声明式UI框架的技术变革在移动操作系统的发展历程中,UI开发模式经历了从命令式到声明式的重大变革。根据
GeorgeGcs GeorgeGcs
16小时前
【HarmonyOS 5】AttributeModifier和AttributeUpdater区别详解
【HarmonyOS5】AttributeModifier和AttributeUpdater区别详解\鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、AttributeModifier和AttributeUpdater的定义和作用1
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言在HarmonyOS5的应用开发模型中,featureAbility是旧版FA模型(FeatureAbility)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙中的UIAbility详解(二)
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言今天我们继续深入讲解UIAbility,根据下图可知,在鸿蒙中UIAbility继承于Ability,开发者无法直接继承Ability。只能使用其两个子类:UIAbility和Ex
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙中Stage模型与FA模型详解
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言在HarmonyOS5的应用开发模型中,featureAbility是旧版FA模型(FeatureAbility)的用法,Stage模型已采用全新的应用架构,推荐使用组件化的上下文
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】使用openCustomDialog如何禁止手势关闭的方案
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言在HarmonyOS中使用openCustomDialog自定义弹框时,我们会遇到实现禁止手势关闭弹框的业务场景。虽然在HarmonyOSNext中,自定义Dialog默认可能继承
GeorgeGcs GeorgeGcs
7小时前
【HarmonyOS 5】鸿蒙中@State的原理详解
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、@State在鸿蒙中是做什么的?@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式。通过将变量标记为@State
GeorgeGcs GeorgeGcs
5小时前
【HarmonyOS 5】鸿蒙用户头像编辑功能实践
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、前言1、应用背景在鸿蒙化开发过程中,我们发现最基本常见的功能用户头像的编辑,实现方式和Android与IOS有极大的不同。在实际开发和调研的过程中,我们发现并总结了鸿蒙隐私处理与业内A
GeorgeGcs GeorgeGcs
5小时前
【HarmonyOS】鸿蒙应用蓝牙功能实现(一)
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财前言蓝牙技术是一种无线通信技术,可以在短距离内传输数据。它是由爱立信公司于1994年提出的,使用2.4GHz的ISM频段,可以在10米左右的距离内进行通信。可以用于连接手机、耳机、音箱、键
GeorgeGcs GeorgeGcs
5小时前
【HarmonyOS】鸿蒙应用蓝牙功能实现 (三)
鸿蒙开发能力HarmonyOSSDK应用服务鸿蒙金融类应用(金融理财一、蓝牙配对业务流程1‌.设备进入可被发现模式‌:首先,设备需要进入可被发现模式,这样周围的蓝牙设备才能识别到它。一方设备(如手机)会主动搜索附近的蓝牙设备,并列出所有可用的配对选项。2‌
GeorgeGcs
GeorgeGcs
Lv1
男 · 金融头部企业 · 鸿蒙应用架构师
HarmonyOS认证创作先锋,华为HDE专家,鸿蒙讲师,作者。目前任职鸿蒙应用架构师。 历经腾讯,宝马,研究所,金融。 待过私企,外企,央企。 深耕大应用开发领域十年。 AAE,Harmony(OpenHarmony\HarmonyOS),MAE(Android\IOS),FE(H5\Vue\RN)。
文章
56
粉丝
1
获赞
2