From afa624ae9ce70de85c1cd7f1f60e3aba6b8f2d7b Mon Sep 17 00:00:00 2001 From: unknown <331404948@qq.com> Date: Wed, 20 Nov 2024 17:13:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8D=8E=E4=B8=BA=E7=9A=84=E5=AE=A1=E6=A0=B8?= =?UTF-8?q?=E5=87=86=E5=A4=87=E6=8D=A2=E6=8F=92=E4=BB=B6=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 46 ++++- components/callPhone/callPhone.vue | 7 +- config/api.js | 4 +- config/site.config.js | 2 +- config/utils.js | 12 +- manifest.json | 12 +- .../consult/pubComplaint/pubComplaint.vue | 8 +- pages/indexEntry/consult/pubConsult/pubConsult.vue | 9 +- pages/indexEntry/signIn/signAndOut/signAndOut.vue | 7 +- .../signIn/signAndOut/signAndOutSubjiect1.vue | 7 +- pages/indexEntry/signIn/signIn.vue | 27 ++- pages/indexEntry/theory/theory.vue | 27 ++- pages/indexEntry/theory/webView.vue | 8 +- pages/mineEntry/personaInfo/personaInfo.vue | 6 +- pages/tabbar/index/comp/schoolItem.vue | 6 +- pages/tabbar/index/index.vue | 24 +-- pages/tabbar/mine/index.vue | 7 +- store/index.js | 3 + store/modules/permissionToast.js | 230 +++++++++++++++++++++ store/modules/user.js | 50 +++-- .../uni-registerRequestPermissionTips/changelog.md | 8 + .../uni-registerRequestPermissionTips/package.json | 115 +++++++++++ .../uni-registerRequestPermissionTips/readme.md | 95 +++++++++ .../utssdk/app-android/AndroidManifest.xml | 3 + .../utssdk/app-android/config.json | 3 + .../utssdk/app-android/index.uts | 148 +++++++++++++ .../app-android/res/anim/popupwindow_enter.xml | 6 + .../app-android/res/anim/popupwindow_exit.xml | 5 + .../res/drawable/dcloud_permission_background.xml | 6 + .../utssdk/interface.uts | 19 ++ 30 files changed, 830 insertions(+), 80 deletions(-) create mode 100644 store/modules/permissionToast.js create mode 100644 uni_modules/uni-registerRequestPermissionTips/changelog.md create mode 100644 uni_modules/uni-registerRequestPermissionTips/package.json create mode 100644 uni_modules/uni-registerRequestPermissionTips/readme.md create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/AndroidManifest.xml create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/config.json create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/index.uts create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_enter.xml create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_exit.xml create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/drawable/dcloud_permission_background.xml create mode 100644 uni_modules/uni-registerRequestPermissionTips/utssdk/interface.uts diff --git a/App.vue b/App.vue index b7afa91..f5a8559 100644 --- a/App.vue +++ b/App.vue @@ -1,10 +1,44 @@ diff --git a/components/callPhone/callPhone.vue b/components/callPhone/callPhone.vue index d9abb63..991a64e 100644 --- a/components/callPhone/callPhone.vue +++ b/components/callPhone/callPhone.vue @@ -26,10 +26,15 @@ show=true } }, - callPhoneClick(item) { + async callPhoneClick(item) { let phone = item.name // #ifdef APP-PLUS + /* #ifdef APP-PLUS */ + let result = await this.$store.dispatch("requestPermissions",'CALL_PHONE',) + if (result !== 1) return + + /* #endif */ this.$u.utils.callPhone(phone) // #endif diff --git a/config/api.js b/config/api.js index f7d9be4..dc43397 100644 --- a/config/api.js +++ b/config/api.js @@ -161,9 +161,9 @@ export const signOutAuth = (data) => http.post('business/student/sign/outAuth', // 签退 export const signOut = (data) => http.post('business/student/sign/out', data) // 学员扫码签到前置校验——理科 -export const vailStudentSignSubject1 = (data) => http.post('business/student/theorySign/before_in', data) +export const vailStudentSignSubject1 = (data) => http.post('business/student/theorySign/before_in', data, {custom: {catch: true, toast: false }}) // 学员扫码签退前置校验——理科 -export const vailStudentSignOutSubject1 = (data) => http.post('business/student/theorySign/before_out', data) +export const vailStudentSignOutSubject1 = (data) => http.post('business/student/theorySign/before_out', data, {custom: {catch: true, toast: false }}) // 学员扫码签到—理科 export const theorySignSubject1 = (data) => http.post('business/student/theorySign/in', data) // 学员扫码签退 -- 签退不做人脸—理科 diff --git a/config/site.config.js b/config/site.config.js index 75b27f6..07da70f 100644 --- a/config/site.config.js +++ b/config/site.config.js @@ -15,6 +15,6 @@ module.exports = { // http://123.6.232.1:8099/测试地址 -// http://192.168.1.43:8318/本地地址 +// http://192.168.1.106:8318//本地地址 //http://www.lyjppt.com/正式地址 diff --git a/config/utils.js b/config/utils.js index e285081..9264bad 100644 --- a/config/utils.js +++ b/config/utils.js @@ -166,8 +166,18 @@ export function uploadImgApi(filePath, imgName, imgLink='image') { }) } - export function scanCodeFn(_this) { + export async function scanCodeFn(_this) { + /* #ifdef APP-PLUS */ + let result2 = await store.dispatch("requestPermissions",'CAMERA',) + if (result2 !== 1) return + let result = await store.dispatch("requestPermissions",'WRITE_EXTERNAL_STORAGE',) + if (result !== 1) return + + /* #endif */ + console.log('就这样吧') + // return uni.scanCode({ + hideAlbum: true, scanType: ['qrCode'], success: function(res) { console.log('条码类型:' + res.scanType); diff --git a/manifest.json b/manifest.json index 58b3f00..dafc203 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "name" : "洛阳学车", "appid" : "__UNI__3347C6E", "description" : "", - "versionName" : "1.4.5", - "versionCode" : 145, + "versionName" : "1.4.6", + "versionCode" : 146, "transformPx" : false, /* 5+App特有相关 */ "app-plus" : { @@ -93,9 +93,9 @@ "ad" : {}, "maps" : { "amap" : { + "name" : "amapOV4nNDfa", "appkey_ios" : "2839b2b14fdcd2983e0d6247ce9baf7a", - "appkey_android" : "3c5fcc5ee6aaba56e4806f3382399c16", - "name" : "amapOV4nNDfa" + "appkey_android" : "3c5fcc5ee6aaba56e4806f3382399c16" } }, "geolocation" : { @@ -229,9 +229,9 @@ "disableHostCheck" : true, "proxy" : { "/api" : { - // "target" : "http://www.lyjppt.com/", + "target" : "http://www.lyjppt.com/", // "target" : "http://123.6.232.1:8099/", - "target" : "http://192.168.1.106:8318/", + // "target" : "http://192.168.1.106:8318/", "changeOrigin" : true, "secure" : true, "pathRewrite" : { diff --git a/pages/indexEntry/consult/pubComplaint/pubComplaint.vue b/pages/indexEntry/consult/pubComplaint/pubComplaint.vue index 81635eb..c46ff36 100644 --- a/pages/indexEntry/consult/pubComplaint/pubComplaint.vue +++ b/pages/indexEntry/consult/pubComplaint/pubComplaint.vue @@ -186,7 +186,13 @@ this.imgArr.splice(index, 1) }, //选择图片 - chooseImages(type) { + async chooseImages(type) { + /* #ifdef APP-PLUS */ + let result2 = await this.$store.dispatch("requestPermissions",'CAMERA',) + if (result2 !== 1) return + let result = await this.$store.dispatch("requestPermissions",'WRITE_EXTERNAL_STORAGE',) + if (result !== 1) return + /* #endif */ let imgNum = 3 - (this.imgArr.length) uni.chooseImage({ count: imgNum, //允许选择的数量 diff --git a/pages/indexEntry/consult/pubConsult/pubConsult.vue b/pages/indexEntry/consult/pubConsult/pubConsult.vue index 431f032..e7b485f 100644 --- a/pages/indexEntry/consult/pubConsult/pubConsult.vue +++ b/pages/indexEntry/consult/pubConsult/pubConsult.vue @@ -81,7 +81,14 @@ this.imgArr.splice(index, 1) }, //选择图片 - chooseImages(type) { + async chooseImages(type) { + /* #ifdef APP-PLUS */ + // let result2 = await this.$store.dispatch("requestPermissions",'CAMERA',) + // if (result2 !== 1) return + // let result = await this.$store.dispatch("requestPermissions",'WRITE_EXTERNAL_STORAGE',) + // if (result !== 1) return + + /* #endif */ let imgNum = 3 - (this.imgArr.length) uni.chooseImage({ count: imgNum, //允许选择的数量 diff --git a/pages/indexEntry/signIn/signAndOut/signAndOut.vue b/pages/indexEntry/signIn/signAndOut/signAndOut.vue index 7efa510..b76866f 100644 --- a/pages/indexEntry/signIn/signAndOut/signAndOut.vue +++ b/pages/indexEntry/signIn/signAndOut/signAndOut.vue @@ -24,7 +24,7 @@ 信息认证 - 失败原因:{{stepFailureReason}} + 失败原因:{{stepFailureReason}} {{step1?'通过': '不通过'}} @@ -109,7 +109,10 @@ } console.log('扫码传的参数') console.log(this.params) - const res = await fn(this.params) + const res = await fn(this.params).catch((err)=>{ + console.log(err,'出错了') + this.stepFailureReason = err.msg + }) console.log('第一步校验信息') console.log(res) console.log(res.msg) diff --git a/pages/indexEntry/signIn/signAndOut/signAndOutSubjiect1.vue b/pages/indexEntry/signIn/signAndOut/signAndOutSubjiect1.vue index 5228bba..66d993d 100644 --- a/pages/indexEntry/signIn/signAndOut/signAndOutSubjiect1.vue +++ b/pages/indexEntry/signIn/signAndOut/signAndOutSubjiect1.vue @@ -24,7 +24,7 @@ 信息认证 - 失败原因:{{stepFailureReason}} + 失败原因:{{stepFailureReason}} {{step1?'通过': '不通过'}} @@ -109,7 +109,10 @@ } console.log('扫码传的参数') console.log(this.params) - const res = await fn(this.params) + const res = await fn(this.params).catch((err)=>{ + console.log(err,'出错了') + this.stepFailureReason = err.msg + }) console.log('第一步校验信息') console.log(res) console.log(res.msg) diff --git a/pages/indexEntry/signIn/signIn.vue b/pages/indexEntry/signIn/signIn.vue index b0bb9f0..e2d1e8c 100644 --- a/pages/indexEntry/signIn/signIn.vue +++ b/pages/indexEntry/signIn/signIn.vue @@ -11,13 +11,14 @@ + diff --git a/pages/mineEntry/personaInfo/personaInfo.vue b/pages/mineEntry/personaInfo/personaInfo.vue index 996dcb1..6563439 100644 --- a/pages/mineEntry/personaInfo/personaInfo.vue +++ b/pages/mineEntry/personaInfo/personaInfo.vue @@ -13,7 +13,7 @@ 手机号 - {{ vuex_userInfo.phone }} + {{ showPhone(vuex_userInfo.phone) }} @@ -92,6 +92,10 @@ }, methods: { + showPhone(phone) { + if(!phone) return '' + return phone.substr(0, 3)+'****'+phone.substr(7) + }, // 修改头像申请 async avatarApplyFn() { const res = await avatarApply({avatarImg: this.photoPath}) diff --git a/pages/tabbar/index/comp/schoolItem.vue b/pages/tabbar/index/comp/schoolItem.vue index 9b68806..5019104 100644 --- a/pages/tabbar/index/comp/schoolItem.vue +++ b/pages/tabbar/index/comp/schoolItem.vue @@ -22,7 +22,7 @@ - {{item.districtName}} 距您{{ $u.utils.distanceFn(item.distance)}} + {{item.districtName}}距您{{ $u.utils.distanceFn(item.distance)}} @@ -48,8 +48,8 @@ methods: { imgError() { delete this.item.schoolIntroduceDO.iconPath - console.log('这图片有问题') - // this.$forceUpdate() + console.log('这图片有问题', this.item.schoolIntroduceDO.iconPath) + this.$forceUpdate() } } } diff --git a/pages/tabbar/index/index.vue b/pages/tabbar/index/index.vue index bd02522..1798fcf 100644 --- a/pages/tabbar/index/index.vue +++ b/pages/tabbar/index/index.vue @@ -69,7 +69,7 @@ - 推荐教练 + 找教练 @@ -166,11 +166,11 @@ icon: require('../../../static/images/indexIcon/entryIcon (5).png'), url: '/pages/indexEntry/signIn/signIn', }, - // { - // text: '理论学习', - // icon: require('../../../static/images/indexIcon/entryIcon (2).png'), - // url: '/pages/indexEntry/theory/theory', - // }, + { + text: '理论学习', + icon: require('../../../static/images/indexIcon/entryIcon (2).png'), + url: '/pages/indexEntry/theory/theory', + }, ], swiperDotIndex: 0, @@ -236,9 +236,7 @@ methods: { async getLatLngFn() { - uni.showLoading({ - title: '正在更新位置...' - }) + await this.$store.dispatch('getCity') this.recommendSchoolList() }, @@ -258,9 +256,9 @@ await this.getarticleListFn() await this.getRecommendList() await this.recommendSchoolList() - this.$nextTick(()=>{uni.hideLoading()}) + uni.hideLoading() }catch(e){ - this.$nextTick(()=>{uni.hideLoading()}) + uni.hideLoading() } @@ -282,8 +280,6 @@ // } this.lat = this.vuex_cityInfo.lat const {data: res} = await recommendSchoolList({pageNo:1,pageSize: 20, lat: this.vuex_cityInfo.lat||'34.682945', lng: this.vuex_cityInfo.lng||'112.477298'}) - res[8].schoolIntroduceDO.iconPath = '' - res[9].schoolIntroduceDO.iconPath = '' this.recommendSchool = Object.freeze(res) // this.recommendSchool = res // console.log(res) @@ -301,7 +297,7 @@ this.$store.commit('updateSchool', {}) return this.$u.utils.clickSignUp() }else if(item.text=='签到签退') { - // if(this.vuex_userInfo.applyStep<6) return this.$u.toast('请先报名学员') + if(this.vuex_userInfo.applyStep<6) return this.$u.toast('请先报名学员') } this.$goPage(item.url) }, diff --git a/pages/tabbar/mine/index.vue b/pages/tabbar/mine/index.vue index 7214a75..050f967 100644 --- a/pages/tabbar/mine/index.vue +++ b/pages/tabbar/mine/index.vue @@ -11,7 +11,7 @@ - {{ vuex_userInfo.name?vuex_userInfo.name:vuex_userInfo.phone?vuex_userInfo.phone:'请登录' }} + {{ vuex_userInfo.name?vuex_userInfo.name:vuex_userInfo.phone?showPhone(vuex_userInfo.phone):'请登录' }} @@ -20,7 +20,7 @@ - {{ vuex_userInfo.phone }} + {{ showPhone(vuex_userInfo.phone) }} @@ -85,6 +85,9 @@ if(this.show) this.show = false }, methods: { + showPhone(phone) { + return phone.substr(0, 3)+'****'+phone.substr(7) + }, async deleteTestClick() { const res = await deleteTest({phone: 18267103167}) this.$store.commit('goLogin') diff --git a/store/index.js b/store/index.js index cc030fc..c05bac6 100644 --- a/store/index.js +++ b/store/index.js @@ -2,8 +2,10 @@ import Vue from 'vue'; import Vuex from 'vuex'; import school from './modules/school'; import user from './modules/user'; +import permissionToast from './modules/permissionToast'; import getters from './getters'; + Vue.use(Vuex); @@ -28,6 +30,7 @@ const store = new Vuex.Store({ modules: { school, user, + permissionToast }, }); diff --git a/store/modules/permissionToast.js b/store/modules/permissionToast.js new file mode 100644 index 0000000..417b4d6 --- /dev/null +++ b/store/modules/permissionToast.js @@ -0,0 +1,230 @@ +// 页面路径:store/index.js + +const permissionToast = { + // 初始化状态 + state: { + // 处理应用程序权限请求 + WRITE_EXTERNAL_STORAGE: false, + ACCESS_FINE_LOCATION: false, + CAMERA: false, + CALL_PHONE: false, + /* #ifdef APP-PLUS */ + isIos: plus.os.name == "iOS", + /* #endif */ + mapping: { + 'CAMERA': { + title: "洛阳学车对扫开相机/摄像头权限申请说明", + content: "便于您使用该功能拍照,扫码,打卡签到签退等功能", + methods: 'SET_CAMERA' + }, + 'WRITE_EXTERNAL_STORAGE': { + title: "洛阳学车对存储空间/照片权限申请说明", + content: "便于您使用该功能上传您的照片/图片/视频及用于更换头像、下载、投诉与咨询等场景中读取和写入相册和文件内容。", + methods: 'SET_WRITE_EXTERNAL_STORAGE' + }, + 'ACCESS_FINE_LOCATION': { + title: "洛阳学车对地理位置权限申请说明", + content: "洛阳学车应用程序可以提供基于位置的服务、定位导航、计算距离、扫码场地打卡等功能。", + methods: 'SET_ACCESS_FINE_LOCATION' + }, + 'CALL_PHONE': { + title: "洛阳学车拨打/管理电话权限申请说明", + content: "便于您使用该功能联系驾校、教练场景下使用", + methods: 'SET_CALL_PHONE' + } + } + }, + mutations: { + // 管理权限告知目的 + SET_WRITE_EXTERNAL_STORAGE(state, val) { + state.WRITE_EXTERNAL_STORAGE = val + }, + SET_CALL_PHONE(state, val) { + state.CALL_PHONE = val + }, + SET_ACCESS_FINE_LOCATION(state, val) { + state.ACCESS_FINE_LOCATION = val + }, + SET_CAMERA(state,val) { + state.CAMERA = val + } + }, + actions: { + //权限获取 + async requestPermissions({state,dispatch,commit}, permissionID) { + console.log('gogogoog来了没??') + try { + if (!state[permissionID] && !state.isIos) { + var viewObj = await dispatch('nativeObjView', permissionID); + viewObj.show(); + } + console.log('android.permission.' + permissionID, '当前手机权限'); + return new Promise(async (resolve, reject) => { + //苹果不需要这个 + if (state.isIos) { + resolve(1); + return + } + // Android权限查询 + function requestAndroidPermission(permissionID_) { + return new Promise((resolve, reject) => { + plus.android.requestPermissions( + [permissionID_], // 理论上支持多个权限同时查询,但实际上本函数封装只处理了一个权限的情况。有需要的可自行扩展封装 + function(resultObj) { + var result = 0; + for (var i = 0; i < resultObj.granted.length; i++) { + var grantedPermission = resultObj.granted[i]; + console.log('已获取的权限:' + grantedPermission); + result = 1 + } + for (var i = 0; i < resultObj.deniedPresent.length; i++) { + var deniedPresentPermission = resultObj.deniedPresent[i]; + console.log('拒绝本次申请的权限:' + deniedPresentPermission); + result = 0 + } + for (var i = 0; i < resultObj.deniedAlways.length; i++) { + var deniedAlwaysPermission = resultObj.deniedAlways[i]; + console.log('永久拒绝申请的权限:' + deniedAlwaysPermission); + result = -1 + } + resolve(result); + }, + function(error) { + console.log('申请权限错误:' + error.code + " = " + error + .message); + resolve({ + code: error.code, + message: error.message + }); + } + ); + }); + } + + const result = await requestAndroidPermission( + 'android.permission.' + permissionID + ); + if (result === 1) { + //'已获得授权' + commit(state.mapping[permissionID].methods, true) + } else if (result === 0) { + //'未获得授权' + commit(state.mapping[permissionID].methods, false) + } else { + commit(state.mapping[permissionID].methods, true) + uni.showModal({ + title: '提示', + content: '操作权限已被拒绝,请手动前往设置', + confirmText: "立即设置", + success: (res) => { + if (res.confirm) { + dispatch('gotoAppPermissionSetting') + } + } + }) + } + if (viewObj) viewObj.close() + resolve(result); + }); + } catch (error) { + console.log(error); + uni.$u.toast('应用定位权限已关闭,请手动打开') + uni.hideLoading() + reject(error); + } + }, + //提示框 + nativeObjView({state}, permissionID) { + const systemInfo = uni.getSystemInfoSync(); + const statusBarHeight = systemInfo.statusBarHeight; + const navigationBarHeight = systemInfo.platform === 'android' ? 48 : + 44; // Set the navigation bar height based on the platform + const totalHeight = statusBarHeight + navigationBarHeight; + let view = new plus.nativeObj.View('per-modal', { + top: '0px', + left: '0px', + width: '100%', + backgroundColor: '#444', + //opacity: .5; + }) + view.drawRect({ + color: '#fff', + radius: '5px' + }, { + top: totalHeight + 'px', + left: '5%', + width: '90%', + height: "100px", + }) + view.drawText(state.mapping[permissionID].title, { + top: totalHeight + 5 + 'px', + left: "8%", + height: "30px" + }, { + align: "left", + color: "#000", + }, { + onClick: function(e) { + console.log(e); + } + }) + view.drawText(state.mapping[permissionID].content, { + top: totalHeight + 35 + 'px', + height: "60px", + left: "8%", + width: "84%" + }, { + whiteSpace: 'normal', + size: "14px", + align: "left", + color: "#656563" + }) + + function show() { + view = plus.nativeObj.View.getViewById('per-modal'); + view.show() + view = null //展示的时候也得清空,不然影响下次的关闭,不知道为啥 + } + + function close() { + view = plus.nativeObj.View.getViewById('per-modal'); + view.close(); + view = null + } + return { + show, + close + } + }, + // 跳转到**应用**的权限页面 + gotoAppPermissionSetting({state}) { + if (state.isIos) { + var UIApplication = plus.ios.import("UIApplication"); + var application2 = UIApplication.sharedApplication(); + var NSURL2 = plus.ios.import("NSURL"); + // var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES"); + var setting2 = NSURL2.URLWithString("app-settings:"); + application2.openURL(setting2); + + plus.ios.deleteObject(setting2); + plus.ios.deleteObject(NSURL2); + plus.ios.deleteObject(application2); + } else { + // console.log(plus.device.vendor); + var Intent = plus.android.importClass("android.content.Intent"); + var Settings = plus.android.importClass("android.provider.Settings"); + var Uri = plus.android.importClass("android.net.Uri"); + var mainActivity = plus.android.runtimeMainActivity(); + var intent = new Intent(); + intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + var uri = Uri.fromParts("package", mainActivity.getPackageName(), null); + intent.setData(uri); + mainActivity.startActivity(intent); + } + } + + } + +} +// 导出 store +export default permissionToast diff --git a/store/modules/user.js b/store/modules/user.js index 084aa38..220a7a4 100644 --- a/store/modules/user.js +++ b/store/modules/user.js @@ -2,7 +2,7 @@ import { httpPrefix } from '../../config/site.config.js'; // #ifdef APP-PLUS // import { requestSingleFreshLocation } from '@/common/js/qqLatLng.js' // #endif - +import store from '@/store/index.js' let apiOk =true let refreshTokenFn = null let timer = null @@ -62,8 +62,14 @@ const user = { getCity({commit}) { return new Promise((resolve, reject) => { // #ifdef APP-PLUS + store.dispatch("requestPermissions",'ACCESS_FINE_LOCATION',).then((result)=>{ + if (result !== 1) return + uni.showLoading({ + title: '正在更新位置...' + }) + getCityInfo(resolve, reject,commit) + }) - getCityInfo(resolve, reject,commit) // #endif // #ifdef H5 @@ -178,24 +184,28 @@ function getCityInfo(resolve, reject, commit) { let result = res.location if(result.latitude===0) { console.log('gogogo来了吗没有获取到经纬度?') - // openGps() - uni.getLocation({ - // type: 'wgs84', - type: 'gcj02', - success: function(res) { - console.log('只为弹出权限当前位置的经度:' + res.longitude); - // console.log('当前位置的纬度:' + res); - getCityInfo(resolve, reject, commit) - uni.hideLoading() - }, - fail() { - uni.showToast({ - title: '您的定位权限已关闭,请手动开启定位权限', - icon: 'none' - }) - uni.hideLoading() - } - }) + // uni.showToast({ + // title: '您的定位权限已关闭,请手动开启定位权限', + // icon: 'none' + // }) + // uni.hideLoading() + // uni.getLocation({ + // // type: 'wgs84', + // type: 'gcj02', + // success: function(res) { + // console.log('只为弹出权限当前位置的经度:' + res.longitude); + // // console.log('当前位置的纬度:' + res); + // getCityInfo(resolve, reject, commit) + // uni.hideLoading() + // }, + // fail() { + // uni.showToast({ + // title: '您的定位权限已关闭,请手动开启定位权限', + // icon: 'none' + // }) + // uni.hideLoading() + // } + // }) }else { console.log('腾讯云经纬度') console.log(result) diff --git a/uni_modules/uni-registerRequestPermissionTips/changelog.md b/uni_modules/uni-registerRequestPermissionTips/changelog.md new file mode 100644 index 0000000..67b6d9a --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/changelog.md @@ -0,0 +1,8 @@ +## 1.0.3(2024-10-18) +修复4.25版引起的插件回调只触发一次的问题。 +## 1.0.2(2024-09-05) +修复uni.chooseImage或者其他部分情况下弹窗不显示的bug。 +## 1.0.1(2024-05-30) +修复云打包可能报错的bug +## 1.0.0(2024-03-09) +支持全局监听权限申请。当申请权限时,会在页面顶部显示申请权限的目的。 diff --git a/uni_modules/uni-registerRequestPermissionTips/package.json b/uni_modules/uni-registerRequestPermissionTips/package.json new file mode 100644 index 0000000..8708e8e --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/package.json @@ -0,0 +1,115 @@ +{ + "id": "uni-registerRequestPermissionTips", + "displayName": "uni-registerRequestPermissionTips", + "version": "1.0.3", + "description": "支持android平台全局监听权限的申请。当申请权限时,会在页面顶部显示申请权限的目的。主要解决上架华为应用市场审核要求:APP在调用终端权限时,应同步告知用户申请该权限的目的。", + "keywords": [ + "权限", + "权限申请", + "上架", + "华为" + ], + "repository": "", + "engines": { + "HBuilderX": "^4.0" + }, + "dcloudext": { + "type": "uts", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + ], + "uni-ext-api": { + "uni": { + "registerRequestPermissionTipsListener": { + "name": "registerRequestPermissionTipsListener", + "app": { + "js": false, + "kotlin": true, + "swift": false + } + }, + "unregisterRequestPermissionTipsListener": { + "name": "unregisterRequestPermissionTipsListener", + "app": { + "js": false, + "kotlin": true, + "swift": false + } + }, + "setRequestPermissionTips": { + "name": "setRequestPermissionTips", + "app": { + "js": false, + "kotlin": true, + "swift": false + } + } + } + }, + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-android": "y", + "app-ios": "n", + "app-harmony": "u" + }, + "H5-mobile": { + "Safari": "n", + "Android Browser": "n", + "微信浏览器(Android)": "n", + "QQ浏览器(Android)": "n" + }, + "H5-pc": { + "Chrome": "n", + "IE": "n", + "Edge": "n", + "Firefox": "n", + "Safari": "n" + }, + "小程序": { + "微信": "n", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "n", + "钉钉": "n", + "快手": "n", + "飞书": "n", + "京东": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/readme.md b/uni_modules/uni-registerRequestPermissionTips/readme.md new file mode 100644 index 0000000..2357b46 --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/readme.md @@ -0,0 +1,95 @@ +## registerRequestPermissionTipsListener(listener?) +注册权限监听事件 +## unregisterRequestPermissionTipsListener(listener?) +取消注册权限监听事件 + +## RequestPermissionTipsListener的属性值 +|名称 |类型 |描述 |必填 | +|:-- |:-- |:-- |:-- | +|onRequest |(permissions:Array)=>void |申请系统权限回调,permissions为触发权限申请的所有权限 |否 | +|onConfirm |(permissions:Array)=>void |弹出系统权限授权框回调,permissions为触发弹出权限授权框的所有权限 |否 | +|onComplete |(permissions:UTSJSONObject)=>void |权限申请完成回调,permissions包括权限及权限的状态。`grant`为权限已获取,`denied`为权限已拒绝 |否 | + +## setRequestPermissionTips(UTSJSONObject) +设置权限监听的说明。支持针对权限设置具体的说明。 + +参考:`{"android.permission.CAMERA":"

相机权限申请说明

"}` + +安卓权限列表可参考[谷歌官方文档](https://developer.android.com/reference/android/Manifest.permission)。 + +权限申请说明基于原生TextView实现,可以实现加载html内容,支持的标签及属性可参考: +``` +:加粗文本。 +:斜体文本。 +:下划线文本。 +:上标文本。 +:下标文本。 +:等宽字体文本。 +:放大字体。 +:缩小字体。 +:带有删除线的文本。 +

:段落。 +

:块级容器。 +

:区域标题元素。 +
    ,
      ,
    1. :无序列表和有序列表。 +
      :换行。 +:设置文本颜色和大小。 +``` + +## 示例 + +``` + +``` \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/AndroidManifest.xml b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/AndroidManifest.xml new file mode 100644 index 0000000..a807709 --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/AndroidManifest.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/config.json b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/config.json new file mode 100644 index 0000000..bf95925 --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/config.json @@ -0,0 +1,3 @@ +{ + "minSdkVersion": "21" +} \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/index.uts b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/index.uts new file mode 100644 index 0000000..b005a53 --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/index.uts @@ -0,0 +1,148 @@ +import { UnregisterRequestPermissionTipsListener, RegisterRequestPermissionTipsListener, RequestPermissionTipsListener, SetRequestPermissionTips } from "../interface"; +import RelativeLayout from 'android.widget.RelativeLayout'; +import LinearLayout from 'android.widget.LinearLayout'; +import Color from 'android.graphics.Color'; +import TextView from 'android.widget.TextView'; +import ViewGroup from 'android.view.ViewGroup'; +import Activity from 'android.app.Activity'; +import HashMap from 'java.util.HashMap'; +import AnimationUtils from 'android.view.animation.AnimationUtils'; +import R from 'io.dcloud.uts.permissionrequest.R' +import Html from 'android.text.Html'; +import View from 'android.view.View'; +import Runnable from "java.lang.Runnable" + +let PermissionTipsView : View | null = null +let permissionTips : HashMap = new HashMap() +var permissionListener : RequestPermissionListener | null = null +var listener : RequestPermissionTipsListener | null = null + +@UTSJS.keepAlive +export function unregisterRequestPermissionTipsListener(e : RequestPermissionTipsListener | null) { + listener = null; + if (permissionListener != null) { + permissionListener!.stop() + permissionListener = null + } + if (PermissionTipsView != null) { + if (PermissionTipsView!.getParent() != null) { + PermissionTipsView!.setAnimation(null); + ((PermissionTipsView!.getParent()) as ViewGroup).removeView(PermissionTipsView) + } + PermissionTipsView = null + } +} + +@UTSJS.keepAlive +export function registerRequestPermissionTipsListener(l : RequestPermissionTipsListener | null) { + listener = l + if (permissionListener == null) { + permissionListener = uni.createRequestPermissionListener() + permissionListener!.onRequest((permissions : Array) => { + if (listener != null) + listener!.onRequest?.invoke(permissions) + }) + permissionListener!.onConfirm((permissions : Array) => { + UTSAndroid.getUniActivity()!.runOnUiThread(new ConfirmRunnable(permissions)) + }) + permissionListener!.onComplete((permissions : Array) => { + UTSAndroid.getUniActivity()!.runOnUiThread(new CompleteRunnable(permissions)) + }) + } +} + +class ConfirmRunnable implements Runnable { + permissions : Array + constructor(permissions : Array) { + this.permissions = permissions + } + override run() { + let activity = UTSAndroid.getUniActivity()! + if (PermissionTipsView != null && PermissionTipsView!.getParent() != null) { + PermissionTipsView!.setAnimation(null); + ((PermissionTipsView!.getParent()) as ViewGroup).removeView(PermissionTipsView) + } + if (this.permissions.length > 0) { + try { + PermissionTipsView = createPermissionWindow(activity, this.permissions); + if (PermissionTipsView != null) { + (activity.findViewById(android.R.id.content) as ViewGroup).addView(PermissionTipsView!) + } + } catch (e) { + console.log(e) + } + } + if (listener != null) + listener!.onConfirm?.invoke(this.permissions) + } +} + +class CompleteRunnable implements Runnable { + permissions : Array + constructor(permissions : Array) { + this.permissions = permissions + } + override run() { + let activity = UTSAndroid.getUniActivity()! + if (PermissionTipsView != null) { + PermissionTipsView!.setAnimation(AnimationUtils.loadAnimation(activity, R.anim.popupwindow_exit)); + ((PermissionTipsView!.getParent()) as ViewGroup).removeView(PermissionTipsView!) + PermissionTipsView = null + } + if (listener != null) { + var permissionStatus = {} + for (var p in this.permissions) { + permissionStatus[p] = UTSAndroid.checkSystemPermissionGranted(UTSAndroid.getUniActivity()!, [p]) ? "grant" : "denied" + } + listener!.onComplete?.invoke(permissionStatus) + } + } +} + +export const setRequestPermissionTips : SetRequestPermissionTips = (tips : UTSJSONObject) => { + permissionTips.clear() + for (var k in tips) { + permissionTips.put(k, tips[k] != null ? tips[k].toString() : "") + } +} + +function createPermissionWindow(activity : Activity, permissions : Array) : ViewGroup | null { + let rootView = new RelativeLayout(activity); + rootView.setBackgroundColor(Color.TRANSPARENT); + let backgroundView = new LinearLayout(activity); + backgroundView.setPadding(30, 0, 30, 30); + backgroundView.setOrientation(1) + backgroundView.setBackgroundResource(R.drawable.dcloud_permission_background); + let permissionTipsList : Array = new Array() + for (var p in permissions) { + if (permissionTips.containsKey(p) && permissionTipsList.indexOf(permissionTips.get(p)) == -1) { + permissionTipsList.push(permissionTips.get(p)!) + } + } + for (var p in permissionTipsList) { + let text = new TextView(activity); + text.setText(Html.fromHtml(p, Html.FROM_HTML_SEPARATOR_LINE_BREAK_HEADING)) + text.setPadding(0, 30, 0, 0) + text.setTextSize((5 * getScale()).toFloat()) + text.setTextColor(Color.BLACK) + backgroundView.addView(text) + } + if (backgroundView.getChildCount() == 0) { + return null; + } + let rll = new RelativeLayout.LayoutParams(-1, -2) + rll.topMargin = (UTSAndroid.getStatusBarHeight() * getScale()).toInt(); + rll.leftMargin = 30; + rll.rightMargin = 30; + rll.bottomMargin = 30; + rootView.addView(backgroundView, rll) + rootView.setAnimation(AnimationUtils.loadAnimation(activity, R.anim.popupwindow_enter)); + return rootView; +} + +function getScale() : Float { + if (UTSAndroid.getUniActivity() != null) { + return UTSAndroid.getUniActivity()!.resources.displayMetrics.scaledDensity + } + return (0 as number).toFloat(); +} \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_enter.xml b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_enter.xml new file mode 100644 index 0000000..37e9c6f --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_enter.xml @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_exit.xml b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_exit.xml new file mode 100644 index 0000000..5054a98 --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/anim/popupwindow_exit.xml @@ -0,0 +1,5 @@ + + \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/drawable/dcloud_permission_background.xml b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/drawable/dcloud_permission_background.xml new file mode 100644 index 0000000..80238cc --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/app-android/res/drawable/dcloud_permission_background.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/uni_modules/uni-registerRequestPermissionTips/utssdk/interface.uts b/uni_modules/uni-registerRequestPermissionTips/utssdk/interface.uts new file mode 100644 index 0000000..aacabe0 --- /dev/null +++ b/uni_modules/uni-registerRequestPermissionTips/utssdk/interface.uts @@ -0,0 +1,19 @@ +export type RequestPermissionTipsListener = { + onRequest ?: ((permissions : Array) => void) | null, + onConfirm ?: ((permission : Array) => void) | null, + onComplete ?: ((permissions : UTSJSONObject) => void) | null +} + + +export type RegisterRequestPermissionTipsListener = (listener : RequestPermissionTipsListener | null) => void +export type UnregisterRequestPermissionTipsListener = (listener : RequestPermissionTipsListener | null) => void +export type SetRequestPermissionTips = (tips : UTSJSONObject) => void + +export interface Uni { + + registerRequestPermissionTipsListener : RegisterRequestPermissionTipsListener, + + unregisterRequestPermissionTipsListener : UnregisterRequestPermissionTipsListener + + setRequestPermissionTips : SetRequestPermissionTips +} \ No newline at end of file