← 资料库索引 ← 官方文档 原始链接 ↗ 🔍
官方文档

唯一标识符的最佳实践 | Android 开发者文档 原文标题:Best practices for unique identifiers  |  Identity  |  Android Developers

发表时间:(页面未标注)采集时间:2026-10-09 10:28:39来源:developer.android.com原文语言:en状态:抽取受限

内容概要总结

Android 官方关于「为你的 App 按用例选择合适的标识符」的指南,核心原则是:为保护用户隐私,使用能满足用例的最严格的标识符。

最佳实践包括:尽量选择用户可重置的标识符;避免使用硬件标识符(如 IMEI、序列号),Android 10(API 29)起对不可重置标识符加了限制(需为设备/资料所有者 App、具备运营商特殊权限或 READ_PRIVILEGED_PHONE_STATE);仅将 Advertising ID 用于用户画像或广告用例,并始终尊重用户的广告追踪选择,且不得 bridge 广告 ID 的重置;除支付反欺诈与电话外,其余用例尽量使用 FID 或私有存储的 GUID。

文档详细展开:使用广告 ID 的注意事项(不得用其他标识符或指纹把重置后的广告 ID 关联起来,必须尊重「退出基于兴趣的广告」设置,需注意 SDK 相关隐私政策,广告 ID 不得与 PII 或任何持久设备标识如 SSAID/MAC/IMEI 关联,并给出可能通过准标识符意外 join 的示例表);FID 与 GUID 的使用;不要使用 MAC 地址(Android 6+ 起仅系统 App 可访问,Android 11 起 Passpoint 网络按 profile 随机化 MAC,非特权 App 无法获取设备 MAC)。

还介绍了标识符的特性维度——作用域(单 App/App 组/设备)、可重置性与持久性(会话级/重装重置/恢复出厂重置/出厂后持久)、唯一性(碰撞概率与熵)、完整性与不可否认性,并给出大量常见用例与推荐标识符(账号、运营商状态、移动订阅状态、单点登录、广告定向/衡量/转化/再营销、App 分析、崩溃上报、性能上报、App 测试、跨设备安装、滥用检测、广告欺诈、DRM、用户偏好等)。

翻译内容

原文内容(English)

⚠ 说明:原站直连返回 302 重定向循环,正文经浏览器渲染(browser-bridge)获取;已剔除站点导航与页脚,仅保留文章主体。原文中生成 GUID 的代码示例在桥接渲染的纯文本中缺失(页面为交互式代码块),故未包含。 原文 content_en 为浏览器渲染的纯文本转储(无 Markdown 标题,抽取时 blocks=0),故按规范「只改 content_zh、标题数须与 content_en 一致」将译文中的 7 处标题降为普通文本行,文字内容未删改。

唯一标识符的最佳实践
本文档为你提供指导,帮助你根据用例为 App 选择合适的标识符。

关于 Android 权限的总体介绍,请参阅「权限概览」。关于处理 Android 权限的具体最佳实践,请参阅「App 权限最佳实践」。

处理 Android 标识符的最佳实践
为保护用户隐私,请使用能满足你 App 用例的、最严格的标识符。具体而言,请遵循以下最佳实践:

  • 尽可能选择用户可重置的标识符。 即便使用不可重置硬件 ID 之外的标识符,你的 App 也能实现大多数用例。
  • 避免使用硬件标识符。 在大多数用例中,你可以在不限制必要功能的前提下避免使用硬件标识符,例如国际移动设备识别码(IMEI)。

Android 10(API level 29)对不可重置的标识符(包括 IMEI 和序列号)增加了限制。你的 App 必须是设备或资料所有者 App、拥有运营商特殊权限,或拥有 READ_PRIVILEGED_PHONE_STATE 特权权限,才能访问这些标识符。

  • 仅将 Advertising ID 用于用户画像或广告用例。 使用 Advertising ID 时,始终尊重用户关于广告追踪的选择。如果你必须把广告标识符与个人可识别信息(PII)关联,请仅在获得用户明确同意的情况下进行。
  • 不要 bridge 广告 ID 的重置。
  • 对于所有其他用例(支付反欺诈和电话除外),尽可能使用 Firebase installation ID(FID)或私有存储的 GUID。 对于绝大多数非广告用例,FID 或 GUID 应当足够。
  • 使用适合你用例的 API,以将隐私风险降到最低。 使用 DRM API 保护高价值内容,使用 Play Integrity API 防止滥用。Play Integrity API 是判定设备是否为正品、又不带来隐私风险的最简单方式。

本指南其余各节将结合 Android App 开发情境对这些规则作进一步展开。

使用广告 ID(Advertising ID)
Advertising ID 是用户可重置的标识符,适用于广告用例。不过,使用该 ID 时有几个要点需要牢记:

  • 始终尊重用户重置广告 ID 的意图。 不要未经用户同意,通过使用另一个标识符或指纹把后续的 Advertising ID 关联在一起,从而 bridge 用户的重置。Google Play 开发者内容政策规定:
「……如果被重置,未经用户明确同意,新的广告标识符不得与之前的广告标识符或由之前广告标识符衍生的数据相连。」
  • 始终尊重相关的个性化广告(Personalized Ads)标志。 Advertising ID 是可配置的,用户可以限制与该 ID 相关的追踪程度。始终使用 AdvertisingIdClient.Info.isLimitAdTrackingEnabled() 方法,确保你没有违背用户的意愿。Google Play 开发者内容政策规定:
