- 版本:3.1.19
- GitHub: https://github.com/nativescript-community/ble
- NPM: https://npmjs.net.cn/package/%40nativescript-community%2Fble
- 下载
- 昨日:38
- 上周:172
- 上个月:741
@nativescript-community/ble
连接并交互蓝牙低功耗外围设备。
目录
安装
从项目的根目录运行以下命令
ns plugin add @nativescript-community/ble
API
想快速入门?查看演示应用!否则,根据需要混合使用这些函数
先决条件
发现
连接
交互
调试
isBluetoothEnabled
报告蓝牙是否启用。
// require the plugin
import { Bluetooth } from '@nativescript-community/ble';
var bluetooth = new Bluetooth();
bluetooth.isBluetoothEnabled().then(
function(enabled) {
console.log("Enabled? " + enabled);
}
);
权限 (Android)
在 Android 6 及以上版本和小于 12 的版本中,您需要在 API 级别 23+ 的目标上请求权限,以便能够与蓝牙外围设备交互(当应用处于后台时)。您需要 BLUETOOTH
和 ACCESS_FINE_LOCATION
。您应该在这里阅读文档https://android-docs.cn/develop/connectivity/bluetooth/bt-permissions
在 Android 12 及以上版本中,您需要新的权限。您应该在这里阅读文档https://android-docs.cn/develop/connectivity/bluetooth/bt-permissions 注意,对于 BLUETOOTH
和 BLUETOOTH_ADMIN
,您不需要运行时权限;将这些添加到 AndroidManifest.xml
即可。
请注意,当以下情况时,hasLocationPermission
将返回 true:
- 您在 iOS 上运行此代码,或
- 您的目标是 API 级别低于 23,或
- 您正在使用运行 Android 6 以下版本的设备,或
- 您已授予权限。
bluetooth.hasLocationPermission().then(
function(granted) {
// if this is 'false' you probably want to call 'requestLocationPermission' now
console.log("Has Location Permission? " + granted);
}
);
requestLocationPermission
从插件版本 1.2.0 开始,startScanning
函数将内部处理此功能,因此不再强制在您的代码中添加权限检查。
// if no permission was granted previously this will open a user consent screen
bluetooth.requestLocationPermission().then(
function(granted) {
console.log("Location permission requested, user granted? " + granted);
}
);
enable (仅限 Android)
在 iOS 上将拒绝承诺
// This turns bluetooth on, will return false if the user denied the request.
bluetooth.enable().then(
function(enabled) {
// use Bluetooth features if enabled is true
}
);
startScanning
一些可选参数需要一些解释
seconds
扫描外围设备会快速耗尽电量,因此您最好不要扫描超过必要的范围。如果外围设备在范围内且未参与其他连接,通常在不到一秒钟的时间内就会出现。如果您不传入秒数,则需要手动调用 stopScanning
。
avoidDuplicates
如果不想在 "onDiscovered" 回调中报告具有相同 serviceUUID 的重复设备,请将此设置为 true。如果为 true,则只会报告首次发现的具有相同 serviceUUID 的外围设备。
skipPermissionCheck
如果不想让插件检查(并请求)所需的蓝牙权限,请将此设置为 true。这对于在非 UI 线程(例如 Worker)上运行此函数特别有用。仅适用于 Android。
filters
扫描所有可用的蓝牙外围设备并报告它们提供的所有服务是不高效的。此外,在 Android 中,如果我们不使用过滤器,则必须具有位置权限并启用 GPS。
如果您只想找到心率外设,例如,可以传入服务UUID '180d'
,如下所示:filters: [{serviceUUID:'180d'}]。如果您添加了2个或更多(以逗号分隔)服务,则只有支持所有这些服务的设备才会匹配。
请注意,UUID始终是字符串;不要传入整数。
onDiscovered
在扫描过程中,插件将立即报告唯一发现的设备。
此函数将接收一个表示外围设备的对象,该对象包含以下属性(和类型)
UUID:字符串
name:字符串
RSSI:数字
(相对信号强度,可用于距离测量)services?:
(可选 - 在连接到外围设备后设置)manufacturerId?:数字
(可选)advertismentData?:{ localName?:字符串 manufacturerData?:ArrayBuffer;serviceUUIDs?:字符串[];txPowerLevel?:数字,flags?:数字 }
(可选)
bluetooth.startScanning({
filters: [{serviceUUID:'180d'}],
seconds: 4,
onDiscovered: function (peripheral) {
console.log("Periperhal found with UUID: " + peripheral.UUID);
}
}).then(function() {
console.log("scanning complete");
}, function (err) {
console.log("error while scanning: " + err);
});
stopScanning
在任何时候进行扫描期间,无论您是否传入秒数,都可以通过调用此函数停止扫描。
例如,当您在startScanning
的onDiscovered
回调中找到的设备与您的标准匹配时,您可以停止扫描。
bluetooth.stopScanning().then(function() {
console.log("scanning stopped");
});
connect
传入您想要连接的外设的UUID,一旦建立连接,onConnected
回调函数将被调用。此回调将接收与之前相同的设备对象,但现在它还包含一个services
属性。返回的设备对象示例可能如下所示
peripheral: {
UUID: '3424-542-4534-53454',
name: 'Polar P7 Heartrate Monitor',
RSSI: '-57',
services: [{
UUID: '180d',
name: 'Heartrate service',
characteristics: [{
UUID: '34534-54353-234324-343',
name: 'Heartrate characteristic',
properties: {
read: true,
write: false,
writeWithoutResponse: false,
notify: true
}
}]
}]
}
以下是connect
函数的作用,以及一个简单的onConnected
实现,它将整个设备对象打印到控制台
bluetooth.connect({
UUID: '04343-23445-45243-423434',
onConnected: function (peripheral) {
console.log("Periperhal connected with UUID: " + peripheral.UUID);
// the peripheral object now has a list of available services:
peripheral.services.forEach(function(service) {
console.log("service found: " + JSON.stringify(service));
});
},
onDisconnected: function (peripheral) {
console.log("Periperhal disconnected with UUID: " + peripheral.UUID);
}
});
请注意,还有onDisconnected
函数:在此事件之后尝试与外围设备交互可能会使您的应用程序崩溃。
disconnect
一旦完成与外围设备的交互,请作为好公民断开连接。这将允许其他应用程序建立连接。
bluetooth.disconnect({
UUID: '34234-5453-4453-54545'
}).then(function() {
console.log("disconnected successfully");
}, function (err) {
// in this case you're probably best off treating this as a disconnected peripheral though
console.log("disconnection error: " + err);
});
read
如果外围设备有一个服务,其中properties.read
为true
,则可以调用read
函数以检索特性的当前状态(值)。
该承诺将接收一个如下的对象
{
value: <ArrayBuffer>, // an ArrayBuffer which you can use to decode (see example below)
ios: <72>, // the platform-specific binary value of the characteristic: NSData (iOS), byte[] (Android)
android: <72>, // the platform-specific binary value of the characteristic: NSData (iOS), byte[] (Android)
characteristicUUID: '434234-234234-234234-434'
}
有了这些知识,让我们调用read
函数
bluetooth.read({
peripheralUUID: '34234-5453-4453-54545',
serviceUUID: '180d',
characteristicUUID: '3434-45234-34324-2343'
}).then(function(result) {
// fi. a heartrate monitor value (Uint8) can be retrieved like this:
var data = new Uint8Array(result.value);
console.log("Your heartrate is: " + data[1] + " bpm");
}, function (err) {
console.log("read error: " + err);
});
write
如果外围设备有一个服务,其中特性properties.write
为true
,则可以调用write
函数来更新特性的当前状态(值)。
值可以是字符串或任何数组类型值。如果您传递字符串,则应传递编码。
bluetooth.write({
peripheralUUID: '34134-5453-4453-54545',
serviceUUID: '180e',
characteristicUUID: '3424-45234-34324-2343',
value: [1]
}).then(function(result) {
console.log("value written");
}, function (err) {
console.log("write error: " + err);
});
writeWithoutResponse
与write
相同的API,只是在承诺调用时,值尚未写入;它只是请求写入,并且在写入完成时不会收到响应。
startNotifying
如果外围设备有一个服务,其中特性properties.notify
为true
,则可以调用startNotifying
函数以检索特性的值更改。
用法与read
非常相似,但结果不会发送到承诺,而是发送到您传入的onNotify
回调函数。这是因为可以接收多个通知,而承诺只能解决一次。发送到onNotify
的对象的值与您在read
的承诺中获得的值相同。
bluetooth.startNotifying({
peripheralUUID: '34234-5453-4453-54545',
serviceUUID: '180d',
characteristicUUID: '3434-45234-34324-2343',
onNotify: function (result) {
// see the read example for how to decode ArrayBuffers
console.log("read: " + JSON.stringify(result));
}
}).then(function() {
console.log("subscribed for notifications");
});
stopNotifying
足够了。当您不再对外围设备发送的值感兴趣时,这样做
bluetooth.stopNotifying({
peripheralUUID: '34234-5453-4453-54545',
serviceUUID: '180d',
characteristicUUID: '3434-45234-34324-2343'
}).then(function() {
console.log("unsubscribed for notifications");
}, function (err) {
console.log("unsubscribe error: " + err);
});
示例
- 基础
- 一个基础示例显示即使是在模态中,覆盖N个手势也是有效的
演示和开发
仓库设置
该仓库使用子模块。如果您没有使用 --recursive
进行克隆,则需要调用
git submodule update --init
用于安装和链接依赖项的包管理器必须是pnpm
或yarn
。不兼容npm
。
开发和测试:如果您使用 yarn
,则运行 yarn
;如果您使用 pnpm
,则运行 pnpm i
交互式菜单
要启动交互式菜单,运行 npm start
(或 yarn start
或 pnpm start
)。这将列出所有常用脚本。
构建
npm run build.all
警告:似乎 yarn build.all
不会总是工作(在 node_modules/.bin
中找不到二进制文件),这就是为什么文档明确使用 npm run
演示
npm run demo.[ng|react|svelte|vue].[ios|android]
npm run demo.svelte.ios # Example
演示设置在某种程度上有些特殊,如果您想修改或添加演示,您不需要直接在 demo-[ng|react|svelte|vue]
中工作。相反,您应在 demo-snippets/[ng|react|svelte|vue]
中工作。您可以从每个样式的 install.ts
开始,了解如何注册新的演示。
贡献
更新仓库
您可以非常容易地更新仓库文件。
首先更新子模块。
npm run update
然后提交更改,然后更新公共文件。
npm run sync
然后您可以运行 yarn|pnpm
,如果有任何更改,请提交更改的文件。
更新 README
npm run readme
更新文档
npm run doc
发布
发布完全由 lerna
处理(您可以通过添加 -- --bump major
强制进行主要版本发布)只需运行即可。
npm run publish
修改子模块
仓库使用 https:// 来处理子模块,这意味着您无法直接将内容推送到子模块。一个简单的解决方案是修改 ~/.gitconfig
并添加以下内容:
[url "ssh://[email protected]/"]
pushInsteadOf = https://github.com/
问题
如果您有任何问题/问题/评论,请随时创建一个问题或在 NativeScript 社区 Discord 中开始对话。