React-Native开发鸿蒙NEXT-蓝牙信标读取
.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-蓝牙信标读取的更多相关文章
- React Native开发入门
目录: 一.前言 二.什么是React Native 三.开发环境搭建 四.预备知识 五.最简单的React Native小程序 六.总结 七.参考资料 一.前言 虽然只是简单的了解了一下Reac ...
- React Native开发技术周报2
(1).资讯 1.React Native 0.22_rc版本发布 添加了热自动重载功能 (2).技术文章 1.用 React Native 设计的第一个 iOS 应用 我们想为用户设计一款移动端的应 ...
- React Native开发技术周报1
(一).资讯 1.React Native 0.21版本发布,最新版本功能特点,修复的Bug可以看一下已翻译 重要:如果升级 Android 项目到这个版本一定要读! 我们简化了 Android 应用 ...
- DECO 一个REACT NAtive 开发IDE工具
DECO 一个REACT NAtive 开发IDE工具. 目前只支持 OS,NO WINDOWS https://www.decosoftware.com/ 一个方便的快速 ERXPRESS 教程:h ...
- React Native 开发之 (02) 用Sublime 3作为React Native的开发IDE
Sublime Text是一个代码编辑器.也是HTML和散文先进的文本编辑器.漂亮的用户界面和非凡的功能,例如:迷你地图,多选择Python插件,代码段等等.完全可自定义键绑定,菜单和工具栏等等.漂亮 ...
- React Native 开发笔记
ReactNativeDemo 学习ReactNative开发,搭建ReactNative第一个项目 React Native 开发笔记 1.安装Homebrew $ /usr/bin/ruby -e ...
- 【转】【React Native开发】
[React Native开发]React Native控件之ListView组件讲解以及最齐全实例(19) [React Native开发]React Native控件之Touchable*系列组 ...
- React Native开发的通讯录应用
React Native开发的通讯录应用(使用JavaScript开发原生iOS应用,vczero) 0.前言: 项目地址:https://github.com/vczero/React-Native ...
- iOS程序员的React Native开发工具集
本文整理了React Native iOS开发过程中有用的工具.服务.测试.库以及网站等. 工具 你可以选择不同的开发环境:DECO.EXPO或者你可以使用Nuclide+Atom,目前我使用EXPO ...
- React-Native(二):React Native开发工具vs code配置
从网上翻阅了一些开发react-native的开发工具时,发现其实可选的工具还是比较多的Sublime Text,WebStrom,Atom+Nuclide,vs code 等.因为我用.net生态环 ...
随机推荐
- 机器学习 | 强化学习(5) | 价值函数拟合(Value Function Approximation)
价值函数拟合(Value Function Approximation) 导论(Introduction) 目前的价值函数都是基于打表法(lookup table)进行穷举 对于所有状态\(s\)都有 ...
- 面试题30. 包含min函数的栈
地址:https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/ <?php /** 定义栈的数据结构,请在该类型中实现一 ...
- python以及java环境搭建+解决不同版本环境共存问题
1.搭建python环境 1.安装python3.9.7,选择自定义安装.将文件添加至环境路径,然后选择下一步. 2.默认.然后选择下一步. 3.选择适用于所有使用者,选择自己想要存放的路径,然后选择 ...
- AI与.NET技术实操系列(八):使用Catalyst进行自然语言处理
引言 自然语言处理(Natural Language Processing, NLP)是人工智能领域中最具活力和潜力的分支之一.从智能客服到机器翻译,再到语音识别,NLP技术正以其强大的功能改变着我们 ...
- IvorySQL 4.4 发布
IvorySQL 4.4 已于 2025 年 3 月 10 日正式发布.新版本全面支持 PostgreSQL 17.4,新增多项新功能,并修复了已知问题. 增强功能 PostgreSQL 17.3 增 ...
- 出现TypeError: float() argument must be a string or a number, not _NoValueType(机器学习 Win11)
博客地址:https://www.cnblogs.com/zylyehuo/ 如果出现以下报错 则说明是torch.numpy等库的版本不匹配 可以去以下网站寻找匹配的版本 https://mirro ...
- BUUCTF---BabyRSA(简单求解n)
题目 p+q : 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e ...
- 区块链特辑——solidity语言基础(一)
Solidity语法基础学习 一.智能合约的结构: 首先以上是智能合约的结构,包含版权宣告.编译指示.Using for 宣告.错误定义.输入.列举与枚举.常数.合约.函数.注释.第一个注释不同于其他 ...
- PHP文件上传封装
class FileUploader { private $targetDirectory; private $allowedExtensions; private $maxFileSize; pub ...
- 多态的前提--java进阶day02
1.多态的前提条件 第一点和第二点都很好理解,第三点父类引用指向子类对象是什么意思?以下图进行讲解 我们以前的写法,如下图,叫做子类引用指向子类 那父类引用呢?就是把左边换成父类Animal即可 因为 ...