原因
华为上架被拒绝
用uni-app开发的app,上架华为被拒,问题如下:
您的应用在运行时,未见向用户告知权限申请的目的,向用户索取(电话、相机、存储)等权限,不符合华为应用市场审核标准。
测试步骤:任意招聘信息详情页-电话联系,申请电话权限;点击置顶推广-保存二维码到相册,申请存储权限;点击发布-任意服务-上传图片-拍摄/从相册选择,申请相机、存储权限;
修改建议:APP在调用终端权限时,应同步告知用户申请该权限的目的。请排查应用内所有权限申请行为,确保均符合要求。
华为相关文档中,关于这块的合规样例如图:
解决方案
在获取权限前面,弹出提示窗:
- 感谢做作者月上柳梢的插件: 插件地址: https://ext.dcloud.net.cn/plugin?id=15739
- 进入链接,下载插件并且导入项目, 里面有插件的使用, 如果看不懂, 可以看我写的教程,
- 首先再需要的页面导入项目,需要先导入组件, 注册组件, data 里面 的permissionID: '字段
-
// 这里是官方的教程 import ykAuthpup from "@/components/yk-authpup/yk-authpup"; // 导入插件 export default { components: { ykAuthpup, // 组件注册 }, data() { permissionID: "", }, methods:{ //这个是自己的方法名 openAuth(){ this.$refs['authpup'].open() //调起自定义权限目的弹框,具体可看示例里面很详细 }, //用户授权权限后的回调 changeAuth(){ //这里是权限通过后执行自己的代码逻辑 console.log('权限已授权,可执行自己的代码逻辑了'); } } }
-
修改前的代码,把点击时间加到组件的点击事件中,
<!-- 原来的代码 --> <view class="add-img" v-if="isUpload" @click="uploadpic"> <text class="iconfont icon-xiangji"></text> </view> <!-- 修改后的代码 --> <view class="authItem" @tap.stop="openAuth('WRITE_EXTERNAL_STORAGE')"> <yk-authpup ref="authpup" type="top" @changeAuth="uploadpic" :permissionID="permissionID"></yk-authpup> <view class="add-img" v-if="isUpload"> <text class="iconfont icon-xiangji"></text> </view> </view>
-
//打开自定义权限目的弹框, 这个写到methods中, 这是组件的自定义的弹窗 openAuth(permissionID){ this.permissionID = permissionID; setTimeout(()=>{ this.$refs['authpup'].open(); },100) }, /**上传文件, 这是原来的点击事件, 获取文件权限后才会执行*/ uploadpic: function() { let that = this; that.$util.uploadImageOne('upload/image', function(res) { console.log(res, '回调') that.uploadImg.push(res.data.path); that.$set(that, 'uploadImg', that.uploadImg); }); },
-
效果
-
但是有些地方这个组件不能使用, 比如视频页面,弹窗会失效, 还可以使用uniapp自己的组件 plus.android.checkPermission() 来检测权限, 你要检测什么组件, 这个_permissionID就写对应的权限, 在granted回调函数中需要对granted进行判断, -1 说明没有获取权限, 可以自定义弹窗, 用户点击确定后在执行对应的代码, 等于0 是权限已经获取到了, 不在弹窗
-
// 点击顶部添加视频图标或者搜索图标 handleNavbarImg(type) { let that = this; let _permissionID = 'android.permission.WRITE_EXTERNAL_STORAGE'; plus.android.checkPermission(_permissionID, granted => { console.log("granted的值是:", granted.checkResult); if (granted.checkResult == "-1") { console.log('Permission granted'); uni.showModal({ title: '一灯茶网对存储空间/照片/相机/摄像头权限申请说明', content: '便于您使用该功能上传您的照片/图片/视频及用于更换头像、意见反馈、保存相册、发布商品/分享、下载与客服沟通等场景中读取和写入相册和文件内容。', showCancel: false, // 不显示取消按钮 success(res) { switch (type) { case 0: //添加视频 if (!that.isNotLogin) { uni.showToast({ icon: 'none', title: '请登录', }) return; } that.$refs.video.open(); break; case 1: //搜索视频 let url = './searchVideo/searchVideo'; uni.navigateTo({ url: url, }) break; }; } }) } else if (granted.checkResult === 0) { console.log('已经获取到权限'); switch (type) { case 0: //添加视频 if (!that.isNotLogin) { uni.showToast({ icon: 'none', title: '请登录', }) return; } that.$refs.video.open(); break; case 1: //搜索视频 let url = './searchVideo/searchVideo'; uni.navigateTo({ url: url, }) break; }; } }, error => { console.log("权限报错:" ,error.message); } ); },
10. 页面效果
11. 其他页面的代码
<!-- <text v-if="storeInfo.service_phone" class="iconfont icon-dadianhua01" @click="goCustomer"></text> -->
<view class="authItem" @tap.stop="openAuth('CALL_PHONE')">
<text v-if="storeInfo.service_phone" class="iconfont icon-dadianhua01"></text>
<yk-authpup ref="authpup" type="top" @changeAuth="goCustomer" :permissionID="permissionID"></yk-authpup>
</view>
methods: {
//侯希晨修改权限打开自定义权限目的弹框
openAuth(permissionID){
this.permissionID = permissionID;
setTimeout(()=>{
this.$refs['authpup'].open();
},200)
},