uniapp 解决华为上架被拒问题,APP在申请敏感权限时,应同步说明权限申请的使用目的

1、store/modules/permission.js

// app权限申请处理
const state = {
	// 处理应用程序权限请求
	CAMERA: false,
	WRITE_EXTERNAL_STORAGE: false,
	ACCESS_FINE_LOCATION: false,
	CALL_PHONE: false,
	isIos: uni.getSystemInfoSync().platform == 'ios',
	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'
		}
	}
}

const mutations = {
	// 管理权限告知目的
	SET_CAMERA(state, val) {
		state.CAMERA = val
	},
	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
	}
}

const actions = {
	// 权限获取
	async requestPermissions({ state, dispatch, commit }, permissionID) {
		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) => {
				// ios不需要这个
				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)
			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: 'rgba(0,0,0,0.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('app-settings:')
			application2.openURL(setting2)

			plus.ios.deleteObject(setting2)
			plus.ios.deleteObject(NSURL2)
			plus.ios.deleteObject(application2)
		} else {
			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)
		}
	}
}

const getters = {}

export default {
	state,
	getters,
	mutations,
	actions
}

 2、store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

import permission from './modules/permission.js'

const namespaced = true

Vue.use(Vuex)

const store = new Vuex.Store({
	modules: {
		permission: {
			namespaced,
			...permission
		}
	}
})

export default store

3、使用

clickFun() {
    // #ifdef APP-PLUS
    const result = await this.$store.dispatch('permission/requestPermissions', 'WRITE_EXTERNAL_STORAGE')
    if (result !== 1) return
    // #endif

    // 权限拿到后,下面的逻辑根据你们的业务逻辑来写 ...
    uni.showToast({
        title:'权限获取成功'
    })
}
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值