uniapp 用户拒绝授权再次调起授权-语音识别、微信地址、附近地址
- 2019 年 10 月 15 日
- 笔记
小程序重构,采用 uniapp 框架。记录一下踩过的坑。关于用户拒绝再次调起授权,及如何识别语音识别、微信地址、附近地址的处理。
语音识别 组件
- 语音识别,小程序只有录音功能,若要识别录音文件,常规做法是把录音文件传递给后端,然后由后端调用百度或讯飞语音识别接口,然后返回结果。
- 但是微信小程序官方提供了“同声传译”插件,支持前端直接识别。可参考:插件介绍、插件使用文档
- uniapp 插件配置,在 manifest.json 文件中,源码模式,加入:
... "mp-weixin": { ... "plugins" : { // 语音识别 - 同声传译 "WechatSI" : { "version" : "0.3.1", "provider" : "wx069ba97219f66d99" } } }
- 调用
<template> <view @click="asrStart">语音识别</view> <view>{{arsRes}}</view> <!-- 语音识别 --> <wechat-asr ref="weixinAsr" @callback="asrResult"/> </template> <script> import WechatAsr from '@/components/wechatASR.vue'; export default { components: {WechatAsr}, data () { return { arsRes: '' } }, methods: { // 语音识别 asrStart () { this.$refs.weixinAsr.show(); }, asrResult (res) { this.arsRes = res; } } } </script>
- 编写组件,其中关于授权,用户若拒绝了,再次点击,本来是会一直进入失败的回调中,导致没法再次打开授权界面。所以先获取授权信息,针对没有授权、授权拒绝、授权成功,分别再次处理。若授权拒绝,需要打开授权设置界面,让用户再次授权处理。
<template> <!-- 微信语音识别 --> <view class="mask" v-show="isShow"> <view class="weixin-asr"> <view class="title">语音识别</view> <!-- 动画 --> <view class="spinner"> <view class="rect rect1"></view> <view class="rect rect2"></view> <view class="rect rect3"></view> <view class="rect rect4"></view> <view class="rect rect5"></view> </view> <view class="tip">说出姓名、电话和详细地址</view> <button class="btn" type="default" @click="recordStop">说完了</button> </view> </view> </template> <script> const WechatSI = requirePlugin("WechatSI"); const ASRManager = WechatSI.getRecordRecognitionManager(); export default { data () { return { isShow: false } }, onReady () { // 录音开启成功回调 ASRManager.onStart = function (res) { _this.isShow = true; } const _this = this; // 识别错误事件 ASRManager.onError = (res) => { _this.isShow = false; console.log(res.msg); } // 录音停止回调 ASRManager.onStop = function (res) { if (res && res.result) { _this.$emit('callback', res.result); } else { uni.showToast({ icon: 'none', title: '抱歉,没听到您的声音哦' }) } } }, methods: { data () { return { isShow: false, } }, show () { const _this = this; // 获取是否授权信息 uni.getSetting({ success(res) { if (res && res.authSetting && res.authSetting.hasOwnProperty('scope.record')) { if (res.authSetting['scope.record']) { start(); } else { // 拒绝授权,打开授权设置 uni.openSetting({ success() { start(); } }) } } else { start(); } } }) function start () { ASRManager.start({ lang: "zh_CN" }); } }, // 录音停止 recordStop () { this.isShow = false; ASRManager.stop(); } } } </script> <style lang="scss" scoped> .mask { position: fixed; top: 0; left: 0; z-index: 300; width: 100%; height: 100%; background: rgba(0, 0, 0, .54); } .weixin-asr { position: absolute; top: calc(50% - #{477upx / 2}); left: 0; right: 0; margin: 0 auto; width: 560upx; height: 477upx; background: #fff; text-align: center; transform: .5s ease-out .5s; .title { margin-top: 42upx; color: #000; font-size: 34upx; font-weight: 500; } .spinner { margin: 50upx; height: 100upx; } .tip { color: #787878; } .btn { margin-top: 28upx; width: 225upx; height: 82upx; background: $theme1; color: #fff; font-size: 34upx; line-height: 82upx; border-radius: 82upx; } } .spinner { text-align: center; } .spinner > .rect { background-color: #EDAA35; height: 100%; border-radius: 13upx; width: 13upx; display: inline-block; -webkit-animation: stretchdelay 1.2s infinite ease-in-out; animation: stretchdelay 1.2s infinite ease-in-out; & + .rect { margin-left: 15upx; } } .spinner .rect2 { -webkit-animation-delay: -1.1s; animation-delay: -1.1s; } .spinner .rect3 { -webkit-animation-delay: -1.0s; animation-delay: -1.0s; } .spinner .rect4 { -webkit-animation-delay: -0.9s; animation-delay: -0.9s; } .spinner .rect5 { -webkit-animation-delay: -0.8s; animation-delay: -0.8s; } @-webkit-keyframes stretchdelay { 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } 20% { -webkit-transform: scaleY(1.0) } } @keyframes stretchdelay { 0%, 40%, 100% { transform: scaleY(0.4); -webkit-transform: scaleY(0.4); } 20% { transform: scaleY(1.0); -webkit-transform: scaleY(1.0); } } </style>
微信地址、附近地址
它们的处理,和上面逻辑一样,只是调用的 api 不一样。
逻辑也是先获取授权信息,未授权、用户拒绝授权、授权成功,在用户拒绝授权时,打开授权设置页面,没授权由小程序主动调起授权弹窗。
主要处理逻辑如下:
- 微信地址
chooseAddress (type) { const _this = this; if (type === 'weixin') { // 处理拒绝再次打开调用设置 uni.getSetting({ success (res) { if (res && res.authSetting && res.authSetting.hasOwnProperty('scope.address')) { if (res.authSetting['scope.address']) { choose(); } else { uni.openSetting({ success () { choose(); } }) } } else { choose(); } } }); function choose () { uni.chooseAddress({ success(res) { if (res) { // 调用接口将省市区转换成项目需要的,带id的,然后进行后续处理 } } }) } } }
- 附近地址
nearAddress () { const _this = this; // 处理拒绝再次打开调用设置 uni.getSetting({ success (res) { if (res && res.authSetting && res.authSetting.hasOwnProperty('scope.userLocation')) { if (res.authSetting['scope.userLocation']) { chooseLocation(); } else { uni.openSetting({ success () { chooseLocation(); } }) } } else { chooseLocation(); } } }) function chooseLocation () { uni.chooseLocation({ success: function (res) { if (res) { // 调用接口将省市区转换成项目需要的,带id的,然后进行后续处理 } } }); } }