uniapp app权限说明弹框2024.4.23更新

华为上架被拒绝

用uni-app开发的app,上架华为被拒,问题如下:

您的应用在运行时,未见向用户告知权限申请的目的,向用户索取(电话、相机、存储)等权限,不符合华为应用市场审核标准。

测试步骤:任意招聘信息详情页-电话联系,申请电话权限;点击置顶推广-保存二维码到相册,申请存储权限;点击发布-任意服务-上传图片-拍摄/从相册选择,申请相机、存储权限;修改建议:APP在调用终端权限时,应同步告知用户申请该权限的目的。请排查应用内所有权限申请行为,确保均符合要求。

本文是使用pinia集中管理的!!如果想使用vuex,照着改,大同小异

20214.4.23 uniapp权限弹框视频

<template><view><button @tap="applyCameraPermission('CAMERA')">申请相机权限</button><button @tap="applyPhonePermission('SET_CALL_PHONE')">申请电话权限</button><button @tap="applyReadexternal('READ_EXTERNAL_STORAGE')">读取照片</button><button @click="nextpage">跳转</button></view>
</template><script setup>
import { usePermission } from "/store/permission.js"
const permissionStore = usePermission()const applyCameraPermission = async (permission) => {/* #ifdef APP */if (!await permissionStore.requstPermission(permission)) return/* #endif */uni.chooseImage({count: 1,sizeType: ['original', 'compressed'],sourceType: ['camera'],success: (res) => {console.log(res)}});
}
const applyPhonePermission = async (permission) => {/* #ifdef APP */if (!await permissionStore.requstPermission(permission)) return/* #endif */uni.makePhoneCall({phoneNumber: '10086'});
}
const applyReadexternal = async (permission) => {/* #ifdef APP */if (!await permissionStore.requstPermission(permission)) return/* #endif */uni.chooseImage({count: 1,sizeType: ['original', 'compressed'],sourceType: ['album'],success: (res) => {console.log(res)}});
}const nextpage = () => {uni.navigateTo({url: '/pages/index/index'});
}
</script><style></style>

pinia权限管理仓库