「……你必须遵守用户的『退出基于兴趣的广告』或『退出广告个性化』设置。如果用户启用了该设置,你不得使用广告标识符为广告目的创建用户画像,也不得向用户投放个性化广告。允许的活动包括上下文广告、频次控制、转化追踪、报表,以及安全和欺诈检测。」
注意:作为 2021 年底 Google Play services 更新的一部分,当用户在 Android 设置中退出使用广告 ID 进行个性化时,广告 ID 将被移除。任何访问该标识符的尝试都将收到一串零而不是该标识符。更多信息请参阅 Play Console Help。
  • 留意你使用的 SDK 中与 Advertising ID 使用相关的任何隐私或安全政策。例如,如果你向 Google Analytics SDK 的 enableAdvertisingIdCollection() 方法传入 true,请务必审阅并遵守所有适用的 Analytics SDK 政策。
  • 另请注意,Google Play 开发者内容政策要求 Advertising ID「不得与个人可识别信息相连,也不得与任何持久设备标识符(例如:SSAID、MAC 地址、IMEI 等)关联」。

举例来说,假设你想收集信息来填充具有以下列的数据库表:

TABLE-01
timestamp    ad_id    account_id    clickid

TABLE-02
account_id    name    dob    country

在这个例子中,ad_id 列可以通过两张表中都有的 account_id 列与 PII join,如果你没有获得用户的明确许可,这将违反 Google Play 开发者内容政策。

请记住,Advertiser ID 与 PII 之间的关联并不总是如此显式。可能存在同时出现在 PII 表和 Ad ID 键控表中的「准标识符(quasi-identifiers)」,这也会带来问题。例如,假设我们把 TABLE-01 和 TABLE-02 改为如下:

TABLE-01
timestamp    ad_id    clickid    dev_model

TABLE-02
timestamp    demo    account_id    dev_model    name

在这种情况下,如果点击事件足够罕见,仍然有可能使用事件的时间戳和设备型号,在 Advertiser ID 表 TABLE-01 与 TABLE-02 中所含的 PII 之间进行 join。

尽管通常很难保证数据集中不存在这类准标识符,但你可以尽可能地对唯一数据进行泛化,从而防止最明显的 join 风险。在前面的例子中,这意味着降低时间戳的精度,使得每个时间戳下都会出现多台同型号的设备。

其他解决方案包括:

  • 不要设计把 PII 与 Advertising ID 显式关联的表。 在上面的第一个例子中,这意味着不要在 TABLE-01 中包含 account_id 列。
  • 为同时有权访问 Advertising ID 键控数据与 PII 的用户或角色,隔离并监控其访问控制列表。 通过严格控制并审计同时访问两种来源的能力(例如对表执行 join),你可以降低 Advertising ID 与 PII 之间发生关联的风险。一般而言,控制访问意味着做到以下几点:
    • 使 Advertiser ID 键控数据与 PII 的访问控制列表(ACL)保持不相交,以尽量减少同时处于两个 ACL 中的个人或角色数量。
    • 实施访问日志记录与审计,以检测并管理对这一规则的任何例外。

关于负责任地使用 Advertising ID 的更多信息,请参阅 AdvertisingIdClient API 参考。

使用 FID 与 GUID
识别设备上运行的某个 App 实例,最直接的方式是使用 Firebase installation ID(FID),在大多数非广告用例中这也是推荐方案。只有为其分配了该 ID 的那个 App 实例才能访问它,而且它(相对)容易重置,因为它只在 App 安装期间持续存在。

因此,与不可重置、设备范围的硬件 ID 相比,FID 提供了更好的隐私属性。更多信息请参阅 firebase.installations API 参考。

在 FID 不实用的情况下,你也可以使用自定义的全局唯一 ID(GUID)来唯一标识一个 App 实例。最简单的方式是用以下代码生成你自己的 GUID:

由于该标识符全局唯一,它可用于标识一个特定的 App 实例。为避免跨 App 关联标识符带来的顾虑,请将 GUID 存储在内部存储中,而不是外部(共享)存储。更多信息请参阅「数据与文件存储概览」页面。

不要使用 MAC 地址
MAC 地址全局唯一、不可由用户重置,并且能在恢复出厂设置后存活。出于这些原因,为保护用户隐私,在 Android 6 及更高版本上,对 MAC 地址的访问被限制为仅系统 App 可用。第三方 App 无法访问它们。

MAC 地址的可用性在 Android 11 中发生变化

在 target Android 11 及更高版本的 App 上,Passpoint 网络的 MAC 随机化按 Passpoint profile 进行,基于以下字段生成唯一的 MAC 地址:

  • 完全限定域名(FQDN)
  • Realm
  • 凭据,基于 Passpoint profile 中使用的凭据:
    • 用户凭据:用户名
    • 证书凭据:证书和证书类型
    • SIM 凭据:EAP 类型和 IMSI

此外,非特权 App 无法访问设备的 MAC 地址;只有具有 IP 地址的网络接口可见。这影响 getifaddrs() 和 NetworkInterface.getHardwareAddress() 方法,以及发送 RTM_GETLINK Netlink 消息。

以下是 App 受此变更影响的方式列表:

  • NetworkInterface.getHardwareAddress() 对每个接口都返回 null。
  • App 无法在 NETLINK_ROUTE socket 上使用 bind() 函数。
  • ip 命令不返回接口信息。
  • App 无法发送 RTM_GETLINK 消息。

