Advertising ID(AAID)已被弃用,替代方案是什么?

解读

国内面试问“AAID 被弃用”并不是考你“Google 把字段删了”这种表面新闻,而是考察三件事:

  1. 是否知道 2021 年起国内主流渠道(华为、OPPO、vivo、小米、荣耀)已强制使用 OAID 作为广告标识,AAID 仅对海外 GMS 生效;
  2. 是否理解 OAID 与 AAID 在获取方式、权限模型、用户重置路径上的差异;
  3. 能否给出合规代码:既要能拿到 OAID,又要在用户关闭“个性化广告”时立刻回退到全 0,同时兼顾 Android 13 及以上版本对 READ_MEDIA_IMAGES 等新权限的连锁影响。
    答不出“OAID + 可关闭 + 零值回退”这三点,基本会被判定为“只会 Google 官方 Demo,没做过国内上架”。

知识点

  1. 国内移动安全联盟(MSA)统一标准:OAID(Open Anonymous Device Identifier)

    • 定义:非永久性、可重置、全域唯一,32 位明文字符串,首字节固定 1-9 避免与 AAID 冲突。
    • 获取入口:各厂商 SDK 统一接口 IdentifierManager.getOAID(context, callback),回调在子线程。
    • 权限要求:无敏感权限,但需在清单声明 com.asus.msa.SupplementaryDID.ACCESS(ASUS)、com.huawei.android.launcher.permission.READ_SETTINGS(华为)等厂商自定义权限,否则返回全 0。
    • 用户关闭路径:系统设置-隐私-广告-“限制广告跟踪”开关,一旦关闭 SDK 必须返回 00000000-0000-0000-0000-000000000000,与 AAID 的“opt-out”语义一致。
  2. 海外 GMS 场景:AAID 并未真正“废弃”,只是 Android 12 以后获取需要 com.google.android.gms.permission.AD_ID 权限,且 2022 年底 Google Play 要求 targetSdk≥33 时必须声明用途才能拿到。国内无 GMS,故可视为“国内已弃用”。

  3. 合规兜底:当 OAID 取不到或用户关闭时,只能使用 0 串,禁止自建 ID(IMEI、MAC、SN、AndroidID)做广告关联,否则应用市场审核会被判“违规收集个人信息”,直接下架。

  4. 技术实现细节

    • 同步转异步:MSA SDK 回调在 Binder 线程,需 Handler(Looper.getMainLooper()).post {} 切回主线程再写入缓存。
    • 缓存策略:OAID 写入私有 SP 并加密(AndroidKeyStore AES256+GCM),避免每次冷启动调用 SDK 造成 100 ms 以上阻塞。
    • 版本兼容:Android 13 开始 READ_PHONE_STATE 升级为 READ_BASIC_PHONE_STATE,但 OAID 本身不依赖,因此需把旧权限声明全部移除,防止商店扫描误报。
  5. 测试验证

    • 真机关闭“个性化广告”后,必须打印 00000000-0000-0000-0000-000000000000
    • 恢复开关后,需拿到新的 32 位字符串,且两次取值不同(证明可重置)。

答案

国内环境 AAID 已名存实亡,替代方案是遵循 MSA 统一标准的 OAID。
获取流程:

  1. 集成最新版 MSA SDK(如 1.2.0),在 Application#onCreate 中调用
    IdentifierManager.getOAID(context) { oaid -> if (oaid.isNullOrBlank() || oaid == ZERO_OAID) { // 用户已关闭个性化广告,停止追踪 adTrackEnabled = false } else { // 加密后落盘,用于广告归因 encryptedOAID = encrypt(oaid) } }
  2. 清单文件按需声明厂商权限,但绝不申请 IMEI、MAC 等硬件标识;
  3. 运行期监听系统广播 android.msa.action.OAID_RESET,收到后立刻清空本地缓存并重新拉取;
  4. 上架前通过华为、小米、OPPO 提供的隐私检测工具扫描,确保“广告标识符”一栏仅出现 OAID 且可关闭。

一句话总结:国内广告标识已全面转向 OAID,开发层面就是“集成 MSA SDK → 拿 OAID → 可关闭 → 不合规就回退 0”,同时把 AAID 相关代码分支直接删除,避免审核踩坑。

拓展思考

  1. 如果公司同时做海外 Google Play 与国内渠道双包,如何一套代码兼容 AAID 与 OAID?
    答:在 AdvertisingIdHelper 内部做区域路由:

    • 当检测到 GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == SUCCESS 且当前 IP 非大陆,走 AdvertisingIdClient.getAdvertisingIdInfo(context)
    • 否则走 OAID 逻辑;
    • 两者接口统一返回 AdIdResult(id: String?, isLimitAdTrackingEnabled: Boolean),上层业务无感知。
  2. Android 14 引入“选装照片”与“部分文件权限”后,MSA SDK 在部分机型出现拿不到 OAID 的异常,如何兜底?
    答:在 SDK 回调超时(500 ms)后,降级使用 UUID.randomUUID().toString() 生成一次性的 SessionAdID,仅用于本次冷启动内的广告请求,进程被杀即失效,既满足归因,又避免持久化违规。

  3. 未来趋势:工信部正在推进 “OAID 3.0”,支持服务端二次加盐哈希,应用端只能拿到不可逆的 S-OAID;作为开发者需要把现有归因逻辑从“明文 OAID”迁移到“S-OAID + 服务端映射”,并提前在埋点通道预留字段,防止政策落地后被动改造。