import {defineStore
} from 'pinia'export const usePermission = defineStore('permission', {state: () => ({dialogView: null,permissionListener: null,list: [{name: "READ_CALENDAR",title: "手机状态权限申请说明:",content: "uni-app正在申请手机日历日历状态权限,允许或拒绝均不会获取任何隐私信息。",}, {name: "CALL_PHONE",title: "拨打电话权限申请说明:",content: "uni-app正在申请拨打电话权限,允许或拒绝均不会获取任何隐私信息。",}, {name: "CAMERA",title: "读取存储权限申请说明:",content: "uni-app正在申请摄像头权限,允许或拒绝均不会获取任何隐私信息。",}, {name: "READ_EXTERNAL_STORAGE",title: "读取存储权限申请说明:",content: "uni-app正在申请读取存储权限,允许或拒绝均不会获取任何隐私信息。",}]}),getters: {},actions: {//监听权限申请async requstPermission(permissionID) {return new Promise((resolve, reject) => {try {// if (!uni.getSystemInfoSync().platform == 'android') return resolve(true) /*** @description plus.navigator.checkPermission 检查应用是否获取指定权限 * 有些权限检测不到 就继续下面的代码,比如相册权限就可以直接检测,就很方便,授权情况下不需要再走下面代码了* checkPermission 返回参数* @params undetermined 未确定* @params authorized 授权*/let checkPermission = plus.navigator.checkPermission('android.permission.' + permissionID)if (checkPermission == 'authorized') return resolve(true)//判断是否自己在list里面配置了这个权限let index = this.list.findIndex(item => item.name == permissionID)if (index == -1) throw new Error('这个权限没有配置')//唤起原生权限说明弹框this.requstPermissionDialog(index)//授权检测回调plus.android.requestPermissions(['android.permission.' + permissionID  //单个权限// 'android.permission.CAMERA', 'android.permission.READ_EXTERNAL_STORAGE'  //多个权限],(resultObj) => {console.log(resultObj, 'resultObj');// 权限申请结果/*** @description resultObj.deniedAlways 永久拒绝授权* 多个权限返回结果可能是{"granted":["android.permission.CAMERA"],"deniedPresent":[],"deniedAlways":["android.permission.READ_EXTERNAL_STORAGE"]}* 这个情况就是我同时授权相册和相机,但是只允许了相机,没有授权相册* 这个时候 可以通过deniedAlways 查看哪个权限被永久拒绝了,然后自行在设置弹框内容* 所以可以自己判断细分一下,我下面的代码是先判断了是否有永久拒绝的权限,然后直接弹框提示用户去设置*/if (resultObj.deniedAlways && resultObj.deniedAlways.length > 0) {uni.showModal({title: '提示',content: '操作权限已被拒绝,请手动前往设置',confirmText: "立即设置",success: (res) => {if (res.confirm) {this.gotoAppPermissionSetting()} else {resolve(false)}}})console.log('永久拒绝授权');} else if (resultObj.deniedPresent && resultObj.deniedPresent.length > 0) {resolve(false)console.log('拒绝授权');} elseif (resultObj.granted && resultObj.granted.length > 0) {resolve(true)console.log('授权成功');}},(error) => {reject(false)console.log('申请权限错误:',error);});} catch (err) {reject(false)console.log(err);}})},//监听弹框requstPermissionDialog(index) {try {if (!this.permissionListener) this.permissionListener = uni.createRequestPermissionListener()const dialogData = this.list[index]this.permissionListener.onConfirm((res) => {this.dialogStyle(dialogData, true)})this.permissionListener.onComplete(async (res) => {this.dialogStyle({}, false)})} catch (err) {console.log('监听弹框错误', err);}},//弹框样式dialogStyle({ title = '', content = '' }, status) {try {if (!status) return this.dialogView.close()const systemInfo = uni.getSystemInfoSync();const statusBarHeight = systemInfo.statusBarHeight;const navigationBarHeight = systemInfo.platform === 'android' ? 48 :44;const totalHeight = statusBarHeight + navigationBarHeight;this.dialogView = new plus.nativeObj.View('per-modal', {top: '0px',left: '0px',width: '100%',backgroundColor: '#444',//opacity: .5;})this.dialogView.drawRect({color: '#fff',radius: '5px'}, {top: totalHeight + 'px',left: '5%',width: '90%',height: "100px",})this.dialogView.drawText(title, {top: totalHeight + 5 + 'px',left: "8%",height: "30px"}, {align: "left",color: "#000",})this.dialogView.drawText(content, {top: totalHeight + 35 + 'px',height: "60px",left: "8%",width: "84%"}, {whiteSpace: 'normal',size: "14px",align: "left",color: "#656563"})this.dialogView.show()} catch (e) {console.log(e, '权限说明弹框样式错误');}},//跳转到app权限设置页面gotoAppPermissionSetting() {if (!uni.getSystemInfoSync().platform == 'android') {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);}}}
})

更多permissionID 值域清单权限  App权限判断和提示 - DCloud 插件市场

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/3835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

HWOD:输出单向链表中倒数第k个节点

一、知识点 不确定输入的数据有多少组时&#xff0c;可以用 if(scanf()>0) 作为判断条件 如果要处理多组数据&#xff0c;不一定要为每组数据申请空间。可以存储一组&#xff0c;处理一组&#xff0c;存储数据的空间清零之后继续存储下一组数据。额外申请空间&#xff0…

MySQL函数之单行函数

1.前言 我们在使用 SQL 语言的时候&#xff0c;不是直接和这门语言打交道&#xff0c;而是通过它使用不同的数据库软件&#xff0c;即DBMS。DBMS 之间的差异性很大&#xff0c;远大于同一个语言不同版本之间的差异。实际上&#xff0c;只有很少的函数是被 DBMS 同时支持的。比…

AI助手对决:ChatGPT vs 文心一言

背景介绍 在当今人工智能技术飞速发展的时代&#xff0c;AI助手已经成为我们日常生活中不可或缺的一部分。而在众多AI助手中&#xff0c;ChatGPT和文心一言可以说是备受瞩目的两大代表&#xff0c;它们在智能回复、语言准确性、知识库丰富度等方面都有着自己的特点和优…

微信小程序:12.页面导航

什么是页面导航 页面导航指的是页面之间的相互跳转。例如&#xff0c;浏览器中实现的页面导航的方式有两种&#xff1a; 连接location.href 小程序中实现页面导航的两种方式 声明式导航 在页面上声明一个导航组件 通过点击组件实现页面跳转 导航TabBar页面 是指配置TabB…

Unity自动化之自动构建图集与压缩

文章目录 前言一、UI图集的压缩unity2020之前的版本使用图集unity2020之后的版本使用图集 二、非UI图集压缩总结 前言 为降低DrawCall&#xff0c;我们需要将多个图片构建在图集上。同时还有个好处&#xff0c;可以自动补齐图片补齐2的幂次方或正方形图&#xff0c;这样便可以…

【CV】特征匹配FAST和MSER

特征匹配是计算机视觉领域的重要概念&#xff0c;涉及在图像中寻找关键点和描述符。FAST和MSER是两种常用的关键点检测算法。 FAST (Features from Accelerated Segment Test) FAST算法是一种快速角点检测器。它基于像素强度比较&#xff0c;在一个圆圈内进行强度对比&#x…

解决uniapp修改内置组件样式,在微信中不生效问题

下面是作者在开发工作中遇到的问题&#xff0c;踩坑几小时最后解决的办法。 接下来以UNIAPP文档中的内置组件 slider 为例 接下来直接上样式代码&#xff1a; <style lang"scss" scoped>::v-deep .wx-slider-wrapper {height: 100% !important;}::v-deep .w…

前端实现将当前页面内容下载成图片(图片可做到高清画质)

插件背景&#xff1a; html2canvas可以把你想要转变的元素变为图片&#xff0c;使用file-saver下载图片。 1、安装html2canvas、file-saver npm install html2canvasnpm install file-saver --save 2、在Vue组件中引入并使用html2canvas、file-saver import html2canvas fro…

Django 学习 笔记

Django 一、模型models 继承django.db.models.Model 1.模型字段 / 模型字段选项参考&#xff1a; 官网&#xff1a;https://docs.djangoproject.com/zh-hans/3.2/ref/models/fields/#common-model-field-options 2.模型Meta选项(定义模型类的属性)&#xff1a; csdn: https:/…

C#基础|对象初始化器与构造方法对比总结

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 01 对象初始化器的作用 为了更加灵活的初始化对象的“属性”&#xff0c;是对构造化方法的补充。 02 构造方法总结 2.1、存在的必要性&#xff1a;一个类中&#xff0c;至少要有一个构造方法&#xff08;有无参数均…

五一节前的信息系统的安全保障工作

文章目录 保障流程制定安全保障计划确定检查人员确定检查内容实施检查风险评估修复漏洞定期复查 保障内容系统安全检查网络安全检查数据安全检查应用安全检查用户安全检查安全政策和流程检查 关闭信息系统说明制定关闭计划备份数据通知相关人员停止系统服务关闭系统设备监控关闭…

合合信息引领AI场景化革新,供应链金融智能化审核全面升级!

官.网地址&#xff1a;合合TextIn - 合合信息旗下OCR云服务产品 随着供给侧结构性改革的深入推进和产业结构的不断升级&#xff0c;金融机构在监管部门的指导下&#xff0c;积极拓展供应链金融业务&#xff0c;取得了显著成效。这一举措有效缓解了上下游中小企业的融资困难&a…

国产麒麟v10系统下打包electron+vue程序,报错unknown output format set

报错如下&#xff1a; 报错第一时间想到可能是代码配置原因报错&#xff0c;查看代码似乎感觉没啥问题 又查看具体报错原因可能是因为icon的原因报错&#xff0c;后面查阅发现ico在各系统平台会不兼容&#xff0c;也就是ico是给win下使用的&#xff0c;此处改下图标格式就ok&am…

Unreal Engine动态添加Button实例

在控件蓝图中添加容器&#xff0c;注意命名不要有中文 C代码中找到容器实例 1 2 3 4 5 6 7 8 UVerticalBox* verticalBox Cast<UVerticalBox>(CurrentWidget->GetWidgetFromName(TEXT("VerticalBox_0"))); if (verticalBox ! nullptr) { UScrollBox* …

AJAX——黑马头条-数据管理平台项目

1.项目介绍 功能&#xff1a; 登录和权限判断查看文章内容列表&#xff08;筛选&#xff0c;分页&#xff09;编辑文章&#xff08;数据回显&#xff09;删除文章发布文章&#xff08;图片上传&#xff0c;富文本编辑器&#xff09; 2.项目准备 技术&#xff1a; 基于Bootst…

stm32mp135d bringup

stm32mp135d bringup 一、安装交叉编译链二、获取bsp代码并编译1. tf-a(trust-firmware)二、optee三、u-boot四、linux 三、快速开始四、st社区关于bringup问题链接 关于 stm32mp135d的移植 一共分为4个部分 tf-a(trusted-firmware) optee u-boot linux文件系统编译后面再说&a…

ShardingSphere 5.x 系列【26】 数据分片原理之 SQL 路由

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 概述2. 携带分片键2.1 直接路由2.2 标准路由2.3 笛卡尔路由3. 不携带分片…

如何在docker上面使用hbase shell

在新公司上班&#xff0c;hbase是cdh6.3.2安装在docker上面&#xff0c;如何直接在shell上面使用hbase shell是访问不到的。使用教程如下&#xff1a; 要在Docker上使用CDH 6.3.2中的HBase shell&#xff0c;你需要按照以下步骤操作&#xff1a; 步骤1&#xff1a;启动HBase服…

【内网横向】SSH协议隧道搭建详解

什么是SSH隧道 SSH隧道是通过Secure Shell&#xff08;SSH&#xff09;协议在两个网络节点之间创建的加密通道。它可以用于安全地传输数据&#xff0c;绕过网络限制或保护数据免受窃听。通过SSH隧道&#xff0c;可以在两个网络之间建立安全的连接&#xff0c;例如在本地计算机和…

字符串简单运算(BigDecimal相关运算)

目录 1.除法 2.乘法 3.减法 4.加法 1.除法 使用 divide(BigDecimal, int, RoundingMode) 方法进行除法运算。第一个参数是要除的 BigDecimal&#xff0c;第二个参数指定结果的小数位数&#xff0c;第三个参数是舍入模式。这里选择了 RoundingMode.HALF_UP&#xff0c;即四舍…