歷經波折三次成功上岸!
三次經歷簡單絮叨一下:使用uniApp+vue開發的微信小程序,使用藍牙連接打印機,藍牙所有的接口都是插件中封裝的,用的插件市場中的這個: dothan-lpapi-ble ;所以,開發中,主要是看插件文檔中使用的API。
首次上線
情況說明: 首次上線微信小程序:直接初始化實例,調用的插件API,測試環境成功連接打印,就上線了。
結果:
客戶手機一直搜索不到打印機,根據經驗發現沒執行實例的代碼;
想到授權藍牙也沒自動彈框提示,小程序設置中也沒有藍牙開啟設置;
問題定位:
那就問 deepseeek 開干唄!
1. 可能是用戶手機 鴻蒙系統 問題:在系統設置中找到應用管理,找到微信,然后打開微信的權限管理,查看 附近設備的權限 - 開啟(反復開關)。
2. 顯示授權:必要的權限聲明
3. 檢查manifest.json配置
4. 微信小程序發版后臺 - 設置 - 基本設置 - 服務內容聲明 - 用戶隱私保護指引 - 添加(藍牙、微信信息收集)
二次上線
情況說明: 二次上線微信小程序:提交審核是其他同事在做,正常提交
結果:
客戶手機一直搜索不到打印機,根據經驗發現沒執行實例的代碼;
線上環境用戶還是沒有觸發授權藍牙、位置信息提示;
審核沒通過
問題定位:
1. 提交審核時勾選了:未采集用戶隱私
2. 親自提審、加圖片、視頻輔佐
三次上線
情況說明:審核通過
結果:
線上成功授權、成功搜索打印機!
成功版本代碼
manifest.json配置
"mp-weixin": {"appid": "...",// 添加..."permission": {"scope.bluetooth": {"desc": "用于連接藍牙設備"},"scope.userLocation": {"desc": "你的位置信息將用于藍牙設備連接"}},"requiredPrivateInfos": ["getLocation"]},
授權提示 - deepseek友情提供
// 使用-獲取藍牙權限
await this.bringBluetoothRight();// 方法 methods:
bringBluetoothRight() {let _this = this;return new Promise((resolve, reject) => {uni.getSetting({success: async (res) => {try {console.log(res, 'res')// 1. 同時檢查藍牙和位置權限const needBluetooth = !res.authSetting['scope.bluetooth'];const needLocation = !res.authSetting['scope.userLocation'];if (!needBluetooth && !needLocation) {// 已有全部權限return resolve(await _this.wechatBluetoothAuthUtils());}// 2. 顯示預授權提示(合并說明)await _this.showPreAuthorizeModal('需要藍牙和位置權限','連接打印機需要以下權限:\n\n1. 藍牙權限 - 用于設備配對\n2. 位置權限 - 用于搜索設備');// 3. 按順序請求權限if (needBluetooth) {await _this.requestPermission('scope.bluetooth', '藍牙');}if (needLocation) {await _this.requestPermission('scope.userLocation', '位置');}// 4. 驗證權限獲取結果const currentSettings = await _this.getSettingWithRetry();console.log(currentSettings, 'currentSettings')if ((!needBluetooth || currentSettings['scope.bluetooth']) &&(!needLocation || currentSettings['scope.userLocation'])) {console.log('.......')resolve(await _this.wechatBluetoothAuthUtils());} else {console.log('1111111')// 5. 有權限未被授予,引導去設置頁await _this.showGoSettingModal();const finalSettings = await _this.getSettingWithRetry();if ((!needBluetooth || finalSettings['scope.bluetooth']) &&(!needLocation || finalSettings['scope.userLocation'])) {resolve(await _this.wechatBluetoothAuthUtils());} else {reject(new Error('權限未完全授予'));}}} catch (error) {reject(error);}},fail: reject});});
},
// 新增:帶重試的獲取設置
getSettingWithRetry(retry = 2) {return new Promise((resolve, reject) => {const tryGet = (attempt) => {uni.getSetting({success: resolve,fail: attempt > 0 ?() => setTimeout(() => tryGet(attempt - 1), 500) : reject});};tryGet(retry);});
},// 改進:通用權限請求方法
requestPermission(scope, permissionName) {let _this = this;// 添加最大重試次數控制const MAX_RETRY = 1; // 最多重試1次(即總共2次機會)return new Promise((resolve, reject) => {const tryAuthorize = (retryCount = 0) => {uni.authorize({scope,success: resolve,fail: async () => {// 第一次拒絕時顯示提示,后續直接引導去設置頁if (retryCount < MAX_RETRY) {const confirmed = await _this.showPreAuthorizeModal(`${permissionName}權限被拒絕`,`需要${permissionName}權限才能連接打印機,是否重新授權?`,'重新授權','取消');if (confirmed) {tryAuthorize(retryCount + 1); // 增加重試計數return;}}// 達到最大重試或用戶取消,引導去設置頁const goSetting = await _this.showPreAuthorizeModal('權限不足',`需要${permissionName}權限才能使用打印機功能,是否去設置頁開啟?`,'去設置','暫不開啟');if (goSetting) {uni.openSetting({success: (res) => {res.authSetting[scope] ? resolve() :reject(new Error(`用戶未授權${permissionName}權限`));},fail: () => reject(new Error('打開設置頁失敗'))});} else {reject(new Error(`用戶取消${permissionName}權限授權`));}}});};tryAuthorize(); // 開始首次授權嘗試});
},
// 改進:預授權彈窗(返回Promise<boolean>)
showPreAuthorizeModal(title, content) {return new Promise((resolve) => {uni.showModal({title,content,confirmText: '繼續',cancelText: '取消',success: (res) => {resolve(!!res.confirm);},fail: () => resolve(false)});});
},// 改進:去設置頁彈窗
showGoSettingModal() {return this.showPreAuthorizeModal('需要權限','需要前往設置頁手動開啟權限,是否現在去設置?').then((confirm) => {if (confirm) {return new Promise((resolve) => {uni.openSetting({success: resolve,fail: resolve});});}return Promise.reject(new Error('用戶取消設置'));});
},wechatBluetoothAuthUtils() {let _this = this;const {bluetoothEnabled,platform} = uni.getSystemInfoSync();console.log(bluetoothEnabled,platform)// 設備為IOS時,微信藍牙是否開啟if (platform === 'ios') {return new Promise((resolve, reject) => {// 初始化藍牙模塊(用openBluetoothAdapter 方法解決部分ios設備,授權藍牙失敗的問題)uni.openBluetoothAdapter({success: () => {// 開啟藍牙功能 =》 初始化拾果sdkresolve(true);},fail: (openBlueFail) => {if (openBlueFail.state === 3) {// 說明微信應用藍牙未授權uni.showModal({content: '檢測到您未允許微信訪問手機藍牙權限,是否打開系統設置?',showCancel: false,confirmText: '前往設置',success: () => {// 跳轉微信應用權限uni.openAppAuthorizeSetting();},});} else if (openBlueFail.state === 4) {// 說明系統藍牙未開啟uni.showModal({content: '藍牙設置 - 小程序需要通過藍牙搜索和連接設備,請確認手機藍牙功能是否已開啟?',showCancel: false,confirmText: '我已開啟',success: async () => {const {bluetoothEnabled,platform} = uni.getSystemInfoSync();if (bluetoothEnabled) {// 開啟藍牙功能resolve(true);} else {uni.showToast({icon: 'none',title: '手機藍牙未開啟'})}},});}},});});} else {return new Promise(function(resolve, reject) {// andriodif (!bluetoothEnabled) {// 說明系統藍牙未開啟uni.showModal({content: '藍牙設置 - 小程序需要通過藍牙搜索和連接設備,請確認手機藍牙功能是否已開啟?',showCancel: false,confirmText: '我已開啟',success: async () => {const {bluetoothEnabled,platform} = uni.getSystemInfoSync();if (bluetoothEnabled) {// 開啟藍牙功能resolve(true);} else {toast({title: '手機藍牙未開啟'});}},});} else {// 開啟藍牙功能resolve(true);}});}
},
額外關閉提示:
<button class="search-btn" type="default" @click="toggleLocationTracking">{{ isTrackingLocation ? '關閉位置追蹤' : '開啟位置追蹤' }}</button>// data
isTrackingLocation:false// methods
toggleLocationTracking() {if (this.isTrackingLocation) {this.stopLocationTracking();} else {this.startLocationTracking();}},
startLocationTracking() {uni.authorize({scope: 'scope.userLocation',success: () => {this.isTrackingLocation = true;uni.showToast({title: '已開啟位置服務',icon: 'success'});},fail: () => {uni.showModal({title: '提示',content: '需要位置權限才能搜索藍牙設備',confirmText: '去設置',success: (res) => {if (res.confirm) uni.openSetting();}});}});},
stopLocationTracking() {uni.getSetting({success: (res) => {if (res.authSetting['scope.userLocation']) {uni.showModal({title: '確認',content: '確定要關閉位置服務嗎?關閉后將無法搜索新設備',success: (res) => {if (res.confirm) {// 實際微信小程序無法直接關閉權限,引導用戶去設置頁uni.openSetting({success: () => {this.isTrackingLocation = false;}});}}});}}});},