23_微信小程序蓝牙-权限适配篇

23_微信小程序蓝牙-权限适配篇

注: 示例代码使用uniapp编写,下面通过uni.调用的API侧重于微信侧,等同于wx.

微信小程序中使用蓝牙模块,首先必须要调用uni.openBluetoothAdapter初始化蓝牙模块。只有蓝牙模块初始化成功,后续的蓝牙相关API才能调用成功,而uni.openBluetoothAdapter受限于小程序的授权管理机制,以及微信app的授权管理机制

一.微信小程序使用蓝牙的权限适配

当微信小程序首次调用uni.openBluetoothAdapter,会弹出弹窗提示用户允许拒绝,如果用户点击允许,那么这个权限授权成功,如果用户点了拒绝,那么下一次调用uni.openBluetoothAdapter,是不会有弹窗提示的,并且uni.openBluetoothAdapter调用结果返回失败。

uni.openBluetoothAdapter().catch((err) => {
  uni.showModal({
    content: JSON.stringify(err)
  })
  return Promise.reject()
}).then((res) => {
  uni.showModal({
    content: "蓝牙模块初始化成功"
  })
})

在这里插入图片描述

这种情况,在调用uni.openBluetoothAdapter之前,使用uni.authorize({scope: "scope.bluetooth"})预先授权,当首次弹出授权弹窗,用户点击了拒绝后,uni.authorize({scope: "scope.bluetooth"})返回失败结果,此时可以使用uni.getSetting判断用户是否授权,如果没有授权,使用uni.openSetting,打开小程序设置页,引导用户授权。

<template>
	<view class="index__test-btn" @click="toOpenBluetoothAdapter($event)">openBluetoothAdapter</view>
</template>

<script>
	export default {
		methods: {
      toOpenBluetoothAdapter: function() {
				const openBluetoothAdapter = () => {
					return uni.openBluetoothAdapter().catch((err) => {
						uni.showModal({
							content: `openBluetoothAdapter: ${JSON.stringify(err)}`
						})
						return Promise.reject()
					})
				}
				
				this.authorizeBluetooth().catch((err) => {
					uni.showModal({
						content: `authorizeBluetooth: ${JSON.stringify(err)}`
					})
					return Promise.reject()
				}).then((res) => {
					return openBluetoothAdapter()
				}).then((res) => {
					uni.showModal({
						content: "蓝牙模块初始化成功"
					})
				})
			},
			
			authorizeBluetooth: function() {
				const scope = "scope.bluetooth"
				const openSetting = () => {
					return uni.showModal({
						content: "您需要在设置中开启\"蓝牙\"选项,才可以使用蓝牙哦!",
						cancelText: "任性不去",
						confirmText: "去设置",
					}).then((res) => {
						if (res.confirm) {
							return uni.openSetting().catch((error) => {
								console.log("openSetting", error)
								return Promise.reject({
									"errMsg": "openSetting:fail system error",
									"errno": -2
								})
							}).then((res) => {
								let authSetting = res.authSetting || {}
								if (authSetting[scope]) {
									return Promise.resolve()
								} else {
									return openSetting()
								}
							})
						} else {
							return Promise.reject({
								"errMsg": "authorize:fail auth deny",
								"errno": 103
							})
						}
					})
				}
				
				const getSetting = () => {
					return uni.getSetting().catch((error) => {
						return Promise.reject({
							"errMsg": "authorize:fail system error",
							"errno": -2
						})
					}).then((res) => {
						let authSetting = res.authSetting || {}
						let keys = Object.keys(authSetting)
						
						if (keys.indexOf(scope) != -1) {
							if(!authSetting[scope]) {
								return openSetting()
							} else {
								return Promise.resolve() 
							}
						} else {
							return Promise.reject({
								"errMsg": "authorize:fail auth canceled",
								"errno": -3
							})
						}
					})
				}
				
				return uni.authorize({scope: scope}).catch((err) => {
					return getSetting()
				})
			}
    }
	}
</script>

在这里插入图片描述

当我们允许小程序使用蓝牙授权后,调用uni.openBluetoothAdapter后,又报了system permission denied

二.微信app使用蓝牙的权限适配

调用uni.openBluetoothAdapter后,之所以会报system permission denied这个错,是因为:

  • 安卓 6.0 及以上版本手机,无定位权限定位开关未打开
  • 安卓 12 及以上版本手机,无搜索附件设备权限附件设备开关未打开
  • iOS手机,未打开微信app访问蓝牙的开关