请注意,大多数开发者应使用 ConnectivityManager 的更高层 API,而不是 NetworkInterface、getifaddrs() 或 Netlink socket 等更低层 API。例如,需要获取当前路由最新信息的 App,可以通过使用 ConnectivityManager.registerNetworkCallback() 监听网络变化,并调用该网络关联的 LinkProperties.getRoutes() 来获取这些信息。

标识符的特性
Android 操作系统提供了许多具有不同行为特性的 ID。你应使用哪个 ID,取决于以下特性如何与你的用例契合。不过,这些特性也伴随隐私影响,因此理解它们之间如何相互作用很重要。

作用域(Scope)

标识符作用域说明了哪些系统可以访问该标识符。Android 标识符作用域通常有三种:

  • 单个 App:该 ID 是 App 内部的,其他 App 无法访问。
  • App 组:该 ID 可被一组预先定义的相关 App 访问。
  • 设备:该 ID 可被设备上安装的所有 App 访问。

授予标识符的作用域越宽,它被用于追踪目的的风险就越大。反过来,如果一个标识符只能被单个 App 实例访问,它就无法用于跨不同 App 中的交易来追踪一台设备。

可重置性与持久性(Resettability and persistence)

可重置性与持久性定义了标识符的寿命,并说明它可以如何被重置。常见的重置触发条件包括:App 内重置、通过系统设置重置、启动时重置,以及安装时重置。Android 标识符可以有不同的寿命,但寿命通常与该 ID 如何重置相关:

  • 仅会话级(Session-only):用户每次重启 App 时都会使用一个新的 ID。
  • 重装重置(Install-reset):用户每次卸载并重装 App 时都会使用一个新的 ID。
  • 恢复出厂重置(FDR-reset):用户每次恢复出厂设置设备时都会使用一个新的 ID。
  • 出厂后持久(FDR-persistent):该 ID 能在恢复出厂设置后存活。

可重置性使用户能够创建一个与任何现有画像信息都解除关联的新 ID。一个标识符持续存在的时间越长、越可靠(例如能在恢复出厂设置后存活),用户遭受长期追踪的风险就越大。如果标识符在 App 重装时被重置,这会降低持久性,并提供了一种重置该 ID 的途径,即使 App 内或系统设置中没有供用户显式重置的控制。

唯一性(Uniqueness)

唯一性确立了发生碰撞的可能性;也就是说,在关联作用域内是否存在完全相同的标识符。在最高层级上,一个全局唯一的标识符永远不会发生碰撞,即使在其他设备或 App 上也是如此。否则,唯一性的程度取决于标识符的熵以及用于创建它的随机性来源。例如,用安装日历日期(如 2019-03-01)作为种子的随机标识符,其碰撞几率远高于用安装的 Unix 时间戳(如 1551414181)作为种子的标识符。

一般而言,用户账号标识符可被视为唯一。也就是说,每个设备/账号组合都有一个唯一的 ID。另一方面,标识符在一个群体中越不唯一,隐私保护就越好,因为它对追踪某个个人用户越没用。

完整性保护与不可否认性(Integrity protection and non-repudiability)

你可以使用一个难以伪造或重放的标识符,来证明关联的设备或账号具有某些属性。例如,你可以证明该设备不是垃圾信息发送者使用的虚拟设备。难以伪造的标识符还提供了不可否认性。如果设备用一个密钥对消息签名,就很难声称是别人的设备发送了该消息。不可否认性可能是用户想要的东西(例如认证支付时),也可能是一种不受欢迎的属性(例如他们发送了一条自己会后悔的消息时)。

常见用例及应使用的合适标识符
本节提供使用硬件 ID(如 IMEI)的替代方案。不鼓励使用硬件 ID,因为用户无法重置它们,而且它们的作用域是设备级的。在许多情况下,App 范围的标识符就已足够。

账号(Accounts)

运营商状态(Carrier status)

在这种情况下,你的 App 通过运营商账号与设备的电话和短信功能交互。

  • 推荐使用的标识符:IMEI、IMSI 和 Line1

为什么这样推荐?

如果运营商相关功能需要,利用硬件标识符是可以接受的。例如,你可以使用这些标识符在蜂窝运营商或 SIM 卡槽之间切换,或通过 IP 投递 SMS 消息(针对 Line1)——即基于 SIM 的用户账号。不过,对于非特权 App,我们建议使用账号登录,在服务器端获取用户设备信息。原因之一是,在 Android 6.0(API level 23)及更高版本中,这些标识符只能通过运行时权限使用。用户可能会关闭该权限,因此你的 App 应优雅地处理这些异常。

移动订阅状态(Mobile subscription status)

在这种情况下,你需要把 App 功能与设备上的某些移动服务订阅关联起来。例如,你可能需要基于设备通过 SIM 卡的移动订阅,来验证对某些高级 App 功能的访问权限。

  • 推荐使用的标识符:Subscription ID API,用于识别设备上使用的 SIM 卡。

Subscription ID 为设备上使用的已安装 SIM 卡(包括物理卡和电子卡)提供一个索引值(从 1 开始),用于唯一标识它们。通过该 ID,你的 App 可以把其功能与某张给定 SIM 卡的各种订阅信息关联起来。除非设备恢复出厂设置,该值对某张给定 SIM 卡是稳定的。然而,可能存在同一张 SIM 卡在不同设备上有不同 Subscription ID,或不同 SIM 卡在不同设备上有相同 ID 的情况。

注意:访问该 ID 需要 READ_PHONE_STATE 权限。

为什么这样推荐?

