前言
上一篇聊了应用市场审核的全流程,本篇单挑最硬的一块——用户数据采集合规。PIPL、GDPR、Google Play Data Safety Form 都强制要求"知情同意"和"最小必要"原则。这些不是法律免责声明的事,而是要在代码层面改出来的工程实践。
一、合规三原则
不通过国内/海外审核的 80% 问题,都出在这三条上。
二、用户数据分类
2.1 个人信息
任何能识别用户身份的数据:
2.2 设备数据(不算个人信息)
2.3 派生数据
三、知情同意的工程实现
3.1 多阶段同意
最常见的合规模式是"分阶段弹窗":
class PrivacyManager(private val context: Context) {
// 基础协议
fun checkBaseConsent(): ConsentState {
val accepted = DataStoreManager.getBool("base_consent")
return ConsentState.ACCEPTED.takeIf { accepted }
?: ConsentState.NOT_ACCEPTED
}
// 单独 / 精细同意(如"是否允许设备识别")
fun checkExtraConsent(key: String): ConsentState {
val accepted = DataStoreManager.getBool("extra_$key")
return ConsentState.ACCEPTED.takeIf { accepted } ?: ConsentState.NOT_ACCEPTED
}
fun recordConsent(key: String, accepted: Boolean) {
DataStoreManager.setBool("base_$key", accepted)
}
}
3.2 同意弹窗设计要点
3.3 用户撤回
GDPR 给了用户撤回同意的权利。每个同意项必须有"撤销"功能:
val settingsComposable: @Composable (() -> Unit) = {
Column {
SwitchPreference(
title = "个性化推荐",
checked = PrivacyManager.checkExtraConsent("personalization"),
onChange = { checked ->
PrivacyManager.recordConsent("personalization", checked)
if (!checked) PersonalizationEngine.clearUserProfile()
}
)
SwitchPreference(
title = "分析数据上报",
checked = PrivacyManager.checkExtraConsent("analytics"),
onChange = { checked ->
PrivacyManager.recordConsent("analytics", checked)
if (!checked) AnalyticsSDK.disable()
}
)
}
}
用户撤回时,立刻停止相关 SDK 的采集、清理服务端缓存。
四、数据采集的工程约束
4.1 设备标识的获取
// 错误:直接拿 IMEI
val imei = telephonyManager.getDeviceId()
// 错误:拿 MAC 地址
val mac = wifiManager.connectionInfo.macAddress
// 推荐:用 Android ID + 安装 ID
val androidId = Settings.Secure.getString(
contentResolver, Settings.Secure.ANDROID_ID
)
val installId = DataStoreManager.getString("install_id")
IMEI 和 MAC 在 Android 8+ 已经不可读,强行读取会被市场扫描拦截。推荐用 Android ID + 安装 UUID 组合作为设备标识。
4.2 上报数据的字段过滤
object DataFilter {
fun filter(event: JSONObject): JSONObject {
val allowed = listOf("event_id", "timestamp", "page_id", "action_type")
val filtered = JSONObject()
event.keys().asSequence().forEach { key ->
if (key in allowed) {
filtered.put(key, event.get(key))
}
}
return filtered
}
}
所有上报事件,先经过过滤器去掉敏感字段。
4.3 用户数据存储
示例:
val masterKey = MasterKey.Builder(context)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
val prefs = EncryptedSharedPreferences.create(
context, "secure_prefs", masterKey,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV
)
prefs.edit().putString("token", "...").apply()
五、第三方 SDK 的数据流控制
每个第三方 SDK 都是潜在合规风险——它们也可能在悄悄上报。工程上做"白名单+过滤器":
class SdkWhitelist {
private val blocked = setOf("e.163.com", "track.adnxs.com")
private val allowedSdks = setOf("Bugly", "JPush", "UMeng")
fun shouldAllow(host: String): Boolean {
return blocked.none { host.contains(it) }
}
fun isSdkInitialized(name: String): Boolean {
return allowedSdks.contains(name)
}
}
实际做法:
六、海外合规要点(GDPR / CCPA)
海外合规更严,要求更高:
// 同意工具
val consent = UserCentrics.getConsentStatus()
// 0 = 没决定,1 = 同意,2 = 拒绝
建议海外版本用合规工具:OneTrust / UserCentrics / Cookiebot,每个合规小项预先配置。
七、儿童模式合规
针对 13 岁以下用户的 App(教育、儿童类),必须:
不能 SDK 上报
不能做任何广告
不能定位
不能社交
不能有引导付费
Google Play 要求 Designed for Families 标签:
if (isKidsMode()) {
PrivacyManager.disableAllSdks()
AdsLoader.disable()
LocationService.disable()
}
八、合规自检清单(CI 集成)
// privacy-lint.gradle
val allowedPermissions = setOf(
"android.permission.INTERNET",
"android.permission.ACCESS_NETWORK_STATE"
)
val declared = parseManifestPermissions()
declared.filterNot { it in allowedPermissions }
.forEach { Lint.warn("Unexpected permission: $it") }
CI 跑 gradle lint privacyCheck,合规字段漂移立刻报警。
九、合规事故的应对
如果已经违规(泄露数据、被通报):
24h 内:停止相关 SDK / 关闭功能
72h 内:内部排查根因
7 天内:通知监管部门和受影响用户(PIPL 要求)
修复:修改代码 + 升级 SOP + 合规培训
PIPL 第 57 条规定:违反个人信息处理义务,造成严重后果的,由省级以上履行个人信息保护职责的部门责令改正,没收违法所得,并处 5000 万以下或者上一年度营业额 5% 以下罚款。
十、一个完整的合规工程设计
启动流程:
1. App.onCreate
└─ 仅做最低运行(不初始化任何 SDK)
2. 检查用户同意
├─ 还没决定:跳到隐私弹窗
└─ 已同意:继续
3. 初始化基础 SDK
├─ 网络、推送、崩溃监控
└─ 同步 Privacy 中心状态
4. 后续业务功能按需开启 SDK
class App : Application() {
override fun onCreate() {
super.onCreate()
// 不再这里初始化任何 SDK
PrivacyGate.start {
if (it) {
Bugly.init(this)
JPush.init(this)
}
}
}
}
小结
合规不是一次改完的事,是持续建设的工程能力。把"用户数据生命周期"画出来——采集、上报、存储、查询、删除,每个环节都有 SOP、可审计、可回滚。系统化做半年后,审核、市场、用户、监管四方都可以交代得过去。
下一篇聊 Android Studio Memory Insights——内存抖动之后的下一步:怎么用 Android Studio 自带工具做深度分析。
参考阅读
个人信息保护法(PIPL)原文
GDPR 官方法律文本
Google Play:Data Safety Form