在进行项目开发时,使用低功耗蓝牙进行设备对接开发;
在安卓平台多台测试机上已经测试OK,但是使用IOS平台进行测试时调用wx.notifyBLECharacteristicValueChange这个API时总是报错:
也就是服务不存在,但是serviceId是通过wx.getBLEDeviceServices获取的,所以如果有错应该安卓测试时也有错;
为了盘查问题所在,所以重新建了一个demo项目进行每一步的调用的独立测试,将获取到的deviceId,serviceId,characteristicId代入进行层别,发现依然是notifyBLECharacteristicValueChange报错10004;
所以,@微信小程序官方,是否v1.02.1907300 stable版本的小程序开发工具对IOS的部分蓝牙API不兼容,如果不兼容我该回退到什么版本比较合适?环境说明: 微信开发工具版本: v1.02.1907300 stable版本; 真机调试用机说明: 1. 机型 iphone 5 (操作系统IOS 10.0.1) 其他 iphone手机还没有尝试;
2. 机型 小米6 , nokia , vivo, oppo (Android操作系统覆盖从6.0到8.0,全部通过)
层别排查代码说明:
(1)层别排查使用的index.js:
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
motto: 'Hello World',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')
},
//事件处理函数
bindViewTap: function() {
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad: function () {
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
} else if (this.data.canIUse){
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallback = res => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
} else {
// 在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
app.globalData.userInfo = res.userInfo
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
}
},
getUserInfo: function(e) {
console.log(e)
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
},
openAdapter: function() {
wx.openBluetoothAdapter({
success: function(res) {
console.log('蓝牙适配开启成功')
},
})
},
connectBle: function() {
wx.createBLEConnection({
deviceId: 'B7F833D9-DE84-4093-8A25-B05859BFDB2A',
success: function(res) {
console.log('蓝牙连接创建成功')
},
})
},
notifyBle: function() {
wx.notifyBLECharacteristicValueChange({
deviceId: 'B7F833D9-DE84-4093-8A25-B05859BFDB2A',
serviceId: '0000FEE7-0000-1000-8000-00805F9B34FB',
characteristicId: '000036F6-0000-1000-8000-00805F9B34FB',
state: true,
success: function(res) {
console.log('蓝牙特征值监听开启成功')
},
fail: function(e) {
console.log('蓝牙特征值监听开启失败:%s', e)
console.dir(e)
}
})
},
openAdapter1: function () {
wx.openBluetoothAdapter({
success: function (res) {
console.log('蓝牙适配开启成功')
},
})
},
connectBle1: function () {
wx.createBLEConnection({
deviceId: '0C:1C:57:A8:BA:C4',
success: function (res) {
console.log('蓝牙连接创建成功')
},
})
},
notifyBle1: function () {
wx.notifyBLECharacteristicValueChange({
deviceId: '0C:1C:57:A8:BA:C4',
serviceId: '0000FEE7-0000-1000-8000-00805F9B34FB',
characteristicId: '000036F6-0000-1000-8000-00805F9B34FB',
state: true,
success: function (res) {
console.log('蓝牙特征值监听开启成功')
},
fail: function (e) {
console.log('蓝牙特征值监听开启失败:%s',e)
console.dir(e)
}
})
}
})
(2)层别排查使用的wxml:
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
<button bindtouchend="openAdapter">IOS开启蓝牙适配</button>
<button bindtouchend="connectBle">IOS创建蓝牙连接</button>
<button bindtouchend="notifyBle">IOS开启特征监听</button>
<button bindtouchend="openAdapter1">Android开启蓝牙适配</button>
<button bindtouchend="connectBle1">Android创建蓝牙连接</button>
<button bindtouchend="notifyBle1">Android开启特征监听</button>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
又是一次自问自答,IOS移动端就针对我测试使用的手机(IPhone 5s,系统IOS 10.2.1),微信小程序调用低功耗蓝牙notifyBLECharacteristicValueChange总报错errCode: 10004问题; 以下原因时本人测试通过后推测的,至于是否是根本原因有待进一步层别排查,但对于该类问题有比较典型的查考意义;
(1)原因: 蓝牙时使用要让IPhone手机自己去发现服务列表,它才会认为有这样的一个服务,否则无法调用(既是使用者已经知道正确参数也不能直接调用notifyBLECharacteristicValueChange)
(2)个人的理解:
IPhone手机内置的蓝牙控制软件进行了对已有服务进行校验,如果在使用蓝牙服务的当时没有通过wx.getBLEDeviceServices获取设备服务列表,即使之前曾经使用过wx.getBLEDeviceServices获取过对该设备蓝牙操作所需要的所有设备特征例如deviceId, serviceId, notify特征的characteristicId等等,就算是这些数值都是正确的,都是无法通过手机本身的检验,所以才一直报错 : 没有找到指定服务(errCode: 10004); 这一点IPhone的的确确没有Android做得好,原来已经做过的事情还需要重新再做一遍,并且获得的参数对于同一个设备都是一样的,浪费了大量的资源做前面的准备;
(3)总结:
IPhone的蓝牙调用必须按套路打完,既是已经知道正确调用的参数和方法,也是不能跳过中间步骤; Android的蓝牙调用只要按需取求即可,无需浪费多余资源重复相同工作;
如果希望兼容IOS和Android还是需要一整套套路打完(感觉好蠢)
我前天也遇到这个问题,不过解决了,目前我出现的问题是,
这个方法没有回执,success,fail,还是complete,都不走,
android没问题,ios就是不走,大佬知道为什么吗?
2021-11-16 问题依旧存在
麻烦提供出现问题的具体机型、微信版本号、系统版本号,以及能复现问题的代码片段(https://developers.weixin.qq.com/miniprogram/dev/devtools/minicode.html)
微信版本号:Version 7.0.5 问题机型: IPhone 5 问题手机操作系统: IOS 10.2.1 微信开发工具版本:Stable v1.02.1907300 开发机操作系统: win10 代码片段分享链接: https://developers.weixin.qq.com/s/0HYEZVmT7Sa4 问题描述: Iphone5 ios10 无法正常调用notifyBLECharacteristicValueChange总报错errCode: 10004,而安卓没有此类问题; deviceId,serviceId,characteristicId都是通过接口查询到后填充的,不代表其他人测试环境也是一样的值,请根据测试蓝牙环境进行修改;