1、先获取权限,才能进行开发

        微信小程序和移动设备的开发不太一样,在做开发之前需要先申请开发过程中需要用到的权限。
       搞开发,基本上都需要用到用户的隐私,开发者需要用到用户的隐私,这个隐私的使用方法和行为必须合法,开发者需要遵守相应的协议和政策,但不能口头上担保,需要去官网填写和签署这些协议和政策。

去哪里?微信公众平台
怎么做?
先完成小程序发布流程然后找到设置
找到“用户隐私保护指引”并完成各种填空。

2、脚本中声明需要用到的权限

在项目中找到app.json或者game.json,声明需要用到的权限

{
	"deviceOrientation": "portrait",
    "permission": {
        "scope.userLocation": {
          "desc": "你的旧版本的位置信息将用于小程序位置接口的效果展示"
        },
        "scope.userFuzzyLocation": {
            "desc": "你的模糊位置信息将用于小程序位置接口的效果展示"
        },
        "scope.bluetooth": {
            "desc": "需要蓝牙进行连接手柄"
		},
		"scope.userInfo": {
			"desc": "需要用户同意授权隐私信息,确保蓝牙功能可用"
		}
    }
}

3、在程序逻辑中使用对应的权限(引导用户同意授权)

获取用户信息

// 通过 wx.getSetting 查询用户是否已授权头像昵称信息
	wx.getSetting({
		success (res){
			if (res.authSetting['scope.userInfo']) {
				// 已经授权,可以直接调用 getUserInfo 获取头像昵称
				wx.getUserInfo({
				success: function(res) {
					console.log("获取用户信息成功",res.userInfo)
				}
				})
			} else {
				// 否则,先通过 wx.createUserInfoButton 接口发起授权
				let button = wx.createUserInfoButton({
					type: 'text',
					text: '获取用户信息',
					style: {
						left: 10,
						top: 160,
						width: 200,
						height: 40,
						lineHeight: 40,
						backgroundColor: '#ff0000',
						color: '#ffffff',
						textAlign: 'center',
						fontSize: 16,
						borderRadius: 4
					}
				})
				button.onTap((res) => {
					// 用户同意授权后回调,通过回调可获取用户头像昵称信息
					console.log(res)
				})
			}
		},
		fail (err){
			console.log("获取用户信息失败",err)
		}
	})

获取定位信息(有的安卓手机使用蓝牙额外需要定位权限)

wx.authorize({
		scope: 'scope.userFuzzyLocation',
		success (res) {
			console.log("获取定位权限成功",res)
		},
		fail (err){
			console.log("获取定位权限失败",err)
		}
	})

	wx.authorize({
		scope: 'scope.bluetooth',
		success (res) {
			console.log("获取蓝牙权限成功",res)
		},
		fail (err){
			console.log("获取蓝牙权限失败",err)
		}
	})

4、开蓝牙之前先关闭蓝牙。。。(为了得到一个干净环境,避免一些旧数据给开发带来干扰)

// 首先
wx.stopBluetoothDevicesDiscovery()
// 接着
wx.closeBluetoothAdapter()
// 然后
wx.openBluetoothAdapter()

5、通过设备ID连接对应的蓝牙设备(不知道如何获取设备ID看文章后半部分)

	wx.createBLEConnection({
		deviceId : "A4:D5:78:13:05:A9",
		success (res) {
			console.log("连接成功", res)
				// 连接成功后获取服务
		},
		fail (err) {
			console.log("连接失败", err)
		}
	})

6、通过蓝牙服务ID和服务特征ID订阅对应的传感器数据(通知)(不知道如何获取这些ID看文章后半部分)

const serviceId = '0000FFE0-0000-1000-8000-00805F9B34FB'
	const characteristicId = '0000FFE1-0000-1000-8000-00805F9B34FB'
	wx.notifyBLECharacteristicValueChange({
		deviceId: "A4:D5:78:13:05:A9",
		serviceId: serviceId,
		characteristicId: characteristicId,
		state: true, // 启用 notify 功能
		success (res) {
			console.log('notify success');
		}
});

7、根据硬件特点以及其发送的数据特点对蓝牙设备传输过来的数据进行解析(这个没法讲,各自的硬件和数据都不一样,只做个示例)

