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的,然後進行後續處理
}
}
});
}
}