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.rhkb.cn/news/315060.html

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

相关文章

C#基础:WPF中常见控件的布局基础

一、用ViewBox实现放缩控件不变 二、布局代码 <Window x:Class"WpfApp1.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"Title"MainWindow"…

探索矿业数字化平台:实现智能化采矿与管理

随着信息技术的迅猛发展&#xff0c;矿业领域也在逐步实现数字化转型。数字化平台的出现为矿业企业带来了更高效、更智能的采矿与管理方式。本文将探讨矿业数字化平台的意义、特点以及未来发展方向。 ### 1. 数字化平台的意义 传统的矿业生产和管理方式存在诸多问题&#xff…

浏览器渲染机制:重排(Reflow)与重绘(Repaint)以及Vue优化策略

浏览器渲染机制是一个复杂但有序的过程&#xff0c;其目的是将HTML、CSS和JavaScript代码转化为用户可以看到和交互的视觉界面。重排&#xff08;Reflow&#xff09;与重绘&#xff08;Repaint&#xff09;是浏览器渲染过程中对页面元素进行更新的两个重要步骤&#xff0c;理解…

系统设计 --- E2E Test System

系统设计 --- E2E Test System 什么是E2EE2E Architecture Example 什么是E2E E2E&#xff08;端到端&#xff09;测试是一种软件测试方法&#xff0c;旨在模拟真实的用户场景&#xff0c;测试整个应用程序或系统的端到端功能和交互流程。E2E 测试涵盖了从用户界面到后端系统的…

物联网实战--平台篇之(一)架构设计

本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html 一、平台简介 物联网平台这个概念比较宽&#xff0c;大致可以分为两大类&#x…

APP自定义身份证相机(Android +iOS)

基本上同时兼容安卓和苹果的插件都需要付费&#xff0c;这里我找了2个好用的免费插件 1.仅支持安卓&#xff1a;自定义身份证相机&#xff08;支持蒙版自定义&#xff09;&#xff0c;内置蒙版&#xff0c;照片预览&#xff0c;身份证裁剪 - DCloud 插件市场、 2.支持iOS(已测…

【Unity】AssetBundle加载与卸载

unity官方apiAssetBundle-LoadFromFileAsync - Unity 脚本 API 异步加载AB包 using UnityEngine; using System.Collections; using System.IO;public class LoadFromFileAsyncExample : MonoBehaviour {IEnumerator Start(){var bundleLoadRequest AssetBundle.LoadFromFil…

区块链安全应用------压力测试

测试要求&#xff1a; 1. 对以下AccountManager智能合约进行压测(基础要求set函数测试&#xff0c;balanceOf涵为20分加分项)2. 在本地链进行测试&#xff0c;需要监控本地进程的资源使用情况。每个进程的multiOutput属性为Avg3. 需要将每一个更改的配置文件截图&#xff0c;和…

深度解析 Spring 源码:三级缓存机制探究

文章目录 一、 三级缓存的概述二、 三级缓存的实现原理2.1 创建Bean流程图2.2 getBean()2.3 doGetBean()2.4 createBean()2.5 doCreateBean()2.4 getSingleton() 三、 三级缓存的使用场景与注意事项3.1 在实际开发中如何使用三级缓存3.2 三级缓存可能出现的问题及解决方法 一、…

【服务器部署篇】Linux下Ansible安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

不可重复读,幻读和脏读

不可重复读一般在读未提交&#xff0c;读已提交这两种隔离级别出现&#xff0c;第一次读和第二次读的数据不一致。 幻读一般在读未提交&#xff0c;读已提交&#xff0c;可重复读出现&#xff0c;原因是第一个事务执行时&#xff0c;第二个事务完成了提交&#xff0c;在第一个…

CISSP通关学习笔记:共计 9 个章节(已完结)

1. 笔记说明 第 0 章节为开篇介绍&#xff0c;不包括知识点。第 1 - 8 章节为知识点梳理汇总&#xff0c;8 个章节的知识框架关系如下图所示&#xff1a; 2. 笔记目录 「 CISSP学习笔记 」0.开篇「 CISSP学习笔记 」1.安全与风险管理「 CISSP学习笔记 」2.资产安全「 CISSP…

网络安全实训Day15

写在前面 电子垃圾&#xff0c;堂堂恢复连载。本来不想分天数梳理了&#xff0c;但是最后要写实训报告&#xff0c;报告里还要有实训日记记录每日学的东西&#xff0c;干脆发这里留个档&#xff0c;到时候写报告提供一个思路。 网络空间安全实训-渗透测试 渗透测试概述 定义 一…

react引入iconfont的svg图标

react引入iconfont的svg图标 本文目录 react引入iconfont的svg图标普通图标通过link引入css组件内引入css使用 svg图标通过script引入js组件内引入js使用 通过封装组件自定义封装组件中调用 通过antd封装使用 普通图标 通过link引入css <link rel"stylesheet" h…

Labelme安装和使用

简介&#xff1a;labelme是图形图像注释工具&#xff0c;它是用Python编写的&#xff0c;并将Qt用于其图形界面&#xff0c;是麻省理工&#xff08;MIT&#xff09;的计算机科学和人工智能实验室&#xff08;CSAIL&#xff09;研发的图像标注工具&#xff0c;人们可以使用该工具…

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言&#xff1a;基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

QFD赋能人工智能:打造智能化需求分析与优化新纪元

在科技飞速发展的今天&#xff0c;人工智能(AI)已经渗透到我们生活的方方面面。然而&#xff0c;如何让AI更加贴合用户需求&#xff0c;提供更加精准和个性化的服务&#xff1f;这成为了一个亟待解决的问题。质量功能展开&#xff08;Quality Function Deployment&#xff0c;简…

go设计模式之工厂方法模式

工厂方法模式 什么是工厂方法模式 工厂方法模式是一种创建型设计模式&#xff0c;它定义了一个用于创建对象的接口&#xff0c;让子类决定实例化哪一个类。工厂方法使一个类的实例化推迟到其子类。 这个接口就是工厂接口&#xff0c;子类就是具体工厂类&#xff0c;而需要创…

Android 开发工具使用

c调试 在NDK调试的时候&#xff0c;如果找不到 符号的话&#xff0c;我们可以在调试配置中添加符号地址的全路径一直到根目录&#xff1a;&#xff0c;xxx/armeabi-v7a&#xff1a; You must point the symbol search paths at the obj/local/ directory. This is also not a …

黑盒优化系列(一):自动化提示词优化【一、绪论】

大语言模型的提示词 随着ChatGPT等大语言模型的问世&#xff0c;我们获取知识的方式从单一的搜索引擎如Google转变为类似ChatGPT这种通过 Q & A 方式提供的方法。 我们尝试对比一下不同提示词&#xff0c;对应的模型输出 ChatGPT无提示词 API&#xff1a; ChatGPT 3.5 …