- 部分安卓机型下 wx.getAppAuthorizeSetting 返回值错误
一. 机型 手机型号: HUAWEI nova 11 Pro手机系统: HarmonyOS 4.2.0二. 复现方式 (1)开启以下4个权限 手机系统对应用的设置 允许微信使用蓝牙(有的手机此项叫附近设备)手机系统对应用的设置 允许微信使用定位开关微信对小程序的设置 授权蓝牙微信对小程序的设置 授权精确地理位置(2)调用 wx.getAppAuthorizeSetting 和 wx.getSettingminiprogramAuthSetting API 并打印返回值 [图片] 在返回值中可以看到4个权限对应返回值: wx.getAppAuthorizeSetting bluetoothAuthorized (允许微信使用蓝牙的开关 未开启)wx.getAppAuthorizeSetting locationAuthorized (允许微信使用定位的开关 已开启)wx.getSettingminiprogramAuthSetting.scope.bluetooth (当前宿主小程序的用户授权结果,是否授权蓝牙 已授权)wx.getSettingminiprogramAuthSetting.scope.userLocation (当前宿主小程序的用户授权结果,是否授权精确地理位置 已授权)可以看出,手机操作系统已给微信开启蓝牙权限,但小程序 wx.getAppAuthorizeSetting 返回的 bluetoothAuthorized 是 denied, 是不对的。 (3)在当前状态执行业务逻辑 系统设置页的状态和微信小程序API调用出现了矛盾,依旧存在一种可能性:wx.getAppAuthorizeSetting 对的,系统设置页展示错误,那么继续进行蓝牙逻辑,即可知道微信使用蓝牙的权限是否真正开启了。 在当前状态下,执行了公司的蓝牙相关业务逻辑,结果是正常运行(此处不放代码和截图了,可以自行验证)。所以确定是 wx.getAppAuthorizeSetting 返回的值异常。 考虑到该错误只在特定机型下出现,猜测可能是微信小程序API对安卓底层的兼容方向出的问题。后续就无法继续排查了,要交给小程序官方了。 (4)退出小程序;关闭手机系统对微信蓝牙权限的授权开关,再重新打开; 执行这一步操作后,wx.getAppAuthorizeSetting 返回值又正常了。 此步骤4可以给广大微信小程序开发者,作为一种临时的解决手段。但用户体验较差。即便我们给了引导提示,我们的客户也没有意愿去重启手机权限,而是跟倾向于向公司投诉我们研发团队…… 三. 文档问题 wx.getAppAuthorizeSetting 其实是有两份文档的,官方回复开发者的留言里经常把文档搞混,其实正确的只有一个。 (1) 文档A 该文档属于多端能力目录下,未特指小程序,但官方引用了这部分使用范围:【仅 iOS 有效,所以返回 'undefined', Android 端可忽略】原始链接:https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/miniapp/api/diffapi/getAppAuthorizeSetting.html(2)文档B 小程序文档目录下使用范围:iOS和安卓均有效,对安卓基础库版本有限制原始链接:https://developers.weixin.qq.com/miniprogram/dev/api/base/system/wx.getAppAuthorizeSetting.html(3)结论 结合我司测试团队对多种机型多次的测试,可以确定:该API在安卓和iOS下均有效,且所有的BUG都出现在安卓机型。所以文档B是对的。 四. BUG 修复进度问题 微信官方也承认了该问题,并于2024年8月9日发布公告,称该问题在修复中。 但截止今天(2024-12-18)微信小程序官方还没有发布修复完毕的版本公告。 公告地址:https://developers.weixin.qq.com/community/develop/doc/00084ac3458228a822f17fa6d66c01?highLine=bluetoothAuthorized [图片] 五. 可复现机型 我司测试团队使用了几十种机型进行测试,在以下机型也复现了问题,此处提供给微信小程序团队,希望能帮助到官方团队更高效定位问题 华为 nova 12 Ultra (HarmonyOS版本 4.2.0.156)华为 nova 9/nova 7/nova11 seoppo reno8,reno 9oppo A2荣耀100华为 mate 60 pro一加 Ace Pro全部问题出现在安卓,并且可以锁定华为(包括荣耀)和OPPO(包括一加)两大品牌。 六. 附录 (1)附社区反馈地址,供测试复现问题和查找机型的参考: https://developers.weixin.qq.com/community/develop/doc/000a08eb204588ae03f1b21b26b400?highLine=bluetoothAuthorized https://developers.weixin.qq.com/community/develop/doc/000062204348c06eea225031e69c00?highLine=wx.getAppAuthorizeSetting https://developers.weixin.qq.com/community/develop/doc/00020c823746809591e1b18166bc00?highLine=bluetoothAuthorized (2)附官方文档接口API地址: https://developers.weixin.qq.com/miniprogram/dev/platform-capabilities/miniapp/api/diffapi/getAppAuthorizeSetting.html https://developers.weixin.qq.com/miniprogram/dev/api/base/system/wx.getAppAuthorizeSetting.html
2024-12-19 - iOS13怎么区分蓝牙的不同状态,是系统蓝牙未打开或者未授权微信蓝牙权限?
在iOS13中,蓝牙变成了和位置,通知服务等同样的可以针对单个app授权的服务。用户可以在设置中关闭微信的Bluetooth Sharing,这样即使系统蓝牙打开了,小程序仍然无法使用BLE服务。 三种情况: a.手机蓝牙未打开 b.手机蓝牙已打开,微信的蓝牙服务关闭 c.两者均打开 在目前的小程序API中,我们可以通过获取system Info来查看蓝牙是否打开(bluetoothEnabled).然而在情况a和b中,该参数均为false。这样我们无法准确提示用户去打开系统蓝牙或者打开微信的蓝牙授权了。 另一种方式是在wx.openBluetoothAdapter(Object object) 这个接口中,情况a返回的error为: {"state": 4,"errCode":10001,"errMsg":"openBluetoothAdapter:fail open fail"} 情况b返回的error为: {"state": 3,"errCode":10001,"errMsg":"openBluetoothAdapter:fail open fail"} 开发者或许可以通过这个state来区分这两种情况,但是在官方文档中并未给出state的具体定义。 我相信在iOS13中,小程序API会有所更新。希望能够补充这种state的定义,同时给出更多蓝牙的选项。 下面是iOS中关于state的定义,我猜测微信直接引用这部分定义: typedef NS_ENUM(NSInteger, CBCentralManagerState) { CBCentralManagerStateUnknown = CBManagerStateUnknown, CBCentralManagerStateResetting = CBManagerStateResetting, CBCentralManagerStateUnsupported = CBManagerStateUnsupported, CBCentralManagerStateUnauthorized = CBManagerStateUnauthorized, CBCentralManagerStatePoweredOff = CBManagerStatePoweredOff, CBCentralManagerStatePoweredOn = CBManagerStatePoweredOn, } NS_DEPRECATED(10_7, 10_13, 5_0, 10_0, "Use CBManagerState instead"); 这个问题已经有用户遇到,应该是购买的iOS13的新手机,希望能够尽早处理。
2019-11-08 - 基于加速度计判断横竖屏
也许有人会问,小程序中都是竖直app形态,要横竖屏判断有什么用?即使判断出了横屏状态,你能把小程序横过来?答案是不能的,但是判断当前设备处于横屏或者竖屏状态来实现一些友好的用户体验交互方式的需求确实存在。例如手机横屏,让视频播放自动全屏,手机竖屏,让视频切换回来小屏。 然而,截止至目前,小程序官方的API中并没有提供这样的横竖屏判断的方法。那么我们只能自己想办法实现这样的判断。小程序的设备API中提供了加速度计的监听方法,使用方法如下: [代码]wx.onAccelerometerChange([代码][代码]function[代码][代码](res) {[代码] [代码] [代码][代码]console.log(res.x)[代码] [代码] [代码][代码]console.log(res.y)[代码] [代码] [代码][代码]console.log(res.z)[代码] [代码]})[代码] 加速度计的三轴以下是一般移动设备的加速度计三轴坐标系示例图: [图片] 以手机竖直面向用户为例,加速计的三轴坐标系统的X、Y、Z轴定义如下: 沿着手机屏幕顶部向上是Y轴正方向,向下是Y轴负方向; 当手机顶部朝上时,沿着手机屏幕向右是X轴正方向,向左是X轴负方向; 正对手机时,垂直屏幕向外是Z轴正方向,垂直屏幕向里是Z轴负方向; 当手机处于静止状态时,手机此时只受一个重力加速度(1g=9.8m/s²)的作用,加速度计返回的res.x、res.y、res.z的值就是设备的三轴受到的加速度的值,取值范围从[-1g,1g]。设备以不同方式放置时,x/y/z的值如下: [图片] 计算姿态角在stackoverflow上找到了根据加速度计三轴的值计算姿态角公式(https://stackoverflow.com/questions/3755059/3d-accelerometer-calculate-the-orientation),经过结合设备的三轴坐标方向对公式进行调整,最终得出了公式: [代码]Pitch = atan2(Y, Z) * 180/M_PI;Roll = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;[代码] [代码][代码]Roll = atan2(-X, sqrt(Y*Y + Z*Z)) * 180/M_PI;[代码][代码] Roll(绕Y轴旋转的角度) 当设备绕着自身Y轴旋转时(表示手机左侧或右侧翘起的角度),该角度值将会发生变化,取值范围是-90到90度。 Pitch(绕X轴旋转的角度) 当手机绕着自身的Y轴旋转(表示手机顶部或尾部翘起的角度),该角度会发生变化,值的范围是-180到180度。 [图片] 接下来就是根据自己对横竖屏角度的观测,再结合微信小程序中,视频全屏只能以手机向左旋转方式全屏的特性,只对用户左侧横屏判断为横屏状态,实现代码片段如下: [代码] // 0为竖屏,1为横屏[代码][代码] [代码][代码]let lastState = 0;[代码][代码] [代码][代码]let lastTime = Date.now();[代码] [代码] [代码][代码]wx.startAccelerometer();[代码] [代码] [代码][代码]wx.onAccelerometerChange((res) => {[代码][代码] [代码][代码]const now = Date.now();[代码][代码] [代码] [代码] [代码][代码]// 500ms检测一次[代码][代码] [代码][代码]if[代码] [代码](now - lastTime < 500) {[代码][代码] [代码][代码]return[代码][代码];[代码][代码] [代码][代码]}[代码][代码] [代码][代码]lastTime = now;[代码] [代码] [代码][代码]let nowState;[代码] [代码] [代码][代码]// 57.3 = 180 / Math.PI[代码][代码] [代码][代码]const Roll = Math.atan2(-res.x, Math.sqrt(res.y * res.y + res.z * res.z)) * 57.3;[代码][代码] [代码][代码]const Pitch = Math.atan2(res.y, res.z) * 57.3;[代码] [代码] [代码][代码]// console.log('Roll: ' + Roll, 'Pitch: ' + Pitch)[代码] [代码] [代码][代码]// 横屏状态[代码][代码] [代码][代码]if[代码] [代码](Roll > 50) {[代码][代码] [代码][代码]if[代码] [代码]((Pitch > -180 && Pitch < -60) || (Pitch > 130)) {[代码][代码] [代码][代码]nowState = 1;[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]nowState = lastState;[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]} [代码][代码]else[代码] [代码]if[代码] [代码]((Roll > 0 && Roll < 30) || (Roll < 0 && Roll > -30)) {[代码][代码] [代码][代码]let absPitch = Math.abs(Pitch);[代码] [代码] [代码][代码]// 如果手机平躺,保持原状态不变,40容错率[代码][代码] [代码][代码]if[代码] [代码]((absPitch > 140 || absPitch < 40)) {[代码][代码] [代码][代码]nowState = lastState;[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]if[代码] [代码](Pitch < 0) { [代码][代码]/*收集竖向正立的情况*/[代码][代码] [代码][代码]nowState = 0;[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]nowState = lastState;[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码] [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]nowState = lastState;[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]// 状态变化时,触发[代码][代码] [代码][代码]if[代码] [代码](nowState !== lastState) {[代码][代码] [代码][代码]lastState = nowState;[代码][代码] [代码][代码]if[代码] [代码](nowState === 1) {[代码][代码] [代码][代码]console.log([代码][代码]'change:横屏'[代码][代码]);[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]console.log([代码][代码]'change:竖屏'[代码][代码]);[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码] [代码][代码]});[代码] 然后就可以在横竖屏切换的状态下,去切换视频的横竖屏了 [代码]if[代码] [代码](state === 1) {[代码][代码] [代码][代码]video.requestFullScreen();[代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]video.exitFullScreen();[代码][代码]}[代码] 其他 另外,在这里发现小程序的一个小bug,就是当进入一个页面,马上就调用requestFullScreen()方法去拉起视频全屏时,会破坏整个页面的布局,并且再调用全屏方法时,视频就无法再全屏了,像这样: [图片] 所以为了防止用户直接以横屏的状态进入一个视频播放页,而我们的横屏判断检测生效立即触发全屏引发bug,我将监听横竖屏的事件通过setTimeout(listener, 3000)延迟3s监听,这样横屏才不会触发bug。 最后 文中的很多知识点很多都是从网络文章学来,可能存在错误的理解,如有错误,欢迎各位指正。 最后再打个广告,欢迎喜欢看游戏直播的小伙伴来试用我们的《TG电竞》直播小程序,这里聚合各大平台的知名主播,总有一款适合你哦。 [图片]
2018-01-25