- 『隐私设置』小程序如何设置隐私保护权限接口,防止线上登录失败,点击按钮没反应
很多用户突然遇到线上版本报错、登录失败、点击没有反应等等情况,其实都是由于最近隐私协议生效了的原因,需要按照以下步骤自行设置更新一下隐私协议,然后提交版本重新发版。 一、设置《小程序用户隐私保护指引》 开发者需登录小程序后台https://mp.weixin.qq.com/,在左侧菜单底部“设置”里找到 “服务内容声明“,在这里更新《用户隐私保护指引》。 注意:需要把用到的隐私接口都加上,提交后是需要审核的,通过才可以测试用,大约2-5个小时左右就会有结果,隐私接口可参考: https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/miniprogram-intro.html [图片] [图片] 二、填写《小程序用户隐私保护指引》 [图片] 注意:上述第一条里需要把用到的隐私接口都加上才管用,点击没反应用不了都是因为缺了 提交后是需要审核的,大约2-5个小时左右就会有结果,隐私接口可参考: https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/miniprogram-intro.html 审核通过后也不是立马生效的,会根据用户的使用情况慢慢覆盖所有用户,所以通过后耐心等待30分钟到1个小时之后再尝试,如果还不行,大概率配置的接口拉下了。 还有一点很重要,下边最后一条: 三、如要进行代码提审,需要勾选 “采集用户隐私” [图片] 很多人遇到隐私接口审核通过了,还是不能用的情况,一是需要等待1个小时左右覆盖到你才可以用,二是以下介绍的: 如果之前发版没有勾选这个《采集用户隐私》,即使隐私协议接口审核通过了,也是不能正常调用的,这时候需要你重新提交代码审核发布一版了,记得勾选这个采集用户隐私。 最好是隐私接口审核通过后,用开发者工具自己多测测,没问题再提交版本审核,开发者工具里“清除授权数据”就会重置隐私接口权限。
2023-11-04 - 为什么图片链接可正常访问但image组件加载不出来图片?
因为 image 控件的图片拉取本质上是 web 上的 backgroundImage,很多时候是由于图片不规范(content-type / length / 是否302跳转等 )导致拉取不成功,最终表现为加载不出图片。关于这一块我们在持续优化中
2021-12-17 - 小程序性能优化实践
小程序性能优化课程基于实际开发场景,由资深开发者分享小程序性能优化的各项能力及应用实践,提升小程序性能表现,满足用户体验。
2024-10-09 - 微信小程序使用科大讯飞语音评测,保姆级教程!
最近微信小程序项目中,需要添加语音评测功能,就选用了科大讯飞的语音评测流式版接口,但在使用过程中,遇到了很多问题,再网上搜资料,搜了好多,也没直接能用的,好在后来参考了许多资料后,终于调试成功了,接下来,跟大家分享一下我是怎么处理的。 1.第一步,准备所用到的工具,下载官方jsdemo,将 base64js 文件复制到自己的小程序项目中,用npm安装crypto-js xmldom这2个工具 然后,将工具导入到页面中 const CryptoJS = require('crypto-js') const Base64 = require('../../tools/base64js').Base64; var DOMParser = require('xmldom').DOMParser; 2.第二步,初始化用到的变量,定义用到的关键函数 const APPID = '替换成你自己的' const API_SECRET = '替换成你自己的' const API_KEY = '替换成你自己的' let audioData = [] //存储音频流的数组 let socketTask = null //小程序的socketTask let handlerInterval = null // 定时器,用来定时发送数据流 function getWebSocketUrl() {//生成socket使用的url return new Promise((resolve, reject) => { var url = 'wss://ise-api.xfyun.cn/v2/open-ise' var host = 'ise-api.xfyun.cn' var apiKey = API_KEY var apiSecret = API_SECRET var date = new Date().toGMTString() var algorithm = 'hmac-sha256' var headers = 'host date request-line' var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/open-ise HTTP/1.1` var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret) var signature = CryptoJS.enc.Base64.stringify(signatureSha) var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"` var authorization =Base64.encode(authorizationOrigin) url = `${url}?authorization=${authorization}&date=${date}&host=${host}` resolve(url) }) } 3.开始录音 //开始录音 startVoiceRecord(){ let that = this that.setData({recordState:'recording'}) recorderManager.onStart(() => { console.log('recorder start') }) recorderManager.onPause(() => { console.log('recorder pause') }) recorderManager.onStop((res) => { console.log('recorder stop', res) const { tempFilePath } = res that.startUpRecord()//录音完成,准备调用讯飞接口 }) recorderManager.onFrameRecorded((res) => { const { frameBuffer } = res console.log('frameBuffer.byteLength', frameBuffer.byteLength) let u8Arr = new Uint8Array(frameBuffer) audioData.push(u8Arr) //将每一帧的数据取出,放到audioData中,准备使用 }) const options = { duration: 180000, sampleRate: 16000, numberOfChannels: 1, encodeBitRate: 44100, frameSize: 2, format: 'pcm', } recorderManager.start(options) }, 4. 开始socket连接,准备上传数据并处理 startUpRecord(){ let that = this getWebSocketUrl().then(( url)=>{ let newURL = encodeURI(url) socketTask = wx.connectSocket({ url: newURL, }) socketTask.onOpen(()=>{ console.log('打开了socket') that.webSocketSend() }) socketTask.onMessage((e)=>{ // result 在这里做信息处理 console.log('收到了结果:',e) that.result(e.data) }) socketTask.onError((err)=>{ //结束录音 console.log('socket 出错:',err) }) socketTask.onClose(()=>{ // 结束录音 console.log('socket 关闭:') }) }) }, webSocketSend() { console.log('开始发送数据',audioData) let that = this let audioDataUp = audioData.splice(0, 1) var params = { common: { app_id:APPID, }, business: { category: 'read_sentence', // read_syllable/单字朗读,汉语专有 read_word/词语朗读 read_sentence/句子朗读 https://www.xfyun.cn/doc/Ise/IseAPI.html#%E6%8E%A5%E5%8F%A3%E8%B0%83%E7%94%A8%E6%B5%81%E7%A8%8B rstcd: 'utf8', group: 'pupil', sub: 'ise', ent: 'cn_vip', tte: 'utf-8', cmd: 'ssb', auf: 'audio/L16;rate=16000', aus: 1, aue: 'raw', text: '\uFEFF' + '今天天气怎么样?' }, data: { status: 0, encoding: 'raw', data_type: 1, data: that.toBase64(audioDataUp[0]), }, } console.log(JSON.stringify(params)) socketTask.send({data: JSON.stringify(params)}) handlerInterval = setInterval(() => { // websocket未连接 if (!socketTask) { clearInterval(handlerInterval) return } // 最后一帧 if (audioData.length === 0) { console.log('数据发送完毕') socketTask.send( {data: JSON.stringify({ business: { cmd: 'auw', aus: 4, aue: 'raw' }, data: { status: 2, encoding: 'raw', data_type: 1, data: '', }, })} ) audioData = [] clearInterval(handlerInterval) return false } audioDataUp = audioData.splice(0, 1) // 中间帧 console.log('audioDataUp:',audioDataUp[0]) socketTask.send( { data: JSON.stringify({ business: { cmd: 'auw', aus: 2, aue: 'raw' }, data: { status: 1, encoding: 'raw', data_type: 1, data: that.toBase64(audioDataUp[0]), }, })} ) }, 40) }, result(resultData) { // 识别结束 let jsonData = JSON.parse(resultData) if (jsonData.data && jsonData.data.data) { let data = Base64.decode(jsonData.data.data) const doc=new DOMParser().parseFromString(data,'text/xml'); let sentence = doc.getElementsByTagName('read_sentence')[1] let accuracy_score = sentence.getAttribute('accuracy_score') let emotion_score = sentence.getAttribute('emotion_score') let fluency_score = sentence.getAttribute('fluency_score') let total_score = sentence.getAttribute('total_score') let integrity_score = sentence.getAttribute('integrity_score') let phone_score = sentence.getAttribute('phone_score') let tone_score = sentence.getAttribute('tone_score') let is_rejected = sentence.getAttribute('is_rejected') console.log('parseRes:',accuracy_score,emotion_score,fluency_score,total_score) //评测结果在这里,就出来了,然后就可以拿评测数据去使用了 } if (jsonData.code === 0 && jsonData.data.status === 2) { // 在这里结束socket socketTask.close() } if (jsonData.code !== 0) { socketTask.close() console.log(`${jsonData.code}:${jsonData.message}`) } }, 到这里,整个流程就完了,祝愿大家都能一次调用成功,有什么问题的话,咱们再讨论!
2023-06-13 - 小程序 RecorderManager 录制的录音文件存在快进、播放倍速问题
最近经用户反馈发现:录音完成后,播放回放的录音文件存在被快进、倍速播放的情况 通过日志和对比recorderManager录制源文件发现,通过recorderManager录制完成的源文件时长duration会出现比本地计时要短的情况,这种情况下播放录音内容被严重快进倍速播放,无法听清内容 以下为几个日志记录的本地计时和recorderManager返回的文件时长duration对比的例子,实际去听文件确实存在快进、被倍速播放的情况 [图片] [图片] [图片] 可以发现出现问题和录音时长没有明显关联,录音时间长短都有可能出现文件快进的情况 再通过查询近6天出现这些情况的用户的机型和微信信息: 用户设备集中在小米品牌 Xiaomi、Redmi 2种 6.10日更新:出现问题的用户设备不止小米品牌,新排查到存在vivo、华为机型 小程序基础库版本为2.24.1、2.24.2 这个问题无法稳定复现,无法稳定复现,无法稳定复现,没有可稳定复现的代码片段提供。 同一个用户,同一手机,在一段时间内多次上传录音不是必现该问题,也有可能是正常的。但确实会存在不可预计的某次录音文件出现倍速播放的问题 现在需要官方帮忙解答,为什么会出现这种问题,以及作为开发者如何解决? 提供一个出现该问题的用户的系统信息 Model:Mi 10 Pro brand:Xiaomi screen_dpi:2 Name:Android Version:12 SDKVersion:2.24.1 app:wechat fontSizeSetting:16 language:zh_CN platform:android screenHeight:835 screenWidth:393 statusBarHeight:33 version:8.0.22 windowHeight:756 windowWidth:393
2022-06-10