使用AI排查鸿蒙6.0系统微信小程序获取手机号失败问题

一、问题现象

近期有反馈鸿蒙系统升级 6.0 之后海康云眸小程序登录没反应,没有任何异常现象和报错,经测试 iOS 和Android 和鸿蒙系统5.0 均可以正常登录,遂问题定位为 鸿蒙6.0 系统升级后兼容问题。

问题描述

如下图所示,小程序用户通过缓存和token去判断是否登录,登录的时候调用接口判断是否之前有授权绑定过手机号,如果绑定过直接登录即可,未绑定需要调用获取绑定手机号授权弹窗授权:
在这里插入图片描述

经反馈,问题集中出现在鸿蒙6.0系统上,未升级之前没有出现过这个问题,升级之后点击【一键登录】会正常弹出授权弹窗,点击授权手机号之后会刷新页面没有任何报错也没有下一步反应。排查代码并且在关键节点都输出了日志,iOS和有且仅有的一台纯血鸿蒙5.0 没有复现问题,Android 小伙伴说纯血的5.0和6.0区别不大,而且升级不上去6.0,最新系统更新到了5.0,测试阻塞。

最后很难得的找到了一台升级到了6.0的北京同事的手机,拜托其远程帮忙调试,排查过代码逻辑问题之后,定位到在鸿蒙6.0系统环境下,用户点击【一键登录】按钮时,调用 bindgetphonenumber 方法获取手机号失败__,且无任何报错提示信息会直接刷新页面,__导致无法完成登录流程。

具体表现

  • 用户点击【一键登录】按钮后,bindgetphonenumber 回调函数无反应
  • 用户无法正常获取手机号,登录流程中断

