@leir0ng/uniapp-ble-sdk
v1.0.4
Published
A comprehensive BLE (Bluetooth Low Energy) SDK for uniapp with connection management, device discovery, and data handling
Downloads
9
Maintainers
Readme
uniapp-ble-sdk
一个功能完整的 UniApp 蓝牙低功耗 (BLE) SDK,提供设备搜索、连接管理、数据传输等完整功能。 如果你想用测试可以参考https://gitee.com/lei_rong/uniapp-ble-sdk-test-v这里是uniapp测试工程[直接下载运行就行]
特性
- 🔄 自动重连: 支持连接断开后自动重连
- 🔍 设备搜索: 支持过滤条件的设备搜索
- 📡 连接管理: 完整的连接状态管理和监听
- 📊 数据传输: 支持特征值读写和通知
- 🛡️ 错误处理: 完善的错误处理和事件回调
- 📱 跨平台: 支持 App、微信小程序等平台
- 🎯 TypeScript: 完整的 TypeScript 支持
安装
npm install uniapp-ble-sdk快速开始
基础使用
import { BLEManager, BLEEventType, ConnectionState } from 'uniapp-ble-sdk';
// 创建BLE管理器实例
const bleManager = new BLEManager({
autoReconnect: true,
reconnectInterval: 3000,
maxReconnectAttempts: 5
});
// 初始化
await bleManager.initialize();
// 监听事件
bleManager.on(BLEEventType.DEVICE_FOUND, (device) => {
console.log('发现设备:', device);
});
bleManager.on(BLEEventType.CONNECTION_STATE_CHANGE, (event) => {
console.log('连接状态变化:', event);
});
// 开始搜索设备
await bleManager.startDeviceDiscovery({
nameKeyword: 'MyDevice',
minRSSI: -80
});
// 连接设备
await bleManager.connect('device-id');
// 获取服务和特征值
const services = await bleManager.getDeviceServices();
const characteristics = await bleManager.getDeviceCharacteristics(serviceId);
// 启用通知
await bleManager.notifyCharacteristicValueChange(serviceId, characteristicId);
// 监听数据
bleManager.on(BLEEventType.CHARACTERISTIC_VALUE_CHANGE, (data) => {
console.log('收到数据:', data);
});
// 写入数据
const buffer = new ArrayBuffer(4);
await bleManager.writeCharacteristicValue(serviceId, characteristicId, buffer);
// 断开连接
await bleManager.disconnect();
// 销毁管理器
await bleManager.destroy();API 文档
BLEManager
主要的 BLE 管理类。
构造函数
constructor(options?: BLEOptions)参数:
options- 可选配置项
interface BLEOptions {
allowDuplicatesKey?: boolean; // 是否允许重复上报同一设备,默认 false
interval?: number; // 上报设备间隔(ms),默认 0
autoReconnect?: boolean; // 是否启用自动重连,默认 true
reconnectInterval?: number; // 重连间隔(ms),默认 3000
maxReconnectAttempts?: number; // 最大重连次数,默认 5
connectionTimeout?: number; // 连接超时时间(ms),默认 10000
}方法
initialize(): Promise
初始化蓝牙适配器。
await bleManager.initialize();destroy(): Promise
销毁管理器,关闭所有连接和监听。
await bleManager.destroy();getAdapterState(): Promise
获取蓝牙适配器状态。
const state = await bleManager.getAdapterState();
console.log('蓝牙可用:', state.available);
console.log('正在搜索:', state.discovering);startDeviceDiscovery(filter?: DeviceFilter): Promise
开始搜索蓝牙设备。
// 搜索所有设备
await bleManager.startDeviceDiscovery();
// 使用过滤器搜索
await bleManager.startDeviceDiscovery({
nameKeyword: 'sensor',
minRSSI: -70,
services: ['180F'] // 电池服务
});stopDeviceDiscovery(): Promise
停止搜索蓝牙设备。
await bleManager.stopDeviceDiscovery();getDiscoveredDevices(): BLEDevice[]
获取已发现的设备列表。
const devices = bleManager.getDiscoveredDevices();connect(deviceId: string): Promise
连接到指定设备。
await bleManager.connect('device-id-123');disconnect(): Promise
断开当前连接。
await bleManager.disconnect();getDeviceServices(deviceId?: string): Promise<BLEService[]>
获取设备服务列表。
const services = await bleManager.getDeviceServices();getDeviceCharacteristics(serviceId: string, deviceId?: string): Promise<BLECharacteristic[]>
获取设备特征值列表。
const characteristics = await bleManager.getDeviceCharacteristics('180F');getDeviceRSSI(deviceId?: string): Promise
获取设备信号强度。
const rssi = await bleManager.getDeviceRSSI();notifyCharacteristicValueChange(serviceId: string, characteristicId: string, state?: boolean, deviceId?: string): Promise
启用或禁用特征值变化通知。
// 启用通知
await bleManager.notifyCharacteristicValueChange(serviceId, characteristicId, true);
// 禁用通知
await bleManager.notifyCharacteristicValueChange(serviceId, characteristicId, false);readCharacteristicValue(serviceId: string, characteristicId: string, deviceId?: string): Promise
读取特征值。
const data = await bleManager.readCharacteristicValue(serviceId, characteristicId);writeCharacteristicValue(serviceId: string, characteristicId: string, value: ArrayBuffer, writeType?: WriteType, deviceId?: string): Promise
写入特征值。
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, 1234, true);
await bleManager.writeCharacteristicValue(
serviceId,
characteristicId,
buffer,
WriteType.WRITE
);setMTU(mtu: number, deviceId?: string): Promise
设置最大传输单元 (22-512)。
await bleManager.setMTU(247);getConnectionState(): ConnectionState
获取当前连接状态。
const state = bleManager.getConnectionState();getConnectedDevice(): BLEDevice | null
获取当前连接的设备信息。
const device = bleManager.getConnectedDevice();事件监听
on(event: string, callback: EventCallback): void
添加事件监听器。
bleManager.on(BLEEventType.DEVICE_FOUND, (device) => {
console.log('发现设备:', device);
});off(event: string, callback?: EventCallback): void
移除事件监听器。
bleManager.off(BLEEventType.DEVICE_FOUND, callback);
// 或移除所有监听器
bleManager.off(BLEEventType.DEVICE_FOUND);事件类型
enum BLEEventType {
ADAPTER_STATE_CHANGE = 'adapterStateChange', // 适配器状态变化
DEVICE_FOUND = 'deviceFound', // 发现新设备
CONNECTION_STATE_CHANGE = 'connectionStateChange', // 连接状态变化
CHARACTERISTIC_VALUE_CHANGE = 'characteristicValueChange', // 特征值变化
ERROR = 'error' // 错误事件
}连接状态
enum ConnectionState {
DISCONNECTED = 'disconnected', // 未连接
CONNECTING = 'connecting', // 连接中
CONNECTED = 'connected', // 已连接
DISCONNECTING = 'disconnecting' // 断开连接中
}写入类型
enum WriteType {
WRITE = 'write', // 需要回复
WRITE_NO_RESPONSE = 'writeNoResponse' // 不需要回复
}完整示例
Vue 3 组件示例
<template>
<view class="ble-demo">
<button @click="initBLE">初始化蓝牙</button>
<button @click="startScan" :disabled="!isInitialized">开始扫描</button>
<button @click="stopScan">停止扫描</button>
<view class="device-list">
<view
v-for="device in devices"
:key="device.deviceId"
class="device-item"
@click="connectDevice(device.deviceId)"
>
<text>{{ device.name || device.localName || '未知设备' }}</text>
<text>{{ device.RSSI }}dBm</text>
</view>
</view>
<view v-if="connectedDevice" class="connected-info">
<text>已连接: {{ connectedDevice.name }}</text>
<button @click="sendData">发送数据</button>
<button @click="disconnect">断开连接</button>
</view>
<view class="logs">
<text v-for="log in logs" :key="log.id">{{ log.message }}</text>
</view>
</view>
</template>
<script setup lang="ts">
import { ref, onUnmounted } from 'vue';
import { BLEManager, BLEEventType, ConnectionState, type BLEDevice } from 'uniapp-ble-sdk';
const bleManager = new BLEManager({
autoReconnect: true,
reconnectInterval: 3000,
maxReconnectAttempts: 3
});
const isInitialized = ref(false);
const devices = ref<BLEDevice[]>([]);
const connectedDevice = ref<BLEDevice | null>(null);
const logs = ref<Array<{ id: number, message: string }>>([]);
let logId = 0;
// 添加日志
const addLog = (message: string) => {
logs.value.push({
id: logId++,
message: `${new Date().toLocaleTimeString()}: ${message}`
});
if (logs.value.length > 100) {
logs.value.shift();
}
};
// 初始化蓝牙
const initBLE = async () => {
try {
await bleManager.initialize();
isInitialized.value = true;
addLog('蓝牙初始化成功');
// 设置事件监听
setupEventListeners();
} catch (error) {
addLog(`蓝牙初始化失败: ${error.message}`);
}
};
// 设置事件监听
const setupEventListeners = () => {
bleManager.on(BLEEventType.DEVICE_FOUND, (device: BLEDevice) => {
const existingIndex = devices.value.findIndex(d => d.deviceId === device.deviceId);
if (existingIndex >= 0) {
devices.value[existingIndex] = device;
} else {
devices.value.push(device);
}
addLog(`发现设备: ${device.name || device.localName || device.deviceId}`);
});
bleManager.on(BLEEventType.CONNECTION_STATE_CHANGE, (event) => {
addLog(`连接状态: ${event.deviceId} - ${event.state}`);
if (event.state === ConnectionState.CONNECTED) {
connectedDevice.value = bleManager.getConnectedDevice();
} else if (event.state === ConnectionState.DISCONNECTED) {
connectedDevice.value = null;
}
});
bleManager.on(BLEEventType.CHARACTERISTIC_VALUE_CHANGE, (data) => {
const view = new DataView(data.value);
addLog(`收到数据: ${Array.from(new Uint8Array(data.value)).map(b => b.toString(16).padStart(2, '0')).join(' ')}`);
});
bleManager.on(BLEEventType.ERROR, (error) => {
addLog(`错误: ${error.errMsg}`);
});
};
// 开始扫描
const startScan = async () => {
try {
devices.value = [];
await bleManager.startDeviceDiscovery({
minRSSI: -80
});
addLog('开始扫描设备');
} catch (error) {
addLog(`开始扫描失败: ${error.message}`);
}
};
// 停止扫描
const stopScan = async () => {
try {
await bleManager.stopDeviceDiscovery();
addLog('停止扫描');
} catch (error) {
addLog(`停止扫描失败: ${error.message}`);
}
};
// 连接设备
const connectDevice = async (deviceId: string) => {
try {
await bleManager.connect(deviceId);
addLog(`连接设备: ${deviceId}`);
// 获取服务和特征值
const services = await bleManager.getDeviceServices();
addLog(`发现 ${services.length} 个服务`);
// 这里可以根据具体需求处理服务和特征值
// 例如启用某个特征值的通知
if (services.length > 0) {
const characteristics = await bleManager.getDeviceCharacteristics(services[0].uuid);
addLog(`服务 ${services[0].uuid} 有 ${characteristics.length} 个特征值`);
// 查找可通知的特征值
const notifyChar = characteristics.find(c => c.properties.notify);
if (notifyChar) {
await bleManager.notifyCharacteristicValueChange(services[0].uuid, notifyChar.uuid);
addLog(`启用特征值通知: ${notifyChar.uuid}`);
}
}
} catch (error) {
addLog(`连接失败: ${error.message}`);
}
};
// 发送数据
const sendData = async () => {
try {
const device = bleManager.getConnectedDevice();
if (!device) return;
const services = await bleManager.getDeviceServices();
if (services.length === 0) return;
const characteristics = await bleManager.getDeviceCharacteristics(services[0].uuid);
const writeChar = characteristics.find(c => c.properties.write || c.properties.writeNoResponse);
if (writeChar) {
const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
view.setUint32(0, Date.now() % 10000, true);
await bleManager.writeCharacteristicValue(services[0].uuid, writeChar.uuid, buffer);
addLog('数据发送成功');
} else {
addLog('未找到可写特征值');
}
} catch (error) {
addLog(`发送数据失败: ${error.message}`);
}
};
// 断开连接
const disconnect = async () => {
try {
await bleManager.disconnect();
addLog('主动断开连接');
} catch (error) {
addLog(`断开连接失败: ${error.message}`);
}
};
// 组件销毁时清理
onUnmounted(async () => {
await bleManager.destroy();
});
</script>
<style scoped>
.ble-demo {
padding: 20px;
}
.device-list {
margin: 20px 0;
}
.device-item {
display: flex;
justify-content: space-between;
padding: 10px;
border: 1px solid #eee;
margin-bottom: 5px;
border-radius: 5px;
}
.connected-info {
background-color: #e8f5e8;
padding: 10px;
border-radius: 5px;
margin: 10px 0;
}
.logs {
max-height: 300px;
overflow-y: auto;
background-color: #f5f5f5;
padding: 10px;
border-radius: 5px;
font-family: monospace;
font-size: 12px;
}
</style>注意事项
- 权限配置: 确保在
manifest.json中配置了蓝牙权限:
{
"mp-weixin": {
"permission": {
"scope.bluetooth": {
"desc": "用于连接蓝牙设备"
}
}
},
"app-plus": {
"modules": {
"Bluetooth": {}
}
}
}平台差异: 不同平台对BLE支持可能有差异,建议在目标平台上充分测试。
连接管理: 建议在应用退出或页面销毁时主动断开连接和销毁管理器。
错误处理: 蓝牙操作可能因为各种原因失败,建议完善错误处理逻辑。
性能优化: 大量数据传输时注意控制频率,避免造成性能问题。
许可证
MIT License
贡献
欢迎提交 Issue 和 Pull Request!
更新日志
1.0.0
- 初始版本发布
- 支持基础的BLE功能
- 自动重连机制
- 完整的事件系统
- TypeScript 支持