这几种情况,只能用户手动去手机的系统设置里面授权。

如果上述权限都已经授权的情况下,系统的蓝牙开关未开启,uni.openBluetoothAdapter也无法被成功调用。
在这里插入图片描述

针对上述权限的适配,以及用户未打开系统蓝牙开关的情况,目前只能是写一个使用说明,把授权流程写清楚,引导用户按照流程操作。

<script>
	/**
	 * 蓝牙权限待申请
	 */
	const BLUETOOTH_AUTHOR_PENDING = "BLUETOOTH_AUTHOR_PENDING"
	/**
	 * 蓝牙权限被拒绝
	 */
	const BLUETOOTH_AUTHOR_REJECT = "BLUETOOTH_AUTHOR_REJECT"
	/**
	 * BluetoothAdapter不可用
	 */
	const BLUETOOTH_ADAPTER_UNAVAILABLE = "BLUETOOTH_ADAPTER_UNAVAILABLE"
	/**
	 * 蓝牙适配器可用
	 */
	const BLUETOOTH_ADAPTER_AVAILABLE = "BLUETOOTH_ADAPTER_AVAILABLE"
	
	export default {
		data() {
			return {
				bluetoothStatus: BLUETOOTH_AUTHOR_PENDING
			}
		},
		onLoad() {
			
		},
		methods: {
			toOpenBluetoothAdapter: function() {
				const openBluetoothAdapter = () => {
					return uni.openBluetoothAdapter().catch((err) => {
						this.bluetoothStatus = BLUETOOTH_ADAPTER_UNAVAILABLE
						return Promise.reject()
					})
				}
				
				this.bluetoothStatus = BLUETOOTH_AUTHOR_PENDING
				this.authorizeBluetooth().then((res) => {
					return openBluetoothAdapter()
				}).catch((err) => {
					uni.showModal({
						content: "蓝牙模块初始化失败",
						confirmText: "如何解决"
					}).then((res) => {
						if(res && res.confirm) {
							if(this.bluetoothStatus == BLUETOOTH_AUTHOR_REJECT) {
								this.toOpenBluetoothAdapter()
							} else {
								uni.navigateTo({
									url: `/pages/bluetooth-solution-page/bluetooth-solution-page`
								})
							}
						}
					})
					return Promise.reject()
				}).then((res) => {
					this.bluetoothStatus = BLUETOOTH_ADAPTER_AVAILABLE
					uni.showModal({
						content: "蓝牙模块初始化成功"
					})
				})
			},
			
			authorizeBluetooth: function() {
				const scope = "scope.bluetooth"
				const openSetting = () => {
					return uni.showModal({
						content: "您需要在设置中开启\"蓝牙\"选项,才可以使用蓝牙哦!",
						cancelText: "任性不去",
						confirmText: "去设置",
					}).then((res) => {
						if (res.confirm) {
							return uni.openSetting().catch((error) => {
								console.log("openSetting", error)
								return Promise.reject({
									"errMsg": "openSetting:fail system error",
									"errno": -2
								})
							}).then((res) => {
								let authSetting = res.authSetting || {}
								if (authSetting[scope]) {
									return Promise.resolve()
								} else {
									return openSetting()
								}
							})
						} else {
							return Promise.reject({
								"errMsg": "authorize:fail auth deny",
								"errno": 103
							})
						}
					})
				}
				
				const getSetting = () => {
					return uni.getSetting().catch((error) => {
						return Promise.reject({
							"errMsg": "authorize:fail system error",
							"errno": -2
						})
					}).then((res) => {
						let authSetting = res.authSetting || {}
						let keys = Object.keys(authSetting)
						
						if (keys.indexOf(scope) != -1) {
							if(!authSetting[scope]) {
								return openSetting()
							} else {
								return Promise.resolve() 
							}
						} else {
							return Promise.reject({
								"errMsg": "authorize:fail auth canceled",
								"errno": -3
							})
						}
					})
				}
				
				return uni.authorize({scope: scope}).catch((err) => {
					return getSetting()
				}).catch((err) => {
					this.bluetoothStatus = BLUETOOTH_AUTHOR_REJECT
					return Promise.reject(err)
				})
			}
		}
	}
</script>
三.蓝牙权限引导页

/pages/bluetooth-solution-page/bluetooth-solution-page页面内容如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值