如果要使用的话建议用uts改写连接蓝牙是耗时操作使用plus对象无法通过plus.android.importClass(java.lang.Thread)将耗时操作放入子线程会导致页面卡顿。以下uts代码由AI生成尚未自测仅供参考。html5plus版本(已自测过)//经典蓝牙服务的UUID const UUIDString 00001101-0000-1000-8000-00805F9B34FB; class Bluetooth { //蓝牙类的实例 instance; /**当前程序页面上下文 */ Activity; /**蓝牙适配器 */ Adapter; /**蓝牙建立的连接 */ BluetoothSocket; /**蓝牙适配器接收器 */ BluetoothReciever; /**蓝牙所需的权限 */ permissions []; /**搜索到蓝牙的回调 */ onBluetoothDeviceFoundCallBack () {}; /**蓝牙状态变更 */ onBluetoothConnectedChangeCallback () {}; /**蓝牙适配器状态变更 */ onBluetoothAdapterChangeCallback () {}; //初始化 constructor() { if (Bluetooth.instance) return Bluetooth.instance; Bluetooth.instance this; return Bluetooth.instance; } //初始化蓝牙适配器 init() { this.Activity plus.android.runtimeMainActivity(); const BluetoothAdapter plus.android.importClass(android.bluetooth.BluetoothAdapter); const BluetoothDevice plus.android.importClass(android.bluetooth.BluetoothDevice); const Intent plus.android.importClass(android.content.Intent); //初始化蓝牙适配器 this.Adapter BluetoothAdapter.getDefaultAdapter(); //校验是否存在蓝牙权限 if (!this.Adapter) return showToast({ position: top, message: 当前设备不支持蓝牙! }); //保存this指向 //如果适配器不可用跳往设置页 if (!this.Adapter.isEnabled) { //创建意图 const intent new Intent(this.Adapter.ACTION_REQUEST_ENABLE); //跳转至蓝牙设置 plus.android.invoke(this.Activity, startActivity, intent, 1, null); return; } const Manifest plus.android.importClass(android.Manifest); this.permissions [ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_ADVERTISE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN ]; //蓝牙开关变化常量 const STATE_CHANGED BluetoothAdapter.ACTION_STATE_CHANGED; //蓝牙连接常量 const ACTION_ACL_CONNECTED BluetoothDevice.ACTION_ACL_CONNECTED; //蓝牙断开连接常量 const ACTION_ACL_DISCONNECTED BluetoothDevice.ACTION_ACL_DISCONNECTED; //搜索到蓝牙常量 const ACTION_FOUND BluetoothDevice.ACTION_FOUND; //保存this指向 const that this; //接收广播(注意:这里广播的类需要加io.dcloud前缀不加会出现报错无法执行) this.BluetoothReciever plus.android.implements(io.dcloud.android.content.BroadcastReceiver, { //接收蓝牙发出的广播 onReceive: function (context, intent) { //获取广播意图 const action plus.android.invoke(intent, getAction); //获取蓝牙设备信息 const device plus.android.invoke(intent, getParcelableExtra, android.bluetooth.device.extra.DEVICE); //获取蓝牙设备名称 const deviceName device.getName(); if (!deviceName) return; //获取蓝牙设备id const deviceId device.getAddress(); switch (action) { //蓝牙开关变化 case STATE_CHANGED: //获取蓝牙广播状态 const EXTRA_STATE plus.android.getAttribute(new BluetoothAdapter(), EXTRA_STATE); //广播状态码 const code plus.android.invoke(intent, getIntExtra, EXTRA_STATE, -1); switch (code) { case BluetoothAdapter.STATE_OFF: that.onBluetoothAdapterChangeCallback({ state: false }); break; case BluetoothAdapter.STATE_ON: that.onBluetoothAdapterChangeCallback({ state: true }); break; } break; //蓝牙连接成功 case ACTION_ACL_CONNECTED: that.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: true }); break; //蓝牙断开连接成功 case ACTION_ACL_DISCONNECTED: //蓝牙断开则把建立的socket置空 that.BluetoothSocket null; that.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: false }); break; //搜索到蓝牙 case ACTION_FOUND: if (!deviceName) return; that.onBluetoothDeviceFoundCallBack({ name: deviceName, deviceId }); break; } } }); //创建意图过滤器添加需要监听的蓝牙广播动作 const IntentFilter plus.android.newObject(android.content.IntentFilter); // 监听蓝牙开关状态变化核心广播 plus.android.invoke(IntentFilter, addAction, STATE_CHANGED); // 监听蓝牙设备连接成功 plus.android.invoke(IntentFilter, addAction, ACTION_ACL_CONNECTED); // 监听蓝牙设备断开连接 plus.android.invoke(IntentFilter, addAction, ACTION_ACL_DISCONNECTED); // 监听搜索到的蓝牙 plus.android.invoke(IntentFilter, addAction, ACTION_ACL_DISCONNECTED); //搜索到蓝牙 plus.android.invoke(IntentFilter, addAction, ACTION_FOUND); //注册广播接收器 plus.android.invoke(this.Activity, registerReceiver, this.BluetoothReciever, IntentFilter); //蓝牙提示语 console.info(蓝牙广播接收器注册成功); } //获取已连接蓝牙列表 getBondedDevices() { return new Promise((resolve, reject) { //获取已配对列表 const devices this.Adapter.getBondedDevices(); const iterator plus.android.invoke(devices, iterator); plus.android.importClass(iterator); const list []; while (iterator.hasNext()) { const device iterator.next(); const name plus.android.invoke(device, getName); const deviceId plus.android.invoke(device, getAddress); list.push({ name, deviceId }); } resolve(list); }); } //搜索蓝牙 discoverDevices(callback) { plus.android.requestPermissions( this.permissions, ({ granted }) { console.log(请求权限, granted); this.onBluetoothDeviceFoundCallBack callback; //当前是否正在搜索 const isDiscovering plus.android.invoke(this.Adapter, isDiscovering); //如果正在搜索,先停止再重新搜索 if (isDiscovering) { this.stopDiscover(); } //开始搜索蓝牙 plus.android.invoke(this.Adapter, startDiscovery); //三秒后停止搜索 setTimeout(() { this.stopDiscover(); }, 3000); }, () {} ); } //蓝牙状态变更 onBluetoothConnectedChange(callback) { this.onBluetoothConnectedChangeCallback callback; } //蓝牙状态变更 onBluetoothAdapterChange(callback) { this.onBluetoothAdapterChangeCallback callback; } //停止搜索 stopDiscover() { if (!this.Adapter || !this.BluetoothReciever) return console.log({ message: 蓝牙适配器未开启! }); plus.android.invoke(this.Adapter, cancelDiscovery); } //连接蓝牙 connectDevice(id) { return new Promise((resolve, reject) { plus.android.requestPermissions( this.permissions, ({ granted }) { console.log(请求权限, granted); try { //停止扫描 const isDiscovering plus.android.invoke(this.Adapter, isDiscovering); //判断是否正在扫描附近的蓝牙 if (isDiscovering) { plus.android.invoke(this.Adapter, cancelDiscovery); } //如果已连接先关闭 if (this.BluetoothSocket) { plus.android.invoke(this.BluetoothSocket, close); this.BluetoothSocket null; } //蓝牙设备 if (!id) return reject({ message: 蓝牙参数错误! }); //获取远程蓝牙信号 const device plus.android.invoke(this.Adapter, getRemoteDevice, id); //筛选可用的设备UUID const UUID plus.android.importClass(java.util.UUID); const uuid UUID.fromString(UUIDString); this.BluetoothSocket device.createRfcommSocketToServiceRecord(uuid); plus.android.invoke(this.BluetoothSocket, connect); resolve(); } catch (error) { console.error(连接蓝牙出现了错误, error); this.BluetoothSocket null; reject({ code: -1, message: 连接超时或设备未开启! }); } }, (err) reject(err) ); }); } //断开蓝牙 disconnectDevice(id) { return new Promise((resolve, reject) { try { //获取当前连接的蓝牙 const device plus.android.invoke(this.Adapter, getRemoteDevice, id); const UUID plus.android.importClass(java.util.UUID); const uuid UUID.fromString(UUIDString); //获取蓝牙建立的连接 const socket plus.android.invoke(device, createInsecureRfcommSocketToServiceRecord, uuid); //当前蓝牙是否已连接 const isConnected plus.android.invoke(device, isConnected); //如果未连接直接阻断 if (!socket || !isConnected) return showToast({ position: top, message: 当前蓝牙未连接! }); //关闭输入流 const inputStream plus.android.invoke(socket, getInputStream); plus.android.invoke(inputStream, close); //关闭输出流 const outputStream plus.android.invoke(socket, getOutputStream); plus.android.invoke(outputStream, close); //断开建立的连接 plus.android.invoke(socket, close); resolve(); } catch (error) { reject(error); } }); } /** * 发送数据 * param {*} byte[] 二进制字节数组 * returns */ sendDataToBluetooth(bytes) { return new Promise(async (resolve, reject) { try { if (!this.BluetoothSocket) return showToast({ position: top, message: 连接已断开,请重新连接! }); //生成输出流; const outputStream plus.android.invoke(this.BluetoothSocket, getOutputStream); //字节长度 const byteLength bytes.byteLength; const blob new Int8Array(bytes); //当前字节索引 let currentSize 0; //切片大小 const chunkSize 2048; //子线程实现方法 while (currentSize byteLength) { const chunk blob.slice(currentSize, currentSize chunkSize); //发送数据 plus.android.invoke(outputStream, write, [...chunk]); //当前索引自增 currentSize chunkSize; } resolve(); } catch (error) { console.error(发送失败, error); reject(error); } }); } } /** * 创建蓝牙实例 * returns */ export const createBluetooth () { return new Bluetooth(); };页面中使用template div classpage van-button clickdiscover搜索蓝牙/van-button van-button clicksendData发送数据/van-button ul classcontainer li v-foritem in list :keyitem.deviceId clickconnect(item.deviceId) {{ item.name }} /li /ul /div /template script setup import { ref, onMounted } from vue; import { getBinary, getTextBinary, getQrCode } from /api/common; import { createBluetooth } from /system/bluetooth; const list ref([]); const bluetooth createBluetooth(); onMounted(() { bluetooth.init(); }); //搜索蓝牙 const discover () { bluetooth.discoverDevices((device) { const same list.value.find((el) el.deviceId device.deviceId); if (same) return; list.value.push(device); }); }; //连接蓝牙 const connect (id) { bluetooth.connectDevice(id); }; //发送数据 const sendData async () { const res await getBinary(); //请求打印数据 bluetooth.sendDataToBluetooth(res); }; bluetooth.onBluetoothConnectedChange((res) console.log(蓝牙连接状态变更了, res)); bluetooth.onBluetoothAdapterChange(({ state }) console.info(蓝牙开关变更了, state)); /script style scoped langscss .page { padding-top: 50px; display: flex; flex-direction: column; width: 100%; height: 100vh; overflow-y: scroll; .van-button { flex-shrink: 0; } .container { width: 100%; flex: 1; overflow-y: scroll; li { width: 100%; height: 40px; text-align: center; overflow: hidden; } } } /styleuts版Android(借助AI生成尚未自测仅作参考)import { BluetoothAdapter, BluetoothDevice, Intent, IntentFilter, BroadcastReceiver,Context,UUID,Manifest} from android; // 经典蓝牙服务UUID const UUIDString 00001101-0000-1000-8000-00805F9B34FB; export type BluetoothDeviceInfo { name: string, deviceId: string } export type BluetoothConnectStatus { name?: string, deviceId?: string, status: boolean } export type BluetoothAdapterStatus { state: boolean } // 安卓原生类导入 import { BluetoothAdapter, BluetoothDevice, Intent, IntentFilter, BroadcastReceiver, Context, UUID, Manifest } from android; export class Bluetooth { private static instance: Bluetooth | null null; private activity: Context; private adapter: BluetoothAdapter | null null; private socket: any null; private receiver: BroadcastReceiver | null null; private permissions: string[] []; public onBluetoothDeviceFoundCallBack: (device: BluetoothDeviceInfo) void () {}; public onBluetoothConnectedChangeCallback: (status: BluetoothConnectStatus) void () {}; public onBluetoothAdapterChangeCallback: (status: BluetoothAdapterStatus) void () {}; private constructor() { this.activity plus.android.runtimeMainActivity(); } public static getInstance(): Bluetooth { if (!Bluetooth.instance) { Bluetooth.instance new Bluetooth(); } return Bluetooth.instance; } private createReceiver(): BroadcastReceiver { const self this; // UTS 官方标准写法替代 plus.android.implements const receiver new BroadcastReceiver(); receiver.onReceive (context: Context, intent: Intent) { const action intent.getAction(); const device intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) as BluetoothDevice | null; if (!device) return; const deviceName device.getName() ?? ; const deviceId device.getAddress() ?? ; if (!deviceName) return; switch (action) { case BluetoothAdapter.ACTION_STATE_CHANGED: const state intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); if (state BluetoothAdapter.STATE_ON) { self.onBluetoothAdapterChangeCallback({ state: true }); } else if (state BluetoothAdapter.STATE_OFF) { self.onBluetoothAdapterChangeCallback({ state: false }); } break; case BluetoothDevice.ACTION_ACL_CONNECTED: self.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: true }); break; case BluetoothDevice.ACTION_ACL_DISCONNECTED: self.socket null; self.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: false }); break; case BluetoothDevice.ACTION_FOUND: self.onBluetoothDeviceFoundCallBack({ name: deviceName, deviceId }); break; } }; return receiver; } // 初始化 public init() { try { this.adapter BluetoothAdapter.getDefaultAdapter(); if (!this.adapter) { uni.showToast({ title: 设备不支持蓝牙, position: top }); return; } if (!this.adapter.isEnabled()) { const enableIntent new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); this.activity.startActivity(enableIntent); return; } // 权限 this.permissions [ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN ]; // 创建广播已修复 this.receiver this.createReceiver(); const filter new IntentFilter(); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); filter.addAction(BluetoothDevice.ACTION_FOUND); this.activity.registerReceiver(this.receiver, filter); console.log(✅ 蓝牙广播注册成功UTS 标准版); } catch (e) { console.error(初始化失败, e); } } // 获取已配对设备 public getBondedDevices(): PromiseBluetoothDeviceInfo[] { return new Promise(resolve { const list: BluetoothDeviceInfo[] []; const devices this.adapter?.getBondedDevices() ?? new Set(); for (const dev of devices) { list.push({ name: dev.getName() ?? , deviceId: dev.getAddress() ?? }); } resolve(list); }); } // 搜索设备 public discoverDevices(callback: (device: BluetoothDeviceInfo) void) { plus.android.requestPermissions(this.permissions, (res: any) { if (!res.granted) return; this.onBluetoothDeviceFoundCallBack callback; if (this.adapter?.isDiscovering()) { this.adapter.cancelDiscovery(); } this.adapter?.startDiscovery(); setTimeout(() this.stopDiscover(), 3000); }); } // 停止搜索 public stopDiscover() { this.adapter?.cancelDiscovery(); } // 连接设备 public connectDevice(deviceId: string): Promisevoid { return new Promise((resolve, reject) { try { if (!this.adapter) return reject(未初始化); if (this.adapter.isDiscovering()) { this.adapter.cancelDiscovery(); } if (this.socket) { this.socket.close(); this.socket null; } const device this.adapter.getRemoteDevice(deviceId); const uuid UUID.fromString(UUIDString); this.socket device.createRfcommSocketToServiceRecord(uuid); this.socket.connect(); resolve(); } catch (e) { this.socket null; reject(e); } }); } // 断开连接 public disconnectDevice(): Promisevoid { return new Promise(resolve { try { if (this.socket) { this.socket.close(); this.socket null; } resolve(); } catch { resolve(); } }); } // 发送数据 public sendDataToBluetooth(buffer: ArrayBuffer): Promisevoid { return new Promise((resolve, reject) { try { if (!this.socket) { uni.showToast({ title: 未连接, position: top }); return reject(未连接); } const stream this.socket.getOutputStream(); const bytes new Uint8Array(buffer); const chunk 2048; let pos 0; while (pos bytes.length) { const end Math.min(pos chunk, bytes.length); const slice bytes.slice(pos, end); stream.write(Array.from(slice)); pos end; } resolve(); } catch (e) { reject(e); } }); } public onBluetoothConnectedChange(callback: (status: BluetoothConnectStatus) void) { this.onBluetoothConnectedChangeCallback callback; } public onBluetoothAdapterChange(callback: (status: BluetoothAdapterStatus) void) { this.onBluetoothAdapterChangeCallback callback; } } export const createBluetooth () Bluetooth.getInstance();uts版本iOS版本(借助AI生成尚未自测,仅供参考)import Foundation import CoreBluetooth // 经典蓝牙 SPP UUIDiOS 上同样使用该 UUID 匹配 const UUIDString 00001101-0000-1000-8000-00805F9B34FB // 设备信息 export type BluetoothDeviceInfo { name: string deviceId: string } // 连接状态 export type BluetoothConnectStatus { name?: string deviceId?: string status: boolean } // 蓝牙开关状态 export type BluetoothAdapterStatus { state: boolean } /** * iOS 经典蓝牙SPP实现 * 对外 API 与 Android 版本完全一致 */ export class Bluetooth { private static instance: Bluetooth | null null // CoreBluetooth 核心 private centralManager: CBCentralManager! private connectedPeripheral: CBPeripheral? private writeCharacteristic: CBCharacteristic? // 发现/连接回调 public onBluetoothDeviceFoundCallBack: (device: BluetoothDeviceInfo) void () {} public onBluetoothConnectedChangeCallback: (status: BluetoothConnectStatus) void () {} public onBluetoothAdapterChangeCallback: (status: BluetoothAdapterStatus) void () {} // 搜索缓存避免重复回调 private discoveredIds: Setstring [] private constructor() { self.centralManager CBCentralManager( delegate: self, queue: DispatchQueue.global() ) } public static getInstance(): Bluetooth { if (Bluetooth.instance null) { Bluetooth.instance Bluetooth() } return Bluetooth.instance! } /** * 初始化蓝牙iOS 自动触发权限 */ public init(): void { // iOS 蓝牙状态由 CBCentralManagerDelegate 回调 console.log(iOS 蓝牙初始化完成) } /** * 获取已配对设备iOS 无法直接获取返回空数组 */ public getBondedDevices(): PromiseBluetoothDeviceInfo[] { return Promise.resolve([]) } /** * 搜索蓝牙设备 */ public discoverDevices(callback: (device: BluetoothDeviceInfo) void): void { self.onBluetoothDeviceFoundCallBack callback self.discoveredIds.removeAll() if self.centralManager.state ! .poweredOn { console.log(蓝牙未开启) return } // 停止之前扫描 self.centralManager.stopScan() // 开始扫描 SPP 设备 let sppUUID CBUUID(string: UUIDString) self.centralManager.scanForPeripherals( withServices: [sppUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: false] ) // 3 秒后停止 setTimeout(3000) { self.centralManager.stopScan() } } /** * 停止搜索 */ public stopDiscover(): void { self.centralManager.stopScan() } /** * 连接设备 */ public connectDevice(deviceId: string): Promisevoid { return Promise { resolve, reject in if deviceId.isEmpty { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 设备 ID 不能为空])) return } if self.centralManager.state ! .poweredOn { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 蓝牙未开启])) return } // 先停止扫描 self.centralManager.stopScan() // 找到对应外设需要先扫描过 guard let peripheral self.findPeripheral(withUUID: deviceId) else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 未找到该设备请先搜索])) return } self.centralManager.connect(peripheral, options: nil) // 超时 10 秒 setTimeout(10000) { if self.connectedPeripheral nil { self.centralManager.cancelPeripheralConnection(peripheral) reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 连接超时])) } } } } /** * 断开连接 */ public disconnectDevice(deviceId: string): Promisevoid { return Promise { resolve, reject in guard let peripheral self.connectedPeripheral else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 未连接设备])) return } self.centralManager.cancelPeripheralConnection(peripheral) resolve() } } /** * 发送二进制数据 */ public sendDataToBluetooth(_ buffer: ArrayBuffer): Promisevoid { return Promise { resolve, reject in guard let char self.writeCharacteristic else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 未找到可写特征])) return } guard let peripheral self.connectedPeripheral else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 设备未连接])) return } let data Data(bytes: buffer.bytes, count: buffer.byteLength) // iOS BLE 单次发送最大 2048与 Android 分片逻辑一致 let chunkSize 2048 var offset 0 while offset data.count { let end min(offset chunkSize, data.count) let chunk data[offset..end] peripheral.writeValue(chunk, for: char, type: .withoutResponse) offset end } resolve() } } // 监听连接状态 public onBluetoothConnectedChange(callback: (BluetoothConnectStatus) - Void) { self.onBluetoothConnectedChangeCallback callback } // 监听蓝牙开关 public onBluetoothAdapterChange(callback: (BluetoothAdapterStatus) - Void) { self.onBluetoothAdapterChangeCallback callback } // 根据 UUID 查找外设 private func findPeripheral(withUUID uuidString: String) - CBPeripheral? { for peripheral in self.centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: UUIDString)]) { if peripheral.identifier.uuidString uuidString { return peripheral } } return nil } } // MARK: - CBCentralManagerDelegate extension Bluetooth: CBCentralManagerDelegate { public func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: self.onBluetoothAdapterChangeCallback({ state: true }) case .poweredOff, .unauthorized, .unsupported, .unknown: self.onBluetoothAdapterChangeCallback({ state: false }) default: break } } public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { let deviceId peripheral.identifier.uuidString let name peripheral.name ?? 未知设备 if self.discoveredIds.contains(deviceId) { return } self.discoveredIds.insert(deviceId) self.onBluetoothDeviceFoundCallBack({ name: name, deviceId: deviceId }) } public func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { self.connectedPeripheral peripheral peripheral.delegate self peripheral.discoverServices([CBUUID(string: UUIDString)]) self.onBluetoothConnectedChangeCallback({ name: peripheral.name ?? 未知设备, deviceId: peripheral.identifier.uuidString, status: true }) } public func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { self.connectedPeripheral nil self.writeCharacteristic nil self.onBluetoothConnectedChangeCallback({ name: peripheral.name ?? 未知设备, deviceId: peripheral.identifier.uuidString, status: false }) } public func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { print(连接失败, error?.localizedDescription ?? ) } } // MARK: - CBPeripheralDelegate extension Bluetooth: CBPeripheralDelegate { public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { guard let services peripheral.services else { return } for service in services { peripheral.discoverCharacteristics(nil, for: service) } } public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { guard let chars service.characteristics else { return } for char in chars { // 找到可写特征 if char.properties.contains(.write) || char.properties.contains(.writeWithoutResponse) { self.writeCharacteristic char print(找到可写特征) } } } } // 对外兼容方法 export const createBluetooth (): Bluetooth { return Bluetooth.getInstance() }
uniapp中使用plus对象实现经典蓝牙
如果要使用的话建议用uts改写连接蓝牙是耗时操作使用plus对象无法通过plus.android.importClass(java.lang.Thread)将耗时操作放入子线程会导致页面卡顿。以下uts代码由AI生成尚未自测仅供参考。html5plus版本(已自测过)//经典蓝牙服务的UUID const UUIDString 00001101-0000-1000-8000-00805F9B34FB; class Bluetooth { //蓝牙类的实例 instance; /**当前程序页面上下文 */ Activity; /**蓝牙适配器 */ Adapter; /**蓝牙建立的连接 */ BluetoothSocket; /**蓝牙适配器接收器 */ BluetoothReciever; /**蓝牙所需的权限 */ permissions []; /**搜索到蓝牙的回调 */ onBluetoothDeviceFoundCallBack () {}; /**蓝牙状态变更 */ onBluetoothConnectedChangeCallback () {}; /**蓝牙适配器状态变更 */ onBluetoothAdapterChangeCallback () {}; //初始化 constructor() { if (Bluetooth.instance) return Bluetooth.instance; Bluetooth.instance this; return Bluetooth.instance; } //初始化蓝牙适配器 init() { this.Activity plus.android.runtimeMainActivity(); const BluetoothAdapter plus.android.importClass(android.bluetooth.BluetoothAdapter); const BluetoothDevice plus.android.importClass(android.bluetooth.BluetoothDevice); const Intent plus.android.importClass(android.content.Intent); //初始化蓝牙适配器 this.Adapter BluetoothAdapter.getDefaultAdapter(); //校验是否存在蓝牙权限 if (!this.Adapter) return showToast({ position: top, message: 当前设备不支持蓝牙! }); //保存this指向 //如果适配器不可用跳往设置页 if (!this.Adapter.isEnabled) { //创建意图 const intent new Intent(this.Adapter.ACTION_REQUEST_ENABLE); //跳转至蓝牙设置 plus.android.invoke(this.Activity, startActivity, intent, 1, null); return; } const Manifest plus.android.importClass(android.Manifest); this.permissions [ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_ADVERTISE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN ]; //蓝牙开关变化常量 const STATE_CHANGED BluetoothAdapter.ACTION_STATE_CHANGED; //蓝牙连接常量 const ACTION_ACL_CONNECTED BluetoothDevice.ACTION_ACL_CONNECTED; //蓝牙断开连接常量 const ACTION_ACL_DISCONNECTED BluetoothDevice.ACTION_ACL_DISCONNECTED; //搜索到蓝牙常量 const ACTION_FOUND BluetoothDevice.ACTION_FOUND; //保存this指向 const that this; //接收广播(注意:这里广播的类需要加io.dcloud前缀不加会出现报错无法执行) this.BluetoothReciever plus.android.implements(io.dcloud.android.content.BroadcastReceiver, { //接收蓝牙发出的广播 onReceive: function (context, intent) { //获取广播意图 const action plus.android.invoke(intent, getAction); //获取蓝牙设备信息 const device plus.android.invoke(intent, getParcelableExtra, android.bluetooth.device.extra.DEVICE); //获取蓝牙设备名称 const deviceName device.getName(); if (!deviceName) return; //获取蓝牙设备id const deviceId device.getAddress(); switch (action) { //蓝牙开关变化 case STATE_CHANGED: //获取蓝牙广播状态 const EXTRA_STATE plus.android.getAttribute(new BluetoothAdapter(), EXTRA_STATE); //广播状态码 const code plus.android.invoke(intent, getIntExtra, EXTRA_STATE, -1); switch (code) { case BluetoothAdapter.STATE_OFF: that.onBluetoothAdapterChangeCallback({ state: false }); break; case BluetoothAdapter.STATE_ON: that.onBluetoothAdapterChangeCallback({ state: true }); break; } break; //蓝牙连接成功 case ACTION_ACL_CONNECTED: that.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: true }); break; //蓝牙断开连接成功 case ACTION_ACL_DISCONNECTED: //蓝牙断开则把建立的socket置空 that.BluetoothSocket null; that.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: false }); break; //搜索到蓝牙 case ACTION_FOUND: if (!deviceName) return; that.onBluetoothDeviceFoundCallBack({ name: deviceName, deviceId }); break; } } }); //创建意图过滤器添加需要监听的蓝牙广播动作 const IntentFilter plus.android.newObject(android.content.IntentFilter); // 监听蓝牙开关状态变化核心广播 plus.android.invoke(IntentFilter, addAction, STATE_CHANGED); // 监听蓝牙设备连接成功 plus.android.invoke(IntentFilter, addAction, ACTION_ACL_CONNECTED); // 监听蓝牙设备断开连接 plus.android.invoke(IntentFilter, addAction, ACTION_ACL_DISCONNECTED); // 监听搜索到的蓝牙 plus.android.invoke(IntentFilter, addAction, ACTION_ACL_DISCONNECTED); //搜索到蓝牙 plus.android.invoke(IntentFilter, addAction, ACTION_FOUND); //注册广播接收器 plus.android.invoke(this.Activity, registerReceiver, this.BluetoothReciever, IntentFilter); //蓝牙提示语 console.info(蓝牙广播接收器注册成功); } //获取已连接蓝牙列表 getBondedDevices() { return new Promise((resolve, reject) { //获取已配对列表 const devices this.Adapter.getBondedDevices(); const iterator plus.android.invoke(devices, iterator); plus.android.importClass(iterator); const list []; while (iterator.hasNext()) { const device iterator.next(); const name plus.android.invoke(device, getName); const deviceId plus.android.invoke(device, getAddress); list.push({ name, deviceId }); } resolve(list); }); } //搜索蓝牙 discoverDevices(callback) { plus.android.requestPermissions( this.permissions, ({ granted }) { console.log(请求权限, granted); this.onBluetoothDeviceFoundCallBack callback; //当前是否正在搜索 const isDiscovering plus.android.invoke(this.Adapter, isDiscovering); //如果正在搜索,先停止再重新搜索 if (isDiscovering) { this.stopDiscover(); } //开始搜索蓝牙 plus.android.invoke(this.Adapter, startDiscovery); //三秒后停止搜索 setTimeout(() { this.stopDiscover(); }, 3000); }, () {} ); } //蓝牙状态变更 onBluetoothConnectedChange(callback) { this.onBluetoothConnectedChangeCallback callback; } //蓝牙状态变更 onBluetoothAdapterChange(callback) { this.onBluetoothAdapterChangeCallback callback; } //停止搜索 stopDiscover() { if (!this.Adapter || !this.BluetoothReciever) return console.log({ message: 蓝牙适配器未开启! }); plus.android.invoke(this.Adapter, cancelDiscovery); } //连接蓝牙 connectDevice(id) { return new Promise((resolve, reject) { plus.android.requestPermissions( this.permissions, ({ granted }) { console.log(请求权限, granted); try { //停止扫描 const isDiscovering plus.android.invoke(this.Adapter, isDiscovering); //判断是否正在扫描附近的蓝牙 if (isDiscovering) { plus.android.invoke(this.Adapter, cancelDiscovery); } //如果已连接先关闭 if (this.BluetoothSocket) { plus.android.invoke(this.BluetoothSocket, close); this.BluetoothSocket null; } //蓝牙设备 if (!id) return reject({ message: 蓝牙参数错误! }); //获取远程蓝牙信号 const device plus.android.invoke(this.Adapter, getRemoteDevice, id); //筛选可用的设备UUID const UUID plus.android.importClass(java.util.UUID); const uuid UUID.fromString(UUIDString); this.BluetoothSocket device.createRfcommSocketToServiceRecord(uuid); plus.android.invoke(this.BluetoothSocket, connect); resolve(); } catch (error) { console.error(连接蓝牙出现了错误, error); this.BluetoothSocket null; reject({ code: -1, message: 连接超时或设备未开启! }); } }, (err) reject(err) ); }); } //断开蓝牙 disconnectDevice(id) { return new Promise((resolve, reject) { try { //获取当前连接的蓝牙 const device plus.android.invoke(this.Adapter, getRemoteDevice, id); const UUID plus.android.importClass(java.util.UUID); const uuid UUID.fromString(UUIDString); //获取蓝牙建立的连接 const socket plus.android.invoke(device, createInsecureRfcommSocketToServiceRecord, uuid); //当前蓝牙是否已连接 const isConnected plus.android.invoke(device, isConnected); //如果未连接直接阻断 if (!socket || !isConnected) return showToast({ position: top, message: 当前蓝牙未连接! }); //关闭输入流 const inputStream plus.android.invoke(socket, getInputStream); plus.android.invoke(inputStream, close); //关闭输出流 const outputStream plus.android.invoke(socket, getOutputStream); plus.android.invoke(outputStream, close); //断开建立的连接 plus.android.invoke(socket, close); resolve(); } catch (error) { reject(error); } }); } /** * 发送数据 * param {*} byte[] 二进制字节数组 * returns */ sendDataToBluetooth(bytes) { return new Promise(async (resolve, reject) { try { if (!this.BluetoothSocket) return showToast({ position: top, message: 连接已断开,请重新连接! }); //生成输出流; const outputStream plus.android.invoke(this.BluetoothSocket, getOutputStream); //字节长度 const byteLength bytes.byteLength; const blob new Int8Array(bytes); //当前字节索引 let currentSize 0; //切片大小 const chunkSize 2048; //子线程实现方法 while (currentSize byteLength) { const chunk blob.slice(currentSize, currentSize chunkSize); //发送数据 plus.android.invoke(outputStream, write, [...chunk]); //当前索引自增 currentSize chunkSize; } resolve(); } catch (error) { console.error(发送失败, error); reject(error); } }); } } /** * 创建蓝牙实例 * returns */ export const createBluetooth () { return new Bluetooth(); };页面中使用template div classpage van-button clickdiscover搜索蓝牙/van-button van-button clicksendData发送数据/van-button ul classcontainer li v-foritem in list :keyitem.deviceId clickconnect(item.deviceId) {{ item.name }} /li /ul /div /template script setup import { ref, onMounted } from vue; import { getBinary, getTextBinary, getQrCode } from /api/common; import { createBluetooth } from /system/bluetooth; const list ref([]); const bluetooth createBluetooth(); onMounted(() { bluetooth.init(); }); //搜索蓝牙 const discover () { bluetooth.discoverDevices((device) { const same list.value.find((el) el.deviceId device.deviceId); if (same) return; list.value.push(device); }); }; //连接蓝牙 const connect (id) { bluetooth.connectDevice(id); }; //发送数据 const sendData async () { const res await getBinary(); //请求打印数据 bluetooth.sendDataToBluetooth(res); }; bluetooth.onBluetoothConnectedChange((res) console.log(蓝牙连接状态变更了, res)); bluetooth.onBluetoothAdapterChange(({ state }) console.info(蓝牙开关变更了, state)); /script style scoped langscss .page { padding-top: 50px; display: flex; flex-direction: column; width: 100%; height: 100vh; overflow-y: scroll; .van-button { flex-shrink: 0; } .container { width: 100%; flex: 1; overflow-y: scroll; li { width: 100%; height: 40px; text-align: center; overflow: hidden; } } } /styleuts版Android(借助AI生成尚未自测仅作参考)import { BluetoothAdapter, BluetoothDevice, Intent, IntentFilter, BroadcastReceiver,Context,UUID,Manifest} from android; // 经典蓝牙服务UUID const UUIDString 00001101-0000-1000-8000-00805F9B34FB; export type BluetoothDeviceInfo { name: string, deviceId: string } export type BluetoothConnectStatus { name?: string, deviceId?: string, status: boolean } export type BluetoothAdapterStatus { state: boolean } // 安卓原生类导入 import { BluetoothAdapter, BluetoothDevice, Intent, IntentFilter, BroadcastReceiver, Context, UUID, Manifest } from android; export class Bluetooth { private static instance: Bluetooth | null null; private activity: Context; private adapter: BluetoothAdapter | null null; private socket: any null; private receiver: BroadcastReceiver | null null; private permissions: string[] []; public onBluetoothDeviceFoundCallBack: (device: BluetoothDeviceInfo) void () {}; public onBluetoothConnectedChangeCallback: (status: BluetoothConnectStatus) void () {}; public onBluetoothAdapterChangeCallback: (status: BluetoothAdapterStatus) void () {}; private constructor() { this.activity plus.android.runtimeMainActivity(); } public static getInstance(): Bluetooth { if (!Bluetooth.instance) { Bluetooth.instance new Bluetooth(); } return Bluetooth.instance; } private createReceiver(): BroadcastReceiver { const self this; // UTS 官方标准写法替代 plus.android.implements const receiver new BroadcastReceiver(); receiver.onReceive (context: Context, intent: Intent) { const action intent.getAction(); const device intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) as BluetoothDevice | null; if (!device) return; const deviceName device.getName() ?? ; const deviceId device.getAddress() ?? ; if (!deviceName) return; switch (action) { case BluetoothAdapter.ACTION_STATE_CHANGED: const state intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); if (state BluetoothAdapter.STATE_ON) { self.onBluetoothAdapterChangeCallback({ state: true }); } else if (state BluetoothAdapter.STATE_OFF) { self.onBluetoothAdapterChangeCallback({ state: false }); } break; case BluetoothDevice.ACTION_ACL_CONNECTED: self.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: true }); break; case BluetoothDevice.ACTION_ACL_DISCONNECTED: self.socket null; self.onBluetoothConnectedChangeCallback({ name: deviceName, deviceId, status: false }); break; case BluetoothDevice.ACTION_FOUND: self.onBluetoothDeviceFoundCallBack({ name: deviceName, deviceId }); break; } }; return receiver; } // 初始化 public init() { try { this.adapter BluetoothAdapter.getDefaultAdapter(); if (!this.adapter) { uni.showToast({ title: 设备不支持蓝牙, position: top }); return; } if (!this.adapter.isEnabled()) { const enableIntent new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); this.activity.startActivity(enableIntent); return; } // 权限 this.permissions [ Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_ADMIN ]; // 创建广播已修复 this.receiver this.createReceiver(); const filter new IntentFilter(); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); filter.addAction(BluetoothDevice.ACTION_FOUND); this.activity.registerReceiver(this.receiver, filter); console.log(✅ 蓝牙广播注册成功UTS 标准版); } catch (e) { console.error(初始化失败, e); } } // 获取已配对设备 public getBondedDevices(): PromiseBluetoothDeviceInfo[] { return new Promise(resolve { const list: BluetoothDeviceInfo[] []; const devices this.adapter?.getBondedDevices() ?? new Set(); for (const dev of devices) { list.push({ name: dev.getName() ?? , deviceId: dev.getAddress() ?? }); } resolve(list); }); } // 搜索设备 public discoverDevices(callback: (device: BluetoothDeviceInfo) void) { plus.android.requestPermissions(this.permissions, (res: any) { if (!res.granted) return; this.onBluetoothDeviceFoundCallBack callback; if (this.adapter?.isDiscovering()) { this.adapter.cancelDiscovery(); } this.adapter?.startDiscovery(); setTimeout(() this.stopDiscover(), 3000); }); } // 停止搜索 public stopDiscover() { this.adapter?.cancelDiscovery(); } // 连接设备 public connectDevice(deviceId: string): Promisevoid { return new Promise((resolve, reject) { try { if (!this.adapter) return reject(未初始化); if (this.adapter.isDiscovering()) { this.adapter.cancelDiscovery(); } if (this.socket) { this.socket.close(); this.socket null; } const device this.adapter.getRemoteDevice(deviceId); const uuid UUID.fromString(UUIDString); this.socket device.createRfcommSocketToServiceRecord(uuid); this.socket.connect(); resolve(); } catch (e) { this.socket null; reject(e); } }); } // 断开连接 public disconnectDevice(): Promisevoid { return new Promise(resolve { try { if (this.socket) { this.socket.close(); this.socket null; } resolve(); } catch { resolve(); } }); } // 发送数据 public sendDataToBluetooth(buffer: ArrayBuffer): Promisevoid { return new Promise((resolve, reject) { try { if (!this.socket) { uni.showToast({ title: 未连接, position: top }); return reject(未连接); } const stream this.socket.getOutputStream(); const bytes new Uint8Array(buffer); const chunk 2048; let pos 0; while (pos bytes.length) { const end Math.min(pos chunk, bytes.length); const slice bytes.slice(pos, end); stream.write(Array.from(slice)); pos end; } resolve(); } catch (e) { reject(e); } }); } public onBluetoothConnectedChange(callback: (status: BluetoothConnectStatus) void) { this.onBluetoothConnectedChangeCallback callback; } public onBluetoothAdapterChange(callback: (status: BluetoothAdapterStatus) void) { this.onBluetoothAdapterChangeCallback callback; } } export const createBluetooth () Bluetooth.getInstance();uts版本iOS版本(借助AI生成尚未自测,仅供参考)import Foundation import CoreBluetooth // 经典蓝牙 SPP UUIDiOS 上同样使用该 UUID 匹配 const UUIDString 00001101-0000-1000-8000-00805F9B34FB // 设备信息 export type BluetoothDeviceInfo { name: string deviceId: string } // 连接状态 export type BluetoothConnectStatus { name?: string deviceId?: string status: boolean } // 蓝牙开关状态 export type BluetoothAdapterStatus { state: boolean } /** * iOS 经典蓝牙SPP实现 * 对外 API 与 Android 版本完全一致 */ export class Bluetooth { private static instance: Bluetooth | null null // CoreBluetooth 核心 private centralManager: CBCentralManager! private connectedPeripheral: CBPeripheral? private writeCharacteristic: CBCharacteristic? // 发现/连接回调 public onBluetoothDeviceFoundCallBack: (device: BluetoothDeviceInfo) void () {} public onBluetoothConnectedChangeCallback: (status: BluetoothConnectStatus) void () {} public onBluetoothAdapterChangeCallback: (status: BluetoothAdapterStatus) void () {} // 搜索缓存避免重复回调 private discoveredIds: Setstring [] private constructor() { self.centralManager CBCentralManager( delegate: self, queue: DispatchQueue.global() ) } public static getInstance(): Bluetooth { if (Bluetooth.instance null) { Bluetooth.instance Bluetooth() } return Bluetooth.instance! } /** * 初始化蓝牙iOS 自动触发权限 */ public init(): void { // iOS 蓝牙状态由 CBCentralManagerDelegate 回调 console.log(iOS 蓝牙初始化完成) } /** * 获取已配对设备iOS 无法直接获取返回空数组 */ public getBondedDevices(): PromiseBluetoothDeviceInfo[] { return Promise.resolve([]) } /** * 搜索蓝牙设备 */ public discoverDevices(callback: (device: BluetoothDeviceInfo) void): void { self.onBluetoothDeviceFoundCallBack callback self.discoveredIds.removeAll() if self.centralManager.state ! .poweredOn { console.log(蓝牙未开启) return } // 停止之前扫描 self.centralManager.stopScan() // 开始扫描 SPP 设备 let sppUUID CBUUID(string: UUIDString) self.centralManager.scanForPeripherals( withServices: [sppUUID], options: [CBCentralManagerScanOptionAllowDuplicatesKey: false] ) // 3 秒后停止 setTimeout(3000) { self.centralManager.stopScan() } } /** * 停止搜索 */ public stopDiscover(): void { self.centralManager.stopScan() } /** * 连接设备 */ public connectDevice(deviceId: string): Promisevoid { return Promise { resolve, reject in if deviceId.isEmpty { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 设备 ID 不能为空])) return } if self.centralManager.state ! .poweredOn { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 蓝牙未开启])) return } // 先停止扫描 self.centralManager.stopScan() // 找到对应外设需要先扫描过 guard let peripheral self.findPeripheral(withUUID: deviceId) else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 未找到该设备请先搜索])) return } self.centralManager.connect(peripheral, options: nil) // 超时 10 秒 setTimeout(10000) { if self.connectedPeripheral nil { self.centralManager.cancelPeripheralConnection(peripheral) reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 连接超时])) } } } } /** * 断开连接 */ public disconnectDevice(deviceId: string): Promisevoid { return Promise { resolve, reject in guard let peripheral self.connectedPeripheral else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 未连接设备])) return } self.centralManager.cancelPeripheralConnection(peripheral) resolve() } } /** * 发送二进制数据 */ public sendDataToBluetooth(_ buffer: ArrayBuffer): Promisevoid { return Promise { resolve, reject in guard let char self.writeCharacteristic else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 未找到可写特征])) return } guard let peripheral self.connectedPeripheral else { reject(NSError(domain: bluetooth, code: -1, userInfo: [NSLocalizedDescriptionKey: 设备未连接])) return } let data Data(bytes: buffer.bytes, count: buffer.byteLength) // iOS BLE 单次发送最大 2048与 Android 分片逻辑一致 let chunkSize 2048 var offset 0 while offset data.count { let end min(offset chunkSize, data.count) let chunk data[offset..end] peripheral.writeValue(chunk, for: char, type: .withoutResponse) offset end } resolve() } } // 监听连接状态 public onBluetoothConnectedChange(callback: (BluetoothConnectStatus) - Void) { self.onBluetoothConnectedChangeCallback callback } // 监听蓝牙开关 public onBluetoothAdapterChange(callback: (BluetoothAdapterStatus) - Void) { self.onBluetoothAdapterChangeCallback callback } // 根据 UUID 查找外设 private func findPeripheral(withUUID uuidString: String) - CBPeripheral? { for peripheral in self.centralManager.retrieveConnectedPeripherals(withServices: [CBUUID(string: UUIDString)]) { if peripheral.identifier.uuidString uuidString { return peripheral } } return nil } } // MARK: - CBCentralManagerDelegate extension Bluetooth: CBCentralManagerDelegate { public func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: self.onBluetoothAdapterChangeCallback({ state: true }) case .poweredOff, .unauthorized, .unsupported, .unknown: self.onBluetoothAdapterChangeCallback({ state: false }) default: break } } public func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { let deviceId peripheral.identifier.uuidString let name peripheral.name ?? 未知设备 if self.discoveredIds.contains(deviceId) { return } self.discoveredIds.insert(deviceId) self.onBluetoothDeviceFoundCallBack({ name: name, deviceId: deviceId }) } public func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { self.connectedPeripheral peripheral peripheral.delegate self peripheral.discoverServices([CBUUID(string: UUIDString)]) self.onBluetoothConnectedChangeCallback({ name: peripheral.name ?? 未知设备, deviceId: peripheral.identifier.uuidString, status: true }) } public func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { self.connectedPeripheral nil self.writeCharacteristic nil self.onBluetoothConnectedChangeCallback({ name: peripheral.name ?? 未知设备, deviceId: peripheral.identifier.uuidString, status: false }) } public func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { print(连接失败, error?.localizedDescription ?? ) } } // MARK: - CBPeripheralDelegate extension Bluetooth: CBPeripheralDelegate { public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { guard let services peripheral.services else { return } for service in services { peripheral.discoverCharacteristics(nil, for: service) } } public func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { guard let chars service.characteristics else { return } for char in chars { // 找到可写特征 if char.properties.contains(.write) || char.properties.contains(.writeWithoutResponse) { self.writeCharacteristic char print(找到可写特征) } } } } // 对外兼容方法 export const createBluetooth (): Bluetooth { return Bluetooth.getInstance() }