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

这篇具有很好参考价值的文章主要介绍了uniApp应用软件在运行时,未同步告知权限申请的使用目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准。。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

app在调用终端敏感权限时,应同步说明权限申请的使用目的,包括但不限于申请权限的,uni-app
app在调用终端敏感权限时,应同步说明权限申请的使用目的,包括但不限于申请权限的,uni-app

应用审核意见:
1.您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(电话)等权限,不符合华为应用市场审核标准。
测试步骤:
点击我的-常见问题-意见反馈-联系客服,申请电话权限。
修改建议:
APP在调用终端敏感权限时,应同步说明权限申请的使用目的,包括但不限于申请权限的名称、服务的具体功能、用途;告知方式不限于弹窗、蒙层、浮窗、或者自定义操作系统权限弹框等。请排查应用内所有权限申请行为,确保均符合要求。文章来源地址https://www.toymoban.com/news/detail-764603.html

解决步骤:

  1. main.js 文件
    // #ifdef VUE3
    import store from './store'
    import { createSSRApp } from 'vue'
    export function createApp() {
      const app = createSSRApp(App)
      app.use(store)
      return {
    	app
      }
    }
    // #endif
    
  2. 创建store,store/index.js文件
    import { createStore } from 'vuex'
    const store = createStore({
    	// 初始化状态
    	state: {
    		// 处理应用程序权限请求
    		WRITE_EXTERNAL_STORAGE: false,
    		ACCESS_FINE_LOCATION: false,
    		CALL_PHONE: false,
    		/* #ifdef APP-PLUS */
    		isIos: plus.os.name == "iOS",
    		/* #endif */
    		mapping: {
    			'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
    		}
    	},
    	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) => {
    					//苹果不需要这个
    					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: '#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 store
    
  3. 在页面中引用
    async call_phone(phone) {
    	// #ifdef H5 || APP-PLUS 
    	let result = await this.$store.dispatch("requestPermissions",'CALL_PHONE')
    	if (result !== 1) return
    	// #endif 
    	
    	// 下面的逻辑随便 怎么写
    	return uni.makePhoneCall({
    		phoneNumber: phone,
    		// 成功回调
    		success: (res) => {
    			console.log('调用成功!')
    		},
    		// 失败回调
    		fail: (res) => {
    			console.log('调用失败!')
    		}
    	});
    },
    

到了这里,关于uniApp应用软件在运行时,未同步告知权限申请的使用目的,向用户索取(存储、相机、电话)等权限,不符合华为应用市场审核标准。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 应用软件破解

    研究软件注册机制,利用OD等工具破解U盘监控器、Free Internet Window Washer,绕过或发现注册码,达到注册成功目的。 1、U盘监控器注册破解 U 盘监控器需要注册才能使用全部功能,我们的任务是使得输入任何注册码均能注册成功 。通常在注册时,程序会读取注册码,然后对注册

    2024年02月16日
    浏览(53)
  • 软件物料清单管理 | 打开“应用软件盲盒”,预警“开源组件风险”

      随着软件规模化发展和开源软件的兴起,越来越多的软件在开发过程中集成第三方组件或开源组件。虽然这极大地提高了开发效率,但也难以避免地引入了安全风险。 2021年底,知名的开源项目 Apache Log4j被暴存在严重的安全漏洞,影响范围巨大,被称之为 “核弹级” 漏洞

    2024年02月08日
    浏览(43)
  • 细数应用软件的缺陷分类

    本文分享自华为云社区《应用软件的缺陷分类》,作者:Uncle_Tom 。 软件缺陷分类在已知缺陷管理、缺陷用例库建设、静态检查工具的能力覆盖和横向对比中起着重要的作用。本文参考GB/T-30279, CNNVD,NVD,以及CWE的各种视图, 给出了一个建立适合自己的缺陷分类方法。 最近先后

    2024年02月13日
    浏览(33)
  • 小课堂:应用软件如何做安全方案

    一、导语 作为三大入侵途径之一的“应用软件”,被用于入侵的频率非常高。 我们常用的Apache、Nginx、Tomcat、MySQL、SQL Server、Serv-U等大部分服务器软件,都有安全隐患,需要做好安全防护措施。 下面我们以Apache为例,讲解如何防御入侵。Apache是一款非常优秀的Web服务器软件

    2024年02月16日
    浏览(39)
  • Android 平台应用软件开发(学习中)

    1,LinearLayout(线性布局),RelativeLayout(相对布局),FrameLayout(帧布局),AbsoluteLayout(绝对布局),TableLayout(表格布局)。 2,线性布局中的控件属性说明 ①android:background,设置UI控件的背景,其值可以是资源文件夹中的图片或者是颜色的十六进制值。 ②android:orientation,该属性是线性布局

    2024年02月04日
    浏览(35)
  • 易语言软件定制软件开发脚本开发协议软件电脑网站APP应用视频制作工程制作

    随着信息技术的不断发展,易语言软件定制开发已成为许多公司的一项重要业务。本文将探讨如何利用易语言承接软件定制软件开发脚本开发协议软件电脑网站APP应用视频制作工程制作。 一、易语言概述 易语言是一种简单易学的编程语言,它采用中文编程,让不会英文的初

    2024年02月08日
    浏览(68)
  • 软件测试/测试开发丨ChatGPT在软件测试领域的应用

    随着互联网技术的迅速发展,软件已经成为现代社会中不可或缺的一部分。而软件测试作为保障软件质量的关键环节,也越来越受到人们的关注。在这个领域,ChatGPT作为一种新型的人工智能技术,正逐渐应用于软件测试领域,为软件测试带来了诸多创新和改进。 在软件测试

    2024年02月14日
    浏览(53)
  • 苹果电脑菜单栏应用管理软件Bartender 4 mac软件特点

    Bartender mac是一款可以帮助用户更好地管理和组织菜单栏图标的 macOS 软件。它允许用户隐藏和重新排列菜单栏图标,从而减少混乱和杂乱。 Bartender mac软件特点 菜单栏图标隐藏:Bartender 允许用户隐藏菜单栏图标,只在需要时显示。这样可以减少菜单栏的拥挤和视觉干扰,使界

    2024年02月03日
    浏览(39)
  • C# 软件Licence应用实例

    我们在使用一些需要购买版权的软件产品时,或者我们做的商业软件需要进行售卖,为了收取费用,一般需要一个软件使用许可证,然后输入这个许可到软件里就能够使用软件。简单的是一串序列码或者一个许可证文件,复杂的是一个定制化插件包。于是有的小伙伴就开始好

    2024年02月10日
    浏览(28)
  • 软件工程应用题汇总

    DFD/L0(基本系统模型) 只包含源点终点和一个处理(XXX系统) DFD/L1(功能级数据流图)在L0基础上进一步划分处理(XXX系统) 个人理解   DFD/L2(在L1基础上进一步分解后的数据流图) 变换流 以CD为变换中心          箭头尾部记得加圆圈(空心圆代表传递的数据,实心圆代表传递

    2024年01月18日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包