uni-app 实现连接蓝牙功能

目前我用的是微信小程序实现无需额外配置,app的需要额外在 manifest.json 文件添加配置。

image

一、初始化蓝牙模块

文档:uni.openBluetoothAdapter

注意

  1. 其他蓝牙相关 API 必须在 uni.openBluetoothAdapter 调用之后使用。否则 API 会返回错误(errCode=10000)。
  2. 在用户蓝牙开关未开启或者手机不支持蓝牙功能的情况下,调用 uni.openBluetoothAdapter 会返回错误(errCode=10001),3. 表示手机蓝牙功能不可用。此时APP蓝牙模块已经初始化完成,可通过 uni.onBluetoothAdapterStateChange 监听手机蓝牙状态的改变,也可以调用蓝牙模块的所有API。
{
    "errMsg": "openBluetoothAdapter:ok"
}

二、获取本机蓝牙适配器状态

文档:uni.getBluetoothAdapterState

三、开始搜寻附近的蓝牙外围设备

文档:uni.startBluetoothDevicesDiscovery

开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用 uni.stopBluetoothDevicesDiscovery 方法停止搜索。

{
    "errMsg": "startBluetoothDevicesDiscovery:ok"
}

注意:

App 端目前仅支持发现ble蓝牙设备,更多蓝牙设备发现,可以使用 Native.js,参考:https://ask.dcloud.net.cn/article/114。 也可以在插件市场获取原生插件

四、监听寻找到新设备的事件

文档:uni.onBluetoothDeviceFound

获取蓝牙设备列表,找到需要的那个,设备列表在回调函数中

{
    "devices": [
        {
            "deviceId": "D2:5D:88:48:54:85",
            "name": "",
            "RSSI": -85,
            "localName": "",
            "advertisServiceUUIDs": [],
            "advertisData": {}
        }
    ]
}

注意

若在 uni.onBluetoothDeviceFound 回调了某个设备,则此设备会添加到 uni.getBluetoothDevices 接口获取到的数组中。

五、连接低功耗蓝牙设备

文档:uni.createBLEConnection

若APP在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。

注意

请保证尽量成对的调用 createBLEConnectioncloseBLEConnection 接口。安卓如果多次调用 createBLEConnection 创建连接,有可能导致系统持有同一设备多个连接的实例,导致调用 closeBLEConnection 的时候并不能真正的断开与设备的连接。
蓝牙连接随时可能断开,建议监听 uni.onBLEConnectionStateChange 回调事件,当蓝牙设备断开时按需执行重连操作
若对未连接的设备或已断开连接的设备调用数据读写操作的接口,会返回 10006 错误,建议进行重连操作。

{
    "errMsg": "createBLEConnection:ok"
}

六、获取蓝牙设备所有服务(service)

文档:uni.getBLEDeviceServices

{
    "services": [
        {
            "uuid": "00001800-0000-1000-8000-00805F9B34FB",
            "isPrimary": true
        },
        {
            "uuid": "00001801-0000-1000-8000-00805F9B34FB",
            "isPrimary": true
        },
        {
            "uuid": "0000180A-0000-1000-8000-00805F9B34FB",
            "isPrimary": true
        },
        {
            "uuid": "D0611E78-BBB4-4591-A5F8-487910AE4366",
            "isPrimary": true
        },
        {
            "uuid": "9FA480E0-4967-4542-9390-D343DC5D04AE",
            "isPrimary": true
        },
        {
            "uuid": "0000FFF1-0000-1000-8000-00805F9B34FB",
            "isPrimary": true
        },
        {
            "uuid": "BAF550E1-8B33-4A03-A6DC-3E2153FD242B",
            "isPrimary": true
        },
        {
            "uuid": "0000180F-0000-1000-8000-00805F9B34FB",
            "isPrimary": true
        },
        {
            "uuid": "00001805-0000-1000-8000-00805F9B34FB",
            "isPrimary": true
        },
        {
            "uuid": "7905F431-B5CE-4E99-A40F-4B1E122D00D0",
            "isPrimary": true
        },
        {
            "uuid": "89D3502B-0F36-433A-8EF4-C502AD55F8DC",
            "isPrimary": true
        }
    ],
    "errMsg": "getBLEDeviceServices:ok"
}

七、获取蓝牙设备某个服务中所有特征值

文档:uni.getBLEDeviceCharacteristics