function onCharacteristicValueChange(res) {
		// 创建一个Uint8Array视图,它引用res.value中的二进制数据
		// let uint8Array = new Uint8Array(res.value);
		// 8int
		// 数据是ASCII码范围是0-127
		let int8Array = new Int8Array(res.value);
		let str = '';
		for(let i = 0; i < int8Array.length; i++) {
			str += String.fromCharCode(int8Array[i]);
		}
		str = str.replace(/(\r\n|\n|\r|\[|\])/gm, "");
		if (str[0] === "K"){
			let kArray = str.substring(1).split(",");
			console.log(kArray);
		}
		// if (str[0] === "A") {
		// 	let aArray = str.substring(1).split(",");
		// 	for (let i = 0; i < aArray.length; i++){
		// 		aArray[i] = parseInt(aArray[i], 16);
		// 		//aArray[i] = 65535 - aArray[i];
		// 	}
		// 	console.log(aArray);
		// 	//console.log(str);
		// }
		// if (str[0] === "G") {
		// 	let gArray = str.substring(1).split(",");
		// 	for (let i = 0; i < gArray.length; i++){
		// 		gArray[i] = parseInt(gArray[i], 16);
		// 		gArray[i] = 65535 - gArray[i];
		// 	}
		// 	console.log(gArray);
		// }
	}

        解析数据的这个函数,其实就是一个回调函数,用来处理(解析)蓝牙发送过来的数据。onCharacteristicValueChange函数作为参数传递给了wx.onBLECharacteristicValueChange;只要程序订阅了蓝牙的通知,传感器的数值发生了变化,蓝牙就会立刻给程序发送通知,程序就会立刻调用这个回调函数onCharacteristicValueChange解析蓝牙发送过来的数据。这个过程也叫事件监听。。。。。。

        就是,你订阅了蓝牙某个服务某个特征的通知,又注册了监听事件(函数),就可以监听对应数据的变化。

8、注册监听事件

// 订阅通知后 注册监听事件, 订阅之后来个监听事件来监听
wx.onBLECharacteristicValueChange(onCharacteristicValueChange);

// 在不需要的时候停止监听并且取消订阅
wx.offBLECharacteristicValueChange(onCharacteristicValueChange);
	wx.notifyBLECharacteristicValueChange({
		deviceId: "A4:D5:78:13:05:A9",
		serviceId: serviceId,
		characteristicId: characteristicId,
		state: false, // 关闭 notify 功能
		success (res) {
			console.log('取消特征值通知成功');
		},
		fail (error) {
			console.error('取消特征值通知失败', error);
		}
});

// 在不需要的时候断开蓝牙连接、关闭蓝牙适配器(收拾手尾)
wx.closeBLEConnection({
		deviceId: "A4:D5:78:13:05:A9",
		success (res) {
		  console.log('断开蓝牙设备成功', res);
		},
		fail (error) {
		  console.log('断开蓝牙设备失败', error);
		}
})

wx.closeBluetoothAdapter()

补充:

1、如何获取想要的蓝牙设备ID?

先搜索附近的BLE低功耗蓝牙、

搜索完毕之后能得到一个详细的列表,

里面包含了蓝牙的名称、蓝牙的设备ID、蓝牙的信号强度等。

(估计要蓝牙2.0甚至4.0版本的低功耗蓝牙才能被搜索到,估计比手机本身能识别的设备要少,就是,有些蓝牙手机能够搜索到,但是微信小程序是收不到的)

    wx.stopBluetoothDevicesDiscovery()

	wx.closeBluetoothAdapter()

	wx.openBluetoothAdapter()

    var DeviceIndex = 0;
	wx.startBluetoothDevicesDiscovery({
		allowDuplicatesKey: false,
		success: (res) => {
			console.log('开始搜索附近蓝牙设备', res);
			function ab2hex(buffer) {
			    const hexArr = Array.prototype.map.call(
				new Uint8Array(buffer),
				function(bit) {
				  return ('00' + bit.toString(16).slice(-2));
				}
			  );
			  return hexArr.join('');
			}
			function onDeviceFound(deviceRes) {
				deviceRes.devices.forEach((device) => {
				    if (device.localName || device.name) {
					console.log('设备名称:', device.localName || device.name);
					console.log('广播数据转为十六进制字符串', ab2hex(device.advertisData));
					console.log('新设备列表', DeviceIndex, deviceRes.devices);
					DeviceIndex++;
				}
			  });
			}
			wx.onBluetoothDeviceFound(onDeviceFound)
		},
		fail: (err) => {
			console.error('蓝牙设备搜索失败', err);
			wx.offBluetoothDeviceFound(onDeviceFound);
			console.log('停止监听新蓝牙设备');
			wx.stopBluetoothDevicesDiscovery({
				success: (res) => {
				  console.log('停止蓝牙搜索', res);
				},
				fail: (err) => {
				  console.error('停止蓝牙搜索失败', err);
				}
			  });
		}
	}); 