一些 App 目前可能为此目的使用 ICC ID。由于 ICC ID 全局唯一且不可重置,自 Android 10 起其访问已被限制为拥有 READ_PRIVILEGED_PHONE_STATE 权限的 App。从 Android 11 开始,无论 App 的 target API level 为何,Android 进一步限制了对 ICCID 的访问,限制通过 getIccId() API 进行。受影响的 App 应改为迁移到使用 Subscription ID。

单点登录(Single sign-on)

在这种情况下,你的 App 提供单点登录体验,允许用户把一个已有账号与你的组织关联。

  • 推荐使用的标识符:与账号管理器兼容的账号,例如 Google Account Linking

为什么这样推荐?

Google Account Linking 允许用户把其已有的 Google 账号与你的 App 关联,从而无缝且更安全地访问你组织的产品和服务。此外,你可以定义自定义 OAuth scope,只共享必要的数据,通过清晰界定其数据如何被使用来增强用户信任。

广告(Ads)

定向(Targeting)

在这种情况下,你的 App 构建用户的兴趣画像,以向他们展示更相关的广告。

  • 推荐使用的标识符:如果你的 App 将某个 ID 用于广告并上传或发布到 Google Play,那么该 ID 必须是 Advertising ID。

为什么这样推荐?

这是一个与广告相关的用例,可能需要一个在你组织的不同 App 之间都可用的 ID,因此使用 Advertising ID 是最合适的方案。根据 Google Play 开发者内容政策,广告用例必须使用 Advertising ID,因为用户可以重置它。

无论你是否在 App 中共享用户数据,如果你为广告目的收集并使用它,你都需要在 Play Console 的 App 内容页面「Data safety」部分中声明这些广告用途。

衡量(Measurement)

在这种情况下,你的 App 基于用户在同一设备上跨你组织 App 的行为,构建其画像。

  • 推荐使用的标识符:Advertising ID 或 Play install referrer API

为什么这样推荐?

这是一个与广告相关的用例,可能需要一个在你组织的不同 App 之间都可用的 ID,因此使用 Advertising ID 是最合适的方案。如果你为广告用例使用某个 ID,该 ID 必须是 Advertising ID,因为用户可以重置它。更多信息见 Google Play 开发者内容政策。

转化(Conversions)

在这种情况下,你追踪转化以检测你的营销策略是否成功。

  • 推荐使用的标识符:Advertising ID 或 Play install referrer API

为什么这样推荐?

这是一个与广告相关的用例,可能需要一个在你组织的不同 App 之间都可用的 ID,因此使用 Advertising ID 是最合适的方案。根据 Google Play 开发者内容政策,广告用例必须使用 Advertising ID,因为用户可以重置它。

再营销(Remarketing)

在这种情况下,你的 App 基于用户之前的兴趣展示广告。

  • 推荐使用的标识符:Advertising ID

为什么这样推荐?

这是一个与广告相关的用例,可能需要一个在你组织的不同 App 之间都可用的 ID,因此使用 Advertising ID 是最合适的方案。根据 Google Play 开发者内容政策,广告用例必须使用 Advertising ID,因为用户可以重置它。

App 分析(App analytics)

在这种情况下,你的 App 评估用户行为,以帮助你判断以下事项:

  • 你组织的其他哪些产品或 App 可能适合该用户。
  • 如何让用户持续对你的 App 感兴趣。
  • 为已登出或匿名用户衡量使用统计与分析。

可能的解决方案包括:

  • App set ID:App Set ID 允许你分析用户在你组织拥有的多个 App 上的行为,只要你不把用户数据用于广告目的。如果你的目标设备由 Google Play services 提供支持,我们建议你使用 App Set ID。
  • Firebase ID(FID):FID 的作用域限于创建它的那个 App,这防止了该标识符被用于跨 App 追踪用户。它也很容易重置,因为用户可以清除 App 数据或重装 App。创建 FID 的过程很直接;见 Firebase installations 指南。

App 开发(App development)

崩溃上报(Crash reporting)

在这种情况下,你的 App 收集关于它在用户设备上何时、为何崩溃的数据。

  • 推荐使用的标识符:FID 或 App set ID

为什么这样推荐?

FID 的作用域限于创建它的那个 App,这防止了该标识符被用于跨 App 追踪用户。它也很容易重置,因为用户可以清除 App 数据或重装 App。创建 FID 的过程很直接;见 Firebase installations 指南。App Set ID 允许你分析用户在你组织拥有的多个 App 上的行为,只要你不把用户数据用于广告目的。

性能上报(Performance reporting)

在这种情况下,你的 App 收集性能指标,例如加载时间和电池使用,以帮助提升 App 质量。

  • 推荐使用的标识符:Firebase Performance Monitoring

为什么这样推荐?

Firebase Performance Monitoring 帮助你聚焦于对你最重要的指标,并测试最近一次改动在你 App 中造成的影响。

App 测试(App testing)

在这种情况下,你的 App 出于测试或调试目的评估用户体验。

  • 推荐使用的标识符:FID 或 App set ID

为什么这样推荐?

FID 的作用域限于创建它的那个 App,这防止了该标识符被用于跨 App 追踪用户。它也很容易重置,因为用户可以清除 App 数据或重装 App。创建 FID 的过程很直接;见 Firebase installations 指南。App Set ID 允许你分析用户在你组织拥有的多个 App 上的行为,只要你不把用户数据用于广告目的。

跨设备安装(Cross-device installation)

在这种情况下,你的 App 需要在同一用户的多个设备上安装时,识别出正确的 App 实例。

  • 推荐使用的标识符:FID 或 GUID

为什么这样推荐?