{
    "characteristics": [
        {
            "uuid": "0000FFF1-0000-1000-8000-00805F9B34FB",
            "properties": {
                "read": true,
                "write": true,
                "notify": true,
                "indicate": true
            }
        }
    ],
    "errMsg": "getBLEDeviceCharacteristics:ok"
}

八、启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值

文档:uni.notifyBLECharacteristicValueChange

启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。注意:必须设备的特征值支持 notify 或者 indicate 才可以成功调用。 另外,必须先启用 notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件

九、向低功耗蓝牙设备特征值中写入二进制数据

文档:uni.writeBLECharacteristicValue

向低功耗蓝牙设备特征值中写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。

注意

  • 并行调用多次会存在写失败的可能性。
  • APP不会对写入数据包大小做限制,但系统与蓝牙设备会限制蓝牙4.0单次传输的数据大小,超过最大字节数后会发生写入错误,建议每次写入不超过20字节。
  • 若单次写入数据过长,iOS 上存在系统不会有任何回调的情况(包括错误回调)。
  • 安卓平台上,在调用 notifyBLECharacteristicValueChange 成功后立即调用 writeBLECharacteristicValue 接口,在部分机型上会发生 10008 系统错误
{
    "errMsg": "writeBLECharacteristicValue:ok"
}

十、监听低功耗蓝牙设备的特征值变化事件

文档:uni.onBLECharacteristicValueChange

监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification

进制转换小工具

// json对象转二进制
const encodeStr = (s) => {
	if (typeof TextEncoder !== 'undefined') return new TextEncoder().encode(s);
	const out = [];
	for (const ch of s || '') {
		const cp = ch.codePointAt(0);
		if (cp <= 0x7F) out.push(cp);
		else if (cp <= 0x7FF) out.push(0xC0 | (cp >> 6), 0x80 | (cp & 0x3F));
		else if (cp <= 0xFFFF) out.push(0xE0 | (cp >> 12), 0x80 | ((cp >> 6) & 0x3F), 0x80 | (
			cp & 0x3F));
		else out.push(0xF0 | (cp >> 18), 0x80 | ((cp >> 12) & 0x3F), 0x80 | ((cp >> 6) & 0x3F),
					  0x80 | (cp & 0x3F));
	}
	return new Uint8Array(out);
};

const toArrayBufferJson = (obj) => {
	const u8 = encodeStr(JSON.stringify(obj));
	return (u8.byteOffset === 0 && u8.byteLength === u8.buffer.byteLength) ? u8.buffer : u8
		.slice().buffer;
};

// 二进制 -> JSON 对象
const bufferToUtf8 = (buffer) => {
	if (!buffer) return ''

	// 确保是 Uint8Array
	let uint8Array = buffer instanceof Uint8Array
	? buffer
	: new Uint8Array(buffer)

	// H5 / 新版 App 支持
	if (typeof TextDecoder !== 'undefined') {
		try {
			return new TextDecoder('utf-8').decode(uint8Array)
		} catch (e) {
			// 继续走兜底
		}
	}

	// 兜底方案:手写 UTF-8 解码(兼容微信小程序)
	let out = ''
	let i = 0
	const len = uint8Array.length

	while (i < len) {
		const c = uint8Array[i++]

		if (c < 0x80) {
			out += String.fromCharCode(c)
		} else if (c < 0xE0) {
			const c2 = uint8Array[i++]
			out += String.fromCharCode(
				((c & 0x1F) << 6) | (c2 & 0x3F)
			)
		} else if (c < 0xF0) {
			const c2 = uint8Array[i++]
			const c3 = uint8Array[i++]
			out += String.fromCharCode(
				((c & 0x0F) << 12) |
				((c2 & 0x3F) << 6) |
				(c3 & 0x3F)
			)
		} else {
			// 4 字节 UTF-8(emoji)
			const c2 = uint8Array[i++]
			const c3 = uint8Array[i++]
			const c4 = uint8Array[i++]
			let codePoint =
				((c & 0x07) << 18) |
				((c2 & 0x3F) << 12) |
				((c3 & 0x3F) << 6) |
				(c4 & 0x3F)
			codePoint -= 0x10000
			out += String.fromCharCode(
				0xD800 + (codePoint >> 10),
				0xDC00 + (codePoint & 0x3FF)
			)
		}
	}

	return out
}

posted @ 2025-07-24 14:46  启航黑珍珠号  阅读(1096)  评论(0)    收藏  举报