在不需要的时候停止蓝牙搜索

    wx.offBluetoothDeviceFound(onDeviceFound);
	console.log('停止监听新蓝牙设备');
	wx.stopBluetoothDevicesDiscovery({
		success: (res) => {
			console.log('停止蓝牙搜索', res);
		},
		fail: (err) => {
			console.error('停止蓝牙搜索失败', err);
		}
	});

枚举上一次搜索得到的蓝牙设备

    wx.getBluetoothDevices({
		success: function(res) {
			console.log('All discovered devices', res.devices);
			},
			fail (err) {
				console.log(err)
			}
	})

2.如何获取某个蓝牙拥有的服务的ID?

wx.startBluetoothDevicesDiscovery({
		allowDuplicatesKey: false,
		success: (res) => {
			console.log('开始搜索附近蓝牙设备', res);
			function ab2hex(buffer) {
			    const hexArr = Array.prototype.map.call(
					new Uint8Array(buffer),
					function(bit) {
						return ('00' + bit.toString(16).slice(-2));
					}
			    );
			    return hexArr.join('');
			}
			function onDeviceFound(deviceRes) {
				deviceRes.devices.forEach((device) => {
				    if (device.deviceId === "A4:D5:78:13:05:A9") {
						console.log('设备名称:', device.localName || device.name);
						console.log('广播数据转为十六进制字符串', ab2hex(device.advertisData));
						console.log('新设备列表', deviceRes.devices);
						wx.stopBluetoothDevicesDiscovery({
							success: (res) => {
								console.log('停止蓝牙搜索成功', res);
							},
							fail: (err) => {
								console.error('停止蓝牙搜索失败', err);
							}
						});
						wx.createBLEConnection({
							deviceId : "A4:D5:78:13:05:A9",
							success (res) {
								console.log("连接成功", res)
								    // 连接成功后获取服务
								wx.getBLEDeviceServices({
									deviceId: 'A4:D5:78:13:05:A9',
									success (res) {
									console.log('设备服务列表', res.services);
									console.log('设备服务列表', res);
									},
									fail (err) {
										console.log("获取服务列表失败", err)
									}
								});
							},
							fail (err) {
								console.log("连接失败", err)
							}
						})
						wx.onBLEConnectionStateChange(function (res) {
							// res.connected 表示该设备是否处于连接状态
							console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)
						})
				}
			  });
			}
			wx.onBluetoothDeviceFound(onDeviceFound)
		},
		fail: (err) => {
			console.error('蓝牙设备搜索失败', err);
			wx.offBluetoothDeviceFound(onDeviceFound);
			console.log('停止监听新蓝牙设备');
			wx.stopBluetoothDevicesDiscovery({
				success: (res) => {
				  console.log('停止蓝牙搜索成功', res);
				},
				fail: (err) => {
				  console.error('停止蓝牙搜索失败', err);
				}
			  });
		}
	});

核心是这里(先连接好蓝牙之后):

wx.getBLEDeviceServices({
    deviceId: 'A4:D5:78:13:05:A9',
	success (res) {
		console.log('设备服务列表', res.services);
		console.log('设备服务列表', res);
    },
	fail (err) {
		console.log("获取服务列表失败", err)
	}
});

3.如何获取某个蓝牙服务的特征ID?

核心(获取了服务ID之后):

	const deviceId = 'A4:D5:78:13:05:A9';
	// 假设 serviceUuids 是您从 wx.getBLEDeviceServices 获取的服务UUID列表
	const serviceUuids = ['00001800-0000-1000-8000-00805F9B34FB', '00001801-0000-1000-8000-00805F9B34FB', '0000FFE0-0000-1000-8000-00805F9B34FB'];
	serviceUuids.forEach(serviceUuid => {
		wx.getBLEDeviceCharacteristics({
		deviceId: deviceId,
		serviceId: serviceUuid,
		success: function(res) {
			console.log(`服务 ${serviceUuid} 的特征列表:`, res.characteristics);
			// 根据特征属性进行后续操作,比如读取、写入、通知等
		},
		fail: function(err) {
			console.error(`获取服务 ${serviceUuid} 的特征失败:`, err);
		}
		});
	});

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