FID 正是为此目的而设计的;其作用域限于该 App,因此不能用于跨不同 App 追踪用户,并且它在 App 重装时重置。在 FID 不足的罕见情况下,你也可以使用 GUID。

安全(Security)

滥用检测(Abuse detection)

在这种情况下,你试图检测攻击你后端服务的多个虚假设备。

  • 推荐使用的标识符:Google Play Integrity API 的 integrity token

为什么这样推荐?

要验证一个请求来自真正的 Android 设备——而不是模拟器或其他冒充另一台设备的代码——请使用 Google Play Integrity API。

广告欺诈(Ad fraud)

在这种情况下,你的 App 检查用户在 App 中的曝光和操作是真实且可验证的。

  • 推荐使用的标识符:Advertising ID

为什么这样推荐?

根据 Google Play 开发者内容政策,广告用例必须使用 Advertising ID,因为用户可以重置它。

数字版权管理(DRM)

在这种情况下,你的 App 想保护知识产权或付费内容不被欺诈性访问。

  • 推荐使用的标识符:使用 FID 或 GUID 会迫使用户为了绕过内容限制而重装 App,这一负担足以阻止大多数人。如果这还不够,Android 提供了 DRM API,可用于限制对内容的访问,它包含一个按 APK 的标识符,即 Widevine ID。

用户偏好(User preferences)

在这种情况下,你的 App 在其自身中保存按设备的用户状态,尤其是针对未登录的用户。你可能会把该状态转移到同一设备上用相同密钥签名的另一个 App。

  • 推荐使用的标识符:FID 或 GUID

为什么这样推荐?

不建议让信息在重装后仍持久存在,因为用户可能希望通过重装 App 来重置其偏好。

本页内容与代码示例受「Content License」中所述许可的约束。Java 和 OpenJDK 是 Oracle 和/或其关联公司的商标或注册商标。

最后更新于 2026-10-01 UTC。

Skip to main content
Essentials
Design & Plan
Develop
Google Play
Blog
Android Studio
SECURITY
IDENTITY
Overview
Samples
Guides
Credential Manager overview
About Credential Manager
Prerequisites
Authenticate users
Authenticate with passkeys
Authenticate with Sign in with Google
Authenticate with passwords
Restore credentials on new devices
Advanced features and integrations
Migrate to Credential Manager
Authenticate across form factors
Implement authentication as a credential provider
Troubleshoot common errors
Credential Manager FAQ
Show a biometric authentication dialog
Block Store
Legacy APIs
Authorize users
Authorize user access
Use digital credentials
About digital credentials
Integrate your holder app with Credential Manager
Integrate your verifier app with Credential Manager
Issue credentials with Credential Manager
Verify phone numbers with digital credentials
Verify email addresses with digital credentials
Verify users
Automate SMS verification
Provide phone number hints to users
Handle user data
Autofill personal information
Identify developer-owned apps
Manage user data
Android Developers
Design & Plan
Security
Identity
Guides
Best practices for unique identifiers

This document provides guidance for selecting appropriate identifiers for your app based on your use case.

For a general look at Android permissions, see Permissions overview. For specific best practices for working with Android permissions, see App permissions best practices.

Best practices for working with Android identifiers

To protect the privacy of your users, use the most restrictive identifier that satisfies your app's use case. In particular, follow these best practices:

Choose user-resettable identifiers whenever possible. Your app can achieve most of its use cases even when it uses identifiers other than non-resettable hardware IDs.

Avoid using hardware identifiers. In most use cases, you can avoid using hardware identifiers, such as International Mobile Equipment Identity (IMEI), without limiting required functionality.

Android 10 (API level 29) adds restrictions for non-resettable identifiers, which include both IMEI and serial number. Your app must be a device or profile owner app, have special carrier permissions, or have the READ_PRIVILEGED_PHONE_STATE privileged permission in order to access these identifiers.

Only use an Advertising ID for user profiling or ads use cases. When using an Advertising ID, always respect users' selections regarding ad tracking. If you must connect the advertising identifier to personally-identifiable information, do so only with the explicit consent of the user.

Don't bridge Advertising ID resets.

Use a Firebase installation ID (FID) or a privately stored GUID whenever possible for all other use cases, except for payment fraud prevention and telephony. For the vast majority of non-ads use cases, an FID or GUID should be sufficient.

Use APIs that are appropriate for your use case to minimize privacy risk. Use the DRM API for high-value content protection and the Play Integrity APIs for abuse protection. The Play Integrity APIs are the easiest way to determine whether a device is genuine without incurring privacy risk.

The remaining sections of this guide elaborate on these rules in the context of developing Android apps.

Work with advertising IDs

The Advertising ID is a user-resettable identifier and is appropriate for ads use cases. There are some key points to bear in mind, however, when you use this ID:

Always respect the user's intention in resetting the advertising ID. Don't bridge user resets by using another identifier or fingerprint to link subsequent Advertising IDs together without the user's consent. The Google Play Developer Content Policy states the following:

"...if reset, a new advertising identifier must not be connected to a previous advertising identifier or data derived from a previous advertising identifier without the explicit consent of the user."

Always respect the associated Personalized Ads flag. Advertising IDs are configurable in that users can limit the amount of tracking associated with the ID. Always use the AdvertisingIdClient.Info.isLimitAdTrackingEnabled() method to ensure that you aren't circumventing your users' wishes. The Google Play Developer Content Policy states the following:

