小程序重構,採用 uniapp 框架。記錄一下踩過的坑。關於用戶拒絕再次調起受權,及如何識別語音識別、微信地址、附近地址的處理。
... "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 不同。css
邏輯也是先獲取受權信息,未受權、用戶拒絕受權、受權成功,在用戶拒絕受權時,打開受權設置頁面,沒受權由小程序主動調起受權彈窗。前端
主要處理邏輯以下:vue
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的,而後進行後續處理 } } }); } }