.markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rgba(37, 41, 51, 1) }
.markdown-body h1, .markdown-body h2, .markdown-body h3, .markdown-body h4, .markdown-body h5, .markdown-body h6 { line-height: 1.5; margin-top: 35px; margin-bottom: 10px; padding-bottom: 5px }
.markdown-body h1 { font-size: 24px; line-height: 38px; margin-bottom: 5px }
.markdown-body h2 { font-size: 22px; line-height: 34px; padding-bottom: 12px; border-bottom: 1px solid rgba(236, 236, 236, 1) }
.markdown-body h3 { font-size: 20px; line-height: 28px }
.markdown-body h4 { font-size: 18px; line-height: 26px }
.markdown-body h5 { font-size: 17px; line-height: 24px }
.markdown-body h6 { font-size: 16px; line-height: 24px }
.markdown-body p { line-height: inherit; margin-top: 22px; margin-bottom: 22px }
.markdown-body img { max-width: 100% }
.markdown-body hr { border-top: 1px solid rgba(221, 221, 221, 1); border-right: none; border-bottom: none; border-left: none; margin-top: 32px; margin-bottom: 32px }
.markdown-body code { border-radius: 2px; overflow-x: auto; background-color: rgba(255, 245, 245, 1); color: rgba(255, 80, 44, 1); font-size: 0.87em; padding: 0.065em 0.4em }
.markdown-body code, .markdown-body pre { font-family: Menlo, Monaco, Consolas, Courier New, monospace }
.markdown-body pre { overflow: auto; position: relative; line-height: 1.75 }
.markdown-body pre>code { font-size: 12px; padding: 15px 12px; margin: 0; word-break: normal; display: block; overflow-x: auto; color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.markdown-body a { text-decoration: none; color: rgba(2, 105, 200, 1); border-bottom: 1px solid rgba(209, 233, 255, 1) }
.markdown-body a:active, .markdown-body a:hover { color: rgba(39, 91, 140, 1) }
.markdown-body table { display: inline-block !important; font-size: 12px; width: auto; max-width: 100%; overflow: auto; border: 1px solid rgba(246, 246, 246, 1) }
.markdown-body thead { background: rgba(246, 246, 246, 1); color: rgba(0, 0, 0, 1); text-align: left }
.markdown-body tr:nth-child(2n) { background-color: rgba(252, 252, 252, 1) }
.markdown-body td, .markdown-body th { padding: 12px 7px; line-height: 24px }
.markdown-body td { min-width: 120px }
.markdown-body blockquote { color: rgba(102, 102, 102, 1); padding: 1px 23px; margin: 22px 0; border-left: 4px solid rgba(203, 203, 203, 1); background-color: rgba(248, 248, 248, 1) }
.markdown-body blockquote:after { display: block; content: "" }
.markdown-body blockquote>p { margin: 10px 0 }
.markdown-body ol, .markdown-body ul { padding-left: 28px }
.markdown-body ol li, .markdown-body ul li { margin-bottom: 0; list-style: inherit }
.markdown-body ol li .task-list-item, .markdown-body ul li .task-list-item { list-style: none }
.markdown-body ol li .task-list-item ol, .markdown-body ol li .task-list-item ul, .markdown-body ul li .task-list-item ol, .markdown-body ul li .task-list-item ul { margin-top: 0 }
.markdown-body ol ol, .markdown-body ol ul, .markdown-body ul ol, .markdown-body ul ul { margin-top: 3px }
.markdown-body ol li { padding-left: 6px }
.markdown-body .contains-task-list { padding-left: 0 }
.markdown-body .task-list-item { list-style: none }
@media (max-width: 720px) { .markdown-body h1 { font-size: 24px } .markdown-body h2 { font-size: 20px } .markdown-body h3 { font-size: 18px } }.markdown-body pre, .markdown-body pre>code.hljs { color: rgba(51, 51, 51, 1); background: rgba(248, 248, 248, 1) }
.hljs-comment, .hljs-quote { color: rgba(153, 153, 136, 1); font-style: italic }
.hljs-keyword, .hljs-selector-tag, .hljs-subst { color: rgba(51, 51, 51, 1); font-weight: 700 }
.hljs-literal, .hljs-number, .hljs-tag .hljs-attr, .hljs-template-variable, .hljs-variable { color: rgba(0, 128, 128, 1) }
.hljs-doctag, .hljs-string { color: rgba(221, 17, 68, 1) }
.hljs-section, .hljs-selector-id, .hljs-title { color: rgba(153, 0, 0, 1); font-weight: 700 }
.hljs-subst { font-weight: 400 }
.hljs-class .hljs-title, .hljs-type { color: rgba(68, 85, 136, 1); font-weight: 700 }
.hljs-attribute, .hljs-name, .hljs-tag { color: rgba(0, 0, 128, 1); font-weight: 400 }
.hljs-link, .hljs-regexp { color: rgba(0, 153, 38, 1) }
.hljs-bullet, .hljs-symbol { color: rgba(153, 0, 115, 1) }
.hljs-built_in, .hljs-builtin-name { color: rgba(0, 134, 179, 1) }
.hljs-meta { color: rgba(153, 153, 153, 1); font-weight: 700 }
.hljs-deletion { background: rgba(255, 221, 221, 1) }
.hljs-addition { background: rgba(221, 255, 221, 1) }
.hljs-emphasis { font-style: italic }
.hljs-strong { font-weight: 700 }

React-Native开发鸿蒙NEXT-蓝牙信标读取

原创 悬空八只脚 悬空八只脚 2024年11月12日 09:46 江苏

项目中用到了ble蓝牙,应用启动后开始定时轮询周边蓝牙设备,根据读取到的数据判断是否是后台绑定的蓝牙设备,并返回给RN端做业务处理。

关于使用前蓝牙权限请求可以参考之前的文章,申请"ohos.permission.ACCESS_BLUETOOTH"权限。

React-Native开发鸿蒙NEXT-权限处理

悬空八只脚,公众号:悬空八只脚React-Native开发鸿蒙NEXT-权限处理

根据业务需要,RN端比较简单,仅仅在app启动判断获取到蓝牙权限后,触发ArkTS端的定时器,开始进行蓝牙扫描,在ArkTS端对扫描到的蓝牙设备进行过滤与数据处理,将最终结果传给RN。

RN端创建BluetoothTurboModule.tsx,仅提供开启/关闭轮询的方法,以及立即触发单次蓝牙查询。

BluetoothTurboModule.tsx

import {TurboModule, TurboModuleRegistry} from 'react-native';
export interface SpecBluetoothTurboModule extends TurboModule {
startTimer(seconds: number): void;
stopTimer(): void;
query(): void;}
export default TurboModuleRegistry.getEnforcing<SpecBluetoothTurboModule>( 'BluetoothTurboModule',);

再来看下ArkTS端的处理。ArkTS端主要处理都在BluetoothTurboModule.ets中完成。包括开启与关闭定时器,进行蓝牙搜索。核心是利用"@kit.ConnectivityKit"类来实现蓝牙搜索操作,通过绑定"BLEDeviceFind"来获取并处理搜索到蓝牙设备。

在使用过程中,发现一个问题,在最新的Ohos_sdk_public 5.0.0.71 (API Version 12 Release)这个版本上,我这的蓝牙硬件设备返回的name字段成了"",但在上个版本的sdk中还是可以正常返回的。不清楚是否是sdk的问题。如果需要使用到name字段来过滤蓝牙列表的同学需要注意下。

/*
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*/ import { TurboModule } from '@rnoh/react-native-openharmony/ts';
import emitter from '@ohos.events.emitter';
import { preferences } from '../entryability/EntryAbility'
import { BusinessError } from '@ohos.base';
import {BluetoothBean} from '../model/DataModel'
import { ble } from '@kit.ConnectivityKit';
import ConstUtil from '../utils/ConstUtil'
export interface TurboModuleEventData {
param: string
} export class BluetoothTurboModule extends TurboModule {
_bluetoothTimer:number = -1; query() {
try {
ble.stopBLEScan();
console.info('BLEDeviceQuery');
// 可以使用蓝牙名称来对蓝牙进行过滤,减少搜索到的蓝牙数量
let scanFilter: ble.ScanFilter = {
// name:"XXXXX",
};
let scanOptions: ble.ScanOptions = {
interval: 2000,
dutyMode: ble.ScanDuty.SCAN_MODE_LOW_POWER,
matchMode: ble.MatchMode.MATCH_MODE_AGGRESSIVE
}
ble.startBLEScan([scanFilter],scanOptions);
console.info('ble.startBLEScan');
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
//errCode: 2900003, errMessage: BusinessError 2900003: Bluetooth switch is off.
}
} startTimer(seconds: number) {
console.log("startTimer from BluetoothTurboModule: " + seconds);
try {
ble.off('BLEDeviceFind', this.onReceiveEvent);
ble.on("BLEDeviceFind", this.onReceiveEvent);
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
//errCode: 2900003, errMessage: BusinessError 2900003: Bluetooth switch is off.
}
if(seconds > 0){
this._bluetoothTimer = setInterval(() => {
console.log('do every ' + seconds * 1000 + 's');
this.query();
}, seconds * 1000);
}
} stopTimer() {
console.log("stopTimer from BluetoothTurboModule: ")
if(this._bluetoothTimer != -1){
clearInterval(this._bluetoothTimer);
}
try {
ble.stopBLEScan();
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
} onReceiveEvent(data: Array<ble.ScanResult>) {
console.info('BLE scan device find result = '+ JSON.stringify(data));
let _bleArray:Array<BluetoothBean> = [];
if(data == null || data.length == 0){
// 未扫描到蓝牙
// 发送给Index.ets,通过Index发送给RN
emitter.emit(ConstUtil.event_id_ble_scan_result,{data:_bleArray});
}else{
// 扫描到蓝牙设备
let _bleArray:Array<BluetoothBean> = [];
data.forEach((object:ble.ScanResult)=>{
if(object.data && object.data.byteLength > 0){
// 这里添加对蓝牙数据的处理,如获取uuid,major,minor。。。。。。
}
});
// 发送给Index.ets,通过Index发送给RN
emitter.emit(ConstUtil.event_id_ble_scan_result,{data:_bleArray});
}
try {
ble.stopBLEScan();
} catch (err) {
console.error('errCode: ' + (err as BusinessError).code + ', errMessage: ' + (err as BusinessError).message);
}
}
}

微信扫一扫

关注该公众号悬空八只脚

React-Native开发鸿蒙NEXT-蓝牙信标读取的更多相关文章

  1. React Native开发入门

    目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料   一.前言 虽然只是简单的了解了一下Reac ...

  2. React Native开发技术周报2

    (1).资讯 1.React Native 0.22_rc版本发布 添加了热自动重载功能 (2).技术文章 1.用 React Native 设计的第一个 iOS 应用 我们想为用户设计一款移动端的应 ...

  3. React Native开发技术周报1

    (一).资讯 1.React Native 0.21版本发布,最新版本功能特点,修复的Bug可以看一下已翻译 重要:如果升级 Android 项目到这个版本一定要读! 我们简化了 Android 应用 ...

  4. DECO 一个REACT NAtive 开发IDE工具

    DECO 一个REACT NAtive 开发IDE工具. 目前只支持 OS,NO WINDOWS https://www.decosoftware.com/ 一个方便的快速 ERXPRESS 教程:h ...

  5. React Native 开发之 (02) 用Sublime 3作为React Native的开发IDE

    Sublime Text是一个代码编辑器.也是HTML和散文先进的文本编辑器.漂亮的用户界面和非凡的功能,例如:迷你地图,多选择Python插件,代码段等等.完全可自定义键绑定,菜单和工具栏等等.漂亮 ...

  6. React Native 开发笔记

    ReactNativeDemo 学习ReactNative开发,搭建ReactNative第一个项目 React Native 开发笔记 1.安装Homebrew $ /usr/bin/ruby -e ...

  7. 【转】【React Native开发】

    [React Native开发]React Native控件之ListView组件讲解以及最齐全实例(19)  [React Native开发]React Native控件之Touchable*系列组 ...

  8. React Native开发的通讯录应用

    React Native开发的通讯录应用(使用JavaScript开发原生iOS应用,vczero) 0.前言: 项目地址:https://github.com/vczero/React-Native ...

  9. iOS程序员的React Native开发工具集

    本文整理了React Native iOS开发过程中有用的工具.服务.测试.库以及网站等. 工具 你可以选择不同的开发环境:DECO.EXPO或者你可以使用Nuclide+Atom,目前我使用EXPO ...

  10. React-Native(二):React Native开发工具vs code配置

    从网上翻阅了一些开发react-native的开发工具时,发现其实可选的工具还是比较多的Sublime Text,WebStrom,Atom+Nuclide,vs code 等.因为我用.net生态环 ...

随机推荐

  1. 在 Visual Studio 上体验腾讯云 AI 代码助手

    ​本文以以 Visual Studio 2022 为例. 第一步 安装[腾讯云 AI 代码助手] 打开以 Visual Studio 2022,依次点击工具栏中的-** 扩展 - ** 管理扩展 ,在 ...

  2. netcore后台服务慎用BackgroundService

    在 .NET Core 开发中,BackgroundService 是一个非常方便的后台任务运行方式,但它并不适用于所有场景. BackgroundService 一时爽,并发火葬场. Backgro ...

  3. 删除空白行,报错 raise KeyError(list(np.compress(check, subset))) KeyError: ['姓名']

    之前这段程序跑完后没报错,经调试发现到这一句报错 > df.dropna(subset=['姓名'],inplace=True) 意思是删除'姓名'列 含有'NAN'的行 思考第一步:应该是 d ...

  4. ascci 码表

  5. (C++实现)2-NAF

    (C++实现)2-NAF 前言 ‍ 任何一个非负整数,都有一个唯一的 NAF (Non-adjacent form) 表示. 因着课程的缘由,我不得不研究一下 NAF 是怎么实现的,也是现学现用. ‍ ...

  6. go declared and not used

    Go语言在代码规范中定义未使用的变量会报"declared and not used"错误 package main import "fmt" func mai ...

  7. Nginx配置跨域,覆盖后端服务跨域配置

    本篇文章主要介绍了,如何通过Nginx配置跨域,并覆盖后端服务跨域配置. 先看下后端代码跨域配置: 主要的目标是:不修改后端跨域配置代码,来实现Nginx跨域指定域名. @Bean public Co ...

  8. linux命令提示符高亮

    说明 \033 或 \e :两者是等价的,表示转义字符(ASCII escape character),即键盘左上角的ESC键.033是ESC的八进制ASCII码.注意,在"老式" ...

  9. AOT编译Avalonia应用:StarBlog Publisher项目实践与挑战

    前言 最近我使用 Avalonia 开发了一个文章发布工具,StarBlog Publisher. Avalonia 是一个跨平台的 UI 框架,它可以在 Windows.Linux 和 macOS ...

  10. 在Linux终端管理你的密码!

    大家好,我是良许. 现在是互联网时代,我们每天都要跟各种 APP .网站打交道,而这些东西基本上都需要注册才可以使用. 但是账号一多,我们自己都经常记不清对应的密码了.有些小伙伴就一把梭,所有的账号密 ...