影响范围

  • 系统版本:鸿蒙6.0系统
  • 功能模块:登录模块(src/pages/index.mpx
  • 用户影响:使用鸿蒙6.0系统的用户无法通过一键登录功能完成登录

代码段如下:

wx:if="{{(!hasBindingPhoneNumber)&&checked}}"
      type="primary"
      size="large"
      custom-style="width: 295px;border-radius: 24rpx;"
      open-type="getPhoneNumber"
      bindgetphonenumber="bindgetphonenumber"
      >一键登录    >
    
    // js
    bindgetphonenumber(e = {}) {
        console.log('bindgetphonenumber',e)
        try{
        log.info('bindgetphonenumber - 获取加密手机号信息:', e)
        const { code } = e.detail || {}
        if (code) {
          this.login(code)
        }
        }catch(err){
          log.error('bindgetphonenumber - 获取加密手机号信息:', err)
        }
      }

参照官网:《手机号快速验证组件-使用方法》

文档标明支持鸿蒙系统,且使用方式无误,社区出现同样问题 鸿蒙6.0获取手机号失效


二、借助AI排查解决问题

在社区和官方文档以及其他渠道搜索问题出现原因,找不到明确的解决方案之后,使用 cursor 尝试解决问题,并帮忙分析问题出现原因以及后续避免手段。

改动内容说明

先让 cursor 帮忙分析有问题代码,并给出解决方案,cursor 主要改动了我原来的获取手机号的方式以及新增了一个获取隐私协议权限的按钮,具体改动点如下:

核心改动点
添加隐私授权检查机制

文件src/pages/index.mpx

改动内容

  1. 新增 refreshPrivacySetting() 方法,用于检查隐私授权状态
  2. 在页面初始化时调用隐私授权检查
  3. 根据隐私授权状态动态显示不同的登录按钮

关键代码

refreshPrivacySetting() {
  return new Promise((resolve) => {
    if (!wx.getPrivacySetting) {
      this.setData({
        privacyNeedAuthorization: false,
        privacyContractName: ''
      })
      return resolve(false)
    }
    wx.getPrivacySetting({
      success: (res) => {
        const needAuthorization = !!(res && res.needAuthorization)
        const privacyContractName = (res && res.privacyContractName) || ''
        this.setData({ privacyNeedAuthorization: needAuthorization, privacyContractName })
        resolve(needAuthorization)
      },
      fail: () => {
        this.setData({
          privacyNeedAuthorization: false,
          privacyContractName: ''
        })
        resolve(false)
      }
    })
  })
}
优化UI交互流程

改动内容

  • 根据隐私授权状态显示不同的按钮:

  • 需要隐私授权时:显示 open-type="agreePrivacyAuthorization" 的按钮

  • 不需要隐私授权时:显示 open-type="getPhoneNumber" 的按钮

  • 已绑定手机号时:显示普通登录按钮

关键代码

<button
  wx:if="{{privacyNeedAuthorization}}"
  type="primary"
  size="default"
  style="width: 295px;border-radius: 24rpx;"
  open-type="agreePrivacyAuthorization"
  bindagreeprivacyauthorization="onAgreePrivacyAuthorization"
>
  一键登录
</button>
<button
  wx:elif="{{(!hasBindingPhoneNumber)&&checked}}"
  type="primary"
  size="default"
  style="width: 295px;border-radius: 24rpx;"
  open-type="getPhoneNumber"
  bindgetphonenumber="bindgetphonenumber"
>
  一键登录
</button>
增强错误处理机制

改动内容: 在 bindgetphonenumber 方法中增加了完善的错误处理逻辑:

关键代码

bindgetphonenumber(e = {}) {
  console.log('bindgetphonenumber',e)
  try{
    log.info('bindgetphonenumber - 获取加密手机号信息:', e)
    const detail = e.detail || {}
    const { code = '', errMsg = '' } = detail
    wx.setStorageSync('phoneCode', code)

    if (code) return this.login(code)

    // 鸿蒙/新版微信:未同意微信隐私授权时可能直接拦截 getPhoneNumber
    if (errMsg && (errMsg.includes('privacy') || errMsg.includes('Privacy'))) {
      this.setData({ privacyNeedAuthorization: true })
      Toast('请先同意微信隐私授权后再获取手机号')
      return
    }
    if (errMsg && errMsg.includes('user deny')) {
      Toast('你已取消授权手机号')
      return
    }
    Toast('获取手机号失败,请重试')
  }catch(err){
    log.error('bindgetphonenumber - 获取加密手机号信息:', err)
  }
}
添加隐私授权回调处理

改动内容: 新增 onAgreePrivacyAuthorization 方法,处理隐私授权结果:

关键代码

onAgreePrivacyAuthorization(e = {}) {
  const { errMsg = '' } = (e && e.detail) || {}
  log.info('onAgreePrivacyAuthorization:', e)
  if (errMsg && errMsg.includes('fail')) {
    Toast('未同意隐私授权,无法获取手机号')
    this.setData({ privacyNeedAuthorization: true })
    return
  }
  this.setData({ privacyNeedAuthorization: false })
  Toast('已同意隐私授权,请再次点击"一键登录"')
}

AI分析问题出现原因

经过调试,意外的发现鸿蒙6.0可以正常获取手机号登录进行后续操作了,我让AI帮我分析次次问题出现的根本原因

根本原因

鸿蒙6.0系统对微信小程序的隐私保护机制进行了更严格的管控,要求在使用 getPhoneNumber 接口之前,必须先通过 agreePrivacyAuthorization 接口完成隐私授权。如果用户未完成隐私授权,系统会直接拦截 getPhoneNumber 的调用,导致 bindgetphonenumber 回调中无法获取到有效的 code

技术原因
  1. 隐私授权机制变更
  • 鸿蒙6.0系统要求在使用敏感接口(如获取手机号)前,必须先调用 wx.getPrivacySetting() 检查隐私授权状态
  • 如果 needAuthorizationtrue,必须先通过 open-type="agreePrivacyAuthorization" 完成授权
  • 未完成授权时,getPhoneNumber 接口会被系统拦截,不会返回有效的 code
  1. 原有代码缺陷
  • 原代码未检查隐私授权状态,直接调用 getPhoneNumber
  • bindgetphonenumber 方法中缺少对隐私相关错误的处理
  • 未区分不同错误场景,无法给用户明确的错误提示
  1. 错误处理不完善
  • 原代码只检查 code 是否存在,未处理 errMsg 中的错误信息
  • 缺少对隐私授权失败、用户拒绝授权等场景的处理

为什么要这么改动

AI分析:为什么要这么改动,和后续针对此类问题需要如何避免和解决方案

符合平台规范要求

鸿蒙6.0系统对隐私保护有更严格的要求,必须在使用敏感接口前完成隐私授权。改动后的代码完全符合平台规范,避免了因违反规范导致的接口调用失败。

提升用户体验
  • 明确的错误提示:当隐私授权失败或用户拒绝授权时,给用户明确的提示信息
  • 流畅的交互流程:通过分步骤的授权流程,引导用户完成隐私授权和手机号获取
  • 友好的错误处理:区分不同错误场景,提供针对性的提示信息
增强代码健壮性
  • 完善的错误处理:增加了对各类错误场景的处理,避免程序崩溃
  • 兼容性处理:通过检查 wx.getPrivacySetting 是否存在,兼容不支持该接口的旧版本
  • 日志记录:增加了详细的日志记录,便于问题排查和定位

经过AI 分析之后豁然开朗,原来鸿蒙6.0增强了微信小程序的隐私保护机制,但是社区和官方文档并没有说明,网上目前也没有明确的指出获取手机号必须要先获取隐私协议授权。接着

后期针对此类问题的解决方案

AI 给出了如下解决方案,由于示例篇幅太长且可采用价值不高,因此我删减了细节展示

  1. 建立平台兼容性检测机制
  2. 建立统一的错误处理机制
  3. 建立隐私授权管理模块
  4. 建立测试和监控机制
  5. 建立文档和知识库

三、优化AI修复后的代码

经过调试,问题是解决了,但是AI修复后的代码,在交互上并不是非常完善的,因为获取隐私协议授权和获取手机号操作必须是用户通过按钮显示的【主动触发】,也就存在一个问题,在这个页面会出现两次【一键登录】按钮,第一次获取隐私协议授权(如果之前没有获取过的话),第二次获取手机号,在交互体感上是非常不好的,因此将获取隐私协议授权的部分逻辑放在了初始化进入小程序同意隐私政策摘要页面的【同意】按钮上,之前隐私政策摘要页面的【同意】按钮只是用来确保用户看到这个页面摘要内容,并未调用微信自带的获取隐私授权接口。

如上改动,经过调试,鸿蒙6.0、Androin、iOS目前均可以正常使用小程序。


四、总结

本次借助 AI 修复针对鸿蒙6.0系统下 bindgetphonenumber 失效问题,通过添加隐私授权检查、优化错误处理、改进交互流程等方式,解决了主要问题并顺便帮我优化了原先代码,收获颇丰。但是细节问题还需要自行调试优化。

由于鸿蒙6.0新出来不久,对新系统的兼容还是会有很多问题,且网上没有很多现成的案例和解决方案,等微信官方修复鸿蒙系统问题或者给出解决方案显然不可行,尝试了很多网上给出的方案花了半个上午时间并未得到很好的解决方案之后借助AI更快速的定位到问题并分析问题原因且得到解决。

对比AI辅助排查问题大致总结了如下几点:

提高效率
  • 快速定位问题并且生成可调试代码
  • 减少查阅文档和网上检索时间(甚至网上可能目前搜不到)
  • 解释为什么做这些修改以及问题出现原因
代码质量提升
  • 自动生成可维护且符合一定编码规范的代码
  • 帮助发现之前旧代码的逻辑漏洞和潜在问题
  • 提供代码优化和后期避免出现问题建议(部分可采纳)
需结合人工调试
  • 虽然AI快速生成了高质量代码,但是基于更好的交互和小程序的特殊性,还是需要结合实际交互需求和代码规范通过各方机型进行人工调试和代码审查,以确保代码的高可维护性

之前虽然已经开发过不少微信和支付宝小程序,经过这次问题排查得出结论:小程序常看常新。小程序API往往是跟不上系统更新迭代的速度,且官方响应非常之缓慢(前年在社区提的问题被官方要走问题复现场景后迄今都没有得到回复),后续视情况而定看需不需要将登录改成由现在的【获取微信绑定的加密手机号和code】改成【输入手机号+验证码】的方式,当然这都是后话了。


Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