uni-app 用户点击拒绝隐私政策后 app仍收集硬件序列码 致应用市场审核不通过
uni-app 用户点击拒绝隐私政策后 app仍收集硬件序列码 致应用市场审核不通过
产品分类
uniapp/App
操作步骤
详见描述
预期结果
点击拒绝之后不收集硬件序列号
实际结果
点击拒绝之后会收集硬件序列号
bug描述
问题描述
点击拒绝进入隐私政策会触发收集硬件序列号。我发现社区还有其他人有同样问题,但没人解答,至今未解决。
调用堆栈说明
硬件序列号
发生时间:2024-12-24 09:57:43
违规md5:md5=084134B446741014FCC3A21A42DEB2E6,
违规包名:pkg=com.nbzhufang.app,
违规动作:action=android.permission.READ_PHONE_STATE_SERIALNO,
违规详情:content=JAVA反射读取Build.SERAIL,callstack:java.lang.Class.getField:1605;io.dcloud.e.f.a$b.f:1;io.dcloud.e.f.a$b.e:6;io.dcloud.e.f.a$b.<clinit>:1;io.dcloud.e.f.a$b.b:1;io.dcloud.e.f.a.a:65;io.dcloud.e.f.a.a:22;io.dcloud.e.f.b.a:10;io.dcloud.e.f.b.<init>:6;io.dcloud.e.f.b.a:4;io.dcloud.feature.gg.dcloud.AolFeatureImpl.doForFeature:136;io.dcloud.feature.gg.AolFeatureImplMgr.doForFeature:5;io.dcloud.a.a:16;io.dcloud.b$a.run:5;android.os.Handler.handleCallback:873;android.os.Handler.dispatchMessage:99;android.os.Looper.loop:193;android.app.ActivityThread.main:7175;java.lang.reflect.Method.invoke:-2;com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run:493;com.android.internal.os.ZygoteInit.main:858;
问题自查
- 是否最新版本 目前已经将uniapp相关依赖升级至最新,版本为3.0.0-4030620241128001
- 隐私政策弹窗是否为template模式
{ "version" : "1.0.0", "prompt" : "template", "title" : "服务协议和隐私政策", "message" : " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https://admin.nbzufang.com.cn/PrivacyPolicy.html\">《隐私政策》</a>和<a href=\"https://admin.nbzufang.com.cn/AppUserAgreement.html\">《服务协议》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", "buttonAccept" : "同意并接受", "buttonRefuse" : "拒绝", "hrefLoader" : "system", "disagreeMode" : { "support" : true, "loadNativePlugins" : false, "visitorEntry" : false, "showAlways" : false }, "styles" : { "backgroundColor" : "#FFFFFF", "borderRadius" : "5px", "title" : { "color" : "#333333" }, "buttonAccept" : { "color" : "#00a381" }, "buttonRefuse" : { "color" : "#c8161d" } } }
- 查看是否集成uni原生插件 已经删除相关原生插件打包,用到了腾讯im离线推送插件和自己写的原生插件,复测未通过
- 是否在disagreeMode模式下调用限制plus API 目前发现启动时会调用plus.navigator.isRoot进行安全检测,加了plus.runtime.isAgreePrivacy()判断进行调用后,还是审核未通过
- 是否是unipush或者友盟sdk导致获取硬件序列号 去除这两个之后,提交复测未通过
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
PC开发环境操作系统 | Windows | CLI |
PC开发环境操作系统版本号 | win10 | |
手机系统 | Android | |
手机系统版本号 | Android 15 | |
打包方式 | 云端 | |
CLI版本号 | 3.0.0-4030620241128001 |
最新情况:
已经去除掉main.js中所有无关代码仅保留createApp
去除掉了app.vue中所有代码和引用
删除掉了所有页面和代码,仅保留了一个啥也没有的空页面
去除掉了unipush,友盟,所有原生插件,仅保留:相机模块,map地图,oauth登录授权,payment支付,share分享videoplayer
apk下载地址:https://nbzhufang-pro.oss-cn-hangzhou.aliyuncs.com/app%2Capp/安装包/demo.apk
结果:审核未通过。
理由:APP启动时,在用户授权同意隐私政策前,APP及SDK不可以提前收集和使用IMEI、OAID、IMSI、MAC、应用列表等信息;
uniapp官方文档说明:
也就是说根据《规定》要求,很多App需要支持在用户不同意“隐私政策的情况下仍然可以进入运行,并提供基本功能服务。为了支持此类需求,HBuilderX 3.3.1版本新增“未同意隐私政策模式”(以下简称“disagreeMode”),配置支持disagreeMode后,用户在“隐私政策”提示框点击拒绝按钮后仍然可以继续使用App。在此模式下,uni-app(5 App/Wap2App) 内部逻辑会做特殊处理:
不会主动申请读写手机存储、访问设备信息等权限
不会主动读任何取设备信息
仍然会发送应用启动统计请求,但不包含设备信息
仍然会提交异常崩溃统计请求,但不包含任何设备信息
不是你们收集的,那是我收集的呗…??我请问呢。。。?
昨天打包去除了原生插件后打包这个给我气笑了,我不知道这个原生插件有没有打包进去,我是先删除原生插件后打包但提示有用到原生插件,原生插件中有用到腾讯im的离线推送
我这里提供一下复现案例可自行下载
问题在确认,如果紧急上架的情况,建议先将support设置为false,如果需要游客模式的话,可以先将visitorEntry设置为true
嗯好,谢谢
您好问题确认了吗
回复 9***@qq.com: 还在确认,你可以先按照我上面说的先上架,有结果我们会同步
回复 9***@qq.com: 我也遇到这个情况,所有的页面用到权限的我都做了判断,一样上架被拒,问题有解决吗
回复 1***@qq.com: 目前先不让用户点拒绝隐私政策之后继续使用,也就是先将support设置为false,这样可以成功上架,但有些应用市场是需要拒绝后让用户继续使用的
回复 9***@qq.com: 好的,谢谢
回复 9***@qq.com: 问题我们在修复中,预计下次发版会修复,后续升级直接打包就可以了
我也遇到了这个问题
回复 d***@qq.com: 发一下包,调用堆栈和检测报告,我这边看一下
同等待,存在两条
1、“APP 存在未经用户同意读取“硬件序列号”的行为”
2、“存在若干 SDK 未经用户许可读取个人隐私信息(硬件序列号)”
针对您提到的uni-app在用户点击拒绝隐私政策后仍收集硬件序列码的问题,这确实违反了隐私保护的基本原则,也是应用市场审核中常见的不合规行为。为了确保应用的合规性,我们需要确保在用户拒绝隐私政策后,应用不会继续收集任何敏感信息,包括硬件序列码。
以下是一个简化的代码示例,展示了如何在uni-app中实现用户隐私政策的同意检查,并在用户拒绝时停止收集硬件序列码:
// 假设我们有一个函数来获取硬件序列码(仅为示例,实际获取方式可能不同)
function getDeviceSerialNumber() {
// 这里是获取硬件序列码的模拟代码
return 'ABC123456789';
}
// 假设我们有一个函数来显示隐私政策对话框
function showPrivacyPolicyDialog() {
return new Promise((resolve, reject) => {
uni.showModal({
title: '隐私政策',
content: '我们需要收集您的硬件序列码以优化服务。请阅读并同意我们的隐私政策。',
showCancel: true,
cancelText: '拒绝',
confirmText: '同意',
success: function (res) {
if (res.confirm) {
resolve(true); // 用户同意
} else if (res.cancel) {
resolve(false); // 用户拒绝
}
}
});
});
}
// 应用启动时检查隐私政策同意状态
async function initApp() {
try {
const isAgreed = await showPrivacyPolicyDialog();
if (isAgreed) {
const serialNumber = getDeviceSerialNumber();
console.log('用户同意隐私政策,硬件序列码为:', serialNumber);
// 在这里可以继续处理硬件序列码,如发送到服务器等
} else {
console.log('用户拒绝隐私政策,不会收集硬件序列码');
// 在这里处理用户拒绝的情况,如显示提示信息或退出应用等
}
} catch (error) {
console.error('显示隐私政策对话框时出错:', error);
}
}
// 调用初始化函数
initApp();
在这个示例中,showPrivacyPolicyDialog
函数显示了一个模态对话框,询问用户是否同意隐私政策。如果用户同意,则调用getDeviceSerialNumber
函数获取硬件序列码;如果用户拒绝,则不会收集硬件序列码,并可以在控制台中记录相应的信息。
请确保在实际应用中,隐私政策的显示和同意状态的检查是严格的,并且符合相关法律法规的要求。此外,对于硬件序列码等敏感信息的收集和处理,应遵循最小必要原则,并确保数据的安全性和隐私保护。