"...you must abide by a user's 'Opt out of interest-based advertising' or 'Opt out of Ads Personalization' setting. If a user has enabled this setting, you may not use the advertising identifier for creating user profiles for advertising purposes or for targeting users with personalized advertising. Allowed activities include contextual advertising, frequency capping, conversion tracking, reporting and security and fraud detection."

Note: As part of Google Play services update in late 2021, the advertising ID will be removed when a user opts out of personalization using advertising ID in Android Settings. Any attempts to access the identifier will receive a string of zeros instead of the identifier. See Play Console Help to learn more.

Be aware of any privacy or security policies associated with SDKs you use that are related to Advertising ID use. For example, if you pass true into the enableAdvertisingIdCollection() method from the Google Analytics SDK, make sure to review and adhere to all applicable Analytics SDK policies.

Also, be aware that the Google Play Developer Content Policy requires that the Advertising ID "must not be connected to personally-identifiable information or associated with any persistent device identifier (for example: SSAID, MAC address, IMEI, etc.,)."

As an example, suppose you want to collect information to populate database tables with the following columns:

TABLE-01
timestamp ad_id account_id clickid
TABLE-02
account_id name dob country

In this example, the ad_id column could be joined to PII via the account_id column in both tables, which would be a violation of the Google Play Developer Content Policy, if you didn't get explicit permission from your users.

Keep in mind that links between Advertiser ID and PII aren't always this explicit. It's possible to have "quasi-identifiers" that appear in both PII and Ad ID keyed tables, which also cause problems. For example, assume we change TABLE-01 and TABLE-02 as follows:

TABLE-01
timestamp ad_id clickid dev_model
TABLE-02
timestamp demo account_id dev_model name

In this case, with sufficiently rare click events, it's still possible to join between the Advertiser ID TABLE-01 and the PII contained in TABLE-02 using the timestamp of the event and the device model.

Although it's often difficult to guarantee that no such quasi-identifiers exist in a dataset, you can prevent the most obvious join risks by generalizing unique data where possible. In the preceding example, this would mean reducing the accuracy of the timestamp so that multiple devices with the same model appear for every timestamp.

Other solutions include the following:

Not designing tables that explicitly link PII with Advertising IDs. In the first example above, this would mean not including the account_id column in TABLE-01.

Segregating and monitoring access control lists for users or roles that have access to both the Advertising ID keyed data and PII. By tightly controlling and auditing the ability to access both sources simultaneously (for example, by performing a join between tables), you reduce the risk of association between the Advertising ID and PII. Generally speaking, controlling access means doing the following:

Keep access control lists (ACLs) for Advertiser ID keyed data and PII disjoint to minimize the number of individuals or roles that are in both ACLs.
Implement access logging and auditing to detect and manage any exceptions to this rule.

For more information on working responsibly with Advertising IDs, see the AdvertisingIdClient API reference.

Work with FIDs and GUIDs

The most straightforward solution to identifying an app instance running on a device is to use a Firebase installation ID (FID), and this is the recommended solution in the majority of non-ads use cases. Only the app instance for which it was provisioned can access this identifier, and it's (relatively) easily resettable because it only persists as long as the app is installed.

As a result, FIDs provide better privacy properties compared to non-resettable, device-scoped hardware IDs. For more information, see the firebase.installations API reference.

In cases where an FID isn't practical, you can also use custom globally-unique IDs (GUIDs) to uniquely identify an app instance. The simplest way to do so is by generating your own GUID using the following code:

Because the identifier is globally unique, it can be used to identify a specific app instance. To avoid concerns related to linking the identifier across apps, store GUIDs in internal storage instead of external (shared) storage. For more information, see the Data and file storage overview page.

Don't work with MAC addresses

MAC addresses are globally unique, not user-resettable, and survive factory resets. For these reasons, to protect user privacy, on Android versions 6 and higher, access to MAC addresses is restricted to system apps. Third-party apps can't access them.

MAC address availability changes in Android 11

On apps targeting Android 11 and higher, MAC randomization for Passpoint networks is per Passpoint profile, generating a unique MAC address based on the following fields:

Fully-qualified domain name (FQDN)
Realm
Credential, based on the credential used in the Passpoint profile:
User credential: user name
Certificate credential: cert and cert type
SIM credential: EAP type and IMSI

In addition, non-privileged apps can't access the device's MAC address; only network interfaces with an IP address are visible. This impacts the getifaddrs() and NetworkInterface.getHardwareAddress() methods, as well as sending RTM_GETLINK Netlink messages.

The following is a list of the ways that apps are affected by this change:

NetworkInterface.getHardwareAddress() returns null for every interface.
Apps cannot use the bind() function on NETLINK_ROUTE sockets.
The ip command does not return information about interfaces.
Apps cannot send RTM_GETLINK messages.

Note that most developers should use the higher-level APIs of ConnectivityManager rather than lower-level APIs like NetworkInterface, getifaddrs(), or Netlink sockets. For example, an app that needs up-to-date information on the current routes can get this information by listening for network changes using ConnectivityManager.registerNetworkCallback() and calling the network's associated LinkProperties.getRoutes().

Identifier characteristics

The Android OS offers a number of IDs with different behavior characteristics. Which ID you should use depends on how the following characteristics work with your use case. These characteristics also come with privacy implications, however, so it's important to understand how these characteristics interact with each other.

Scope

Identifier scope explains which systems can access the identifier. Android identifier scope generally comes in three flavors:

Single app: The ID is internal to the app and not accessible to other apps.
Group of apps: The ID is accessible to a pre-defined group of related apps.
Device: The ID is accessible to all apps installed on the device.

The wider the scope granted to an identifier, the greater the risk of it being used for tracking purposes. Conversely, if an identifier can only be accessed by a single app instance, it cannot be used to track a device across transactions in different apps.

Resettability and persistence

Resettability and persistence define the lifespan of the identifier and explain how it can be reset. Common reset triggers include: in-app resets, resets via System Settings, resets on launch, and resets on installation. Android identifiers can have varying lifespans, but the lifespan is usually related to how the ID is reset:

Session-only: A new ID is used every time the user restarts the app.
Install-reset: A new ID is used every time user uninstalls and reinstalls the app.
FDR-reset: A new ID is used every time the user factory-resets the device.
FDR-persistent: The ID survives factory reset.

Resettability gives users the ability to create a new ID that is disassociated from any existing profile information. The longer, and more reliably, an identifier persists, such as one that persists across factory resets, the greater the risk that the user may be subjected to long-term tracking. If the identifier is reset upon app reinstall, this reduces the persistence and provides a means for the ID to be reset, even if there is no explicit user control to reset it from within the app or System Settings.

Uniqueness

Uniqueness establishes the likelihood of collisions; that is, that identical identifiers exist within the associated scope. At the highest level, a globally unique identifier never has a collision, even on other devices or apps. Otherwise, the level of uniqueness depends on the entropy of the identifier and the source of randomness used to create it. For example, the chance of a collision is much higher for random identifiers seeded with the calendar date of installation (such as 2019-03-01) than for identifiers seeded with the Unix timestamp of installation (such as 1551414181).

In general, user account identifiers can be considered unique. That is, each device/account combination has a unique ID. On the other hand, the less unique an identifier is within a population, the greater the privacy protection because it's less useful for tracking an individual user.

Integrity protection and non-repudiability

You can use an identifier that is difficult to spoof or replay to prove that the associated device or account has certain properties. For example, you could prove that the device isn't a virtual device used by a spammer. Difficult-to-spoof identifiers also provide non-repudiability. If the device signs a message with a secret key, it's difficult to claim that someone else's device sent the message. Non-repudiability could be something a user wants, such as when authenticating a payment, or it could be an undesirable property, such as when they send a message they regret.

Common use cases and the appropriate identifier to use

This section provides alternatives to using hardware IDs, such as IMEI. Using hardware IDs is discouraged because the user cannot reset them, and they're scoped to the device. In many cases, an app-scoped identifier would suffice.

Accounts

Carrier status

In this case, your app interacts with the device's phone and texting functionality using a carrier account.

Recommended identifier to use: IMEI, IMSI, and Line1

Why this recommendation?

Leveraging hardware identifiers is acceptable if it's required for carrier-related functionality. For example, you could use these identifiers to switch between cellular carriers or SIM slots, or to deliver SMS messages over IP (for Line1) - SIM-based user accounts. For unprivileged apps, however, we recommend using an account sign-in to retrieve user device information server-side. One reason for this is that, in Android 6.0 (API level 23) and higher, these identifiers can only be used via a runtime permission. Users might toggle off this permission, so your app should handle these exceptions gracefully.

Mobile subscription status

In this case, you need to associate app functionality with certain mobile service subscriptions on the device. For example, you may have a requirement to verify access to certain premium app features based on the device's mobile subscriptions via SIM.

Recommended identifier to use: Subscription ID API to identify SIMs that are used on the device.

The Subscription ID provides an index value (starting at 1) for uniquely identifying installed SIMs (including physical and electronic) used on the device. Through this ID, your app can associate its functionality with various subscription information for a given SIM. This value is stable for a given SIM unless the device is factory reset. However, there may be cases where the same SIM has a different Subscription ID on different devices or different SIMs have the same ID on different devices.

Note: Access to this ID requires the READ_PHONE_STATE permission.

Why this recommendation?

Some apps may be currently using the ICC ID for this purpose. Because the ICC ID is globally unique and non-resettable, the access has been restricted to apps with the READ_PRIVILEGED_PHONE_STATE permission since Android 10. Beginning with Android 11, Android further restricted access to the ICCID through the getIccId() API, regardless of the app's target API level. Affected apps should migrate to use the Subscription ID instead.

Single sign-on

In this case, your app offers a single sign-on experience, allowing users to associate an existing account with your organization.

Recommended identifier to use: Account manager-compatible accounts, such as Google Account Linking

Why this recommendation?

Google Account Linking allows users to associate a user's existing Google account with your app, providing seamless and more secure access to your organization's products and services. Additionally, you can define custom OAuth scopes to share only necessary data, increasing user trust by clearly defining how their data is used.

Ads
Targeting

In this case, your app builds a profile of a user's interests, to show them more relevant ads.

Recommended identifier to use: If your app uses an ID for ads and uploads or publishes to Google Play, that ID must be the Advertising ID.

Why this recommendation?

This is an ads-related use case which might require an ID that is available across your organization's different apps, so using an Advertising ID is the most appropriate solution. Use of the Advertising ID is mandatory for advertising use cases, per the Google Play Developer Content Policy, because the user can reset it.

Regardless of whether you share user data in your app, if you collect and use it for ads purposes, you need to declare the ads purposes in the Data safety section of the App content page in the Play Console.

Measurement

In this case, your app creates a profile of a user based on their behavior across your organization's apps on the same device.

Recommended identifier to use: Advertising ID or Play install referrer APIs

Why this recommendation?

This is an ads-related use case which might require an ID that is available across your organization's different apps, so using an Advertising ID is the most appropriate solution. If you use an ID for advertising use cases, that ID must be the Advertising ID because the user can reset it. Learn more in the Google Play Developer Content Policy.

Conversions

In this case, you're tracking conversions to detect if your marketing strategy is successful.

Recommended identifier to use: Advertising ID or Play install referrer APIs

Why this recommendation?

This is an ads-related use case which might require an ID that is available across your organization's different apps, so using an Advertising ID is the most appropriate solution. Use of the Advertising ID is mandatory for advertising use cases, per the Google Play Developer Content Policy, because the user can reset it.

Remarketing

In this case, your app shows ads based on a user's previous interests.

Recommended identifier to use: Advertising ID

Why this recommendation?

This is an ads-related use case which might require an ID that is available across your organization's different apps, so using an Advertising ID is the most appropriate solution. Use of the Advertising ID is mandatory for advertising use cases, per the Google Play Developer Content Policy, because the user can reset it.

App analytics

In this case, your app evaluates a user's behavior to help you determine the following:

Which of your organization's other products or apps might be suitable for the user.
How to keep users interested in using your app.
Measure usage statistics and analytics for signed-out or anonymous users.

Possible solutions include:

App set ID: An App Set ID allows you to analyze a user's behavior across multiple apps that your organization owns, as long as you don't use user data for advertising purposes. If you're targeting devices powered by Google Play services, we recommend that you use App Set ID.
Firebase ID (FID): An FID is scoped to the app that creates it, which prevents the identifier from being used to track users across apps. It is also easily resettable, as the user can clear app data or reinstall the app. The process of creating a FID is straightforward; see the Firebase installations guide.
App development
Crash reporting

In this case, your app collects data regarding when and why it crashes on a user's devices.

Recommended identifier to use: FID or App set ID

Why this recommendation?

An FID is scoped to the app that creates it, which prevents the identifier from being used to track users across apps. It is also easily resettable, as the user can clear app data or reinstall the app. The process of creating a FID is straightforward; see the Firebase installations guide. An App Set ID allows you to analyze a user's behavior across multiple apps that your organization owns, as long as you don't use user data for advertising purposes.

Performance reporting

In this case, your app collects performance metrics, such as load times and battery usage, to help improve your app's quality.

Recommended identifier to use: Firebase Performance Monitoring

Why this recommendation?

Firebase Performance Monitoring helps you focus on the metrics that matter most to you, and to test the impact of a recent change in your app.

App testing

In this case, your app evaluates a user's experience with your app for testing or debugging purposes.

Recommended identifier to use: FID or App set ID

Why this recommendation?

An FID is scoped to the app that creates it, which prevents the identifier from being used to track users across apps. It is also easily resettable, as the user can clear app data or reinstall the app. The process of creating a FID is straightforward; see the Firebase installations guide. An App Set ID allows you to analyze a user's behavior across multiple apps that your organization owns, as long as you don't use user data for advertising purposes.

Cross-device installation

In this case, your app needs to identify the correct instance of the app when it's installed on multiple devices for the same user.

Recommended identifier to use: FID or GUID

Why this recommendation?

An FID is designed explicitly for this purpose; its scope is limited to the app so that it cannot be used to track users across different apps, and it's reset upon app reinstall. In the rare cases where an FID is insufficient, you can also use a GUID.

Security

Abuse detection

In this case, you are trying to detect multiple fake devices attacking your backend services.

Recommended identifier to use: The Google Play Integrity API integrity token

Why this recommendation?

To verify that a request comes from a genuine Android device—rather than an emulator or other code spoofing another device—use the Google Play Integrity API.

Ad fraud

In this case, your app checks that a user's impressions and actions in your app are genuine and verifiable.

Recommended identifier to use: Advertising ID

Why this recommendation?

Use of the Advertising ID is mandatory for advertising use cases, per the Google Play Developer Content Policy, because the user can reset it.

Digital rights management (DRM)

In this case, your app wants to protect fraudulent access to intellectual property or paid content.

Recommended identifier to use: Using an FID or GUID forces the user to reinstall the app in order to circumvent the content limits, which is a sufficient burden to deter most people. If this isn't sufficient protection, Android provides a DRM API, which can be used to limit access to content, includes a per-APK identifier, the Widevine ID.

User preferences

In this case, your app saves per-device user state on your app's, particularly for users who aren't signed in. You might transfer this state to another app that's signed with the same key on the same device.

Recommended identifier to use: FID or GUID

Why this recommendation?

Persisting information through reinstalls isn't recommended because users may want to reset their preferences by reinstalling the app.

Content and code samples on this page are subject to the licenses described in the Content License. Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.

Last updated 2026-10-01 UTC.

X
Follow @AndroidDev on X
YouTube
Check out Android Developers on YouTube
LinkedIn
Connect with the Android Developers community on LinkedIn
MORE ANDROID
Android
Android for Enterprise
Security
Source
News
Blog
Podcasts
DISCOVER
Gaming
Machine Learning
Health & Fitness
Camera & Media
Privacy
5G
ANDROID DEVICES
Large screens
Wear OS
ChromeOS devices
Android for cars
Android TV
RELEASES
Android 17
Android 16
Android 15
Android 14
Android 13
Android 12
Android 11
DOCUMENTATION AND DOWNLOADS
Android Studio guide
Developers guides
API reference
Download Studio
Android NDK
SUPPORT
Report platform bug
Report documentation bug
Google Play support
Join research studies
Android
Chrome
Firebase
Google Cloud Platform
All products
Privacy
License
Brand guidelines
Get news and tips by email
Subscribe