在 Android 设备中,有多种可以用来标识设备的“唯一标识符”,但每种都有不同的特性、权限要求、以及在不同 Android 版本中的可用性。以下是常见的几种唯一标识符:
描述:用于唯一标识 GSM、WCDMA 和 LTE 手机。
获取方式:
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getImei(); // Android 8.0+
权限要求:READ_PHONE_STATE
注意事项:
Android 10(API 29)开始,除非 app 是系统 app 或默认拨号器,无法访问 IMEI。
不适用于没有蜂窝模块的设备(如 Wi-Fi 平板)。
描述:首次启动设备时生成,设备恢复出厂设置时会改变。用于APP内部标识设备。
获取方式:
String androidId = Settings.Secure.getString(
context.getContentResolver(), Settings.Secure.ANDROID_ID);
权限要求:无(但只能获取自己 app 的 ID)
特点:
在 Android 8.0 之前,同一个设备上不同 app 获取的值一样。
从 Android 8.0 开始,不同的 app 获取的 Android ID 是不同的(基于 app + user)。
部分设备可能返回 null 或固定值(如 9774d56d682e549c)。
描述:开发者可自定义生成并存储在 SharedPreferences 或数据库中。
获取方式:
String uuid = UUID.randomUUID().toString();
权限要求:无
特点:
不是真正的设备 ID,但可用于标识安装实例。
应用卸载重装会变。
OAID(Open Anonymous Identifier) 是由中国移动安全联盟(MSA)推出的一种 匿名设备标识符,其核心目的是在不违反用户隐私的前提下,为设备分配一个唯一标识符,以用于广告归因、反作弊、设备识别等。
特性 | 描述 |
---|---|
唯一性 | 同一设备上 OAID 是唯一的 |
可重置 | 用户可以在系统设置中手动重置 OAID(部分厂商提供) |
匿名性 | 不关联用户真实身份 |
厂商实现 | 依赖各手机厂商支持,非所有设备都支持 |
不需敏感权限 | 不需要 READ_PHONE_STATE 等权限 |
Google Play 替代 | 在国内没有 GMS 的 Android 设备中,OAID 常被用于替代 Google Advertising ID |
限制 | 仅适用于国内设备,部分厂商可能不支持。 |
OAID 无法通过原生 Android SDK 获取,需要集成 MSA 提供的 SDK 或三方封装库。
官方 MSA SDK 获取方式:
前往 MSA 官网申请厂商支持:
获取 SDK 和文档,集成进 app。
获取示例代码(简略示意):
// 初始化
MdidSdkHelper.InitSdk(context, true, new IIdentifierListener() {
@Override
public void OnSupport(boolean isSupport, IdSupplier idSupplier) {
if (idSupplier != null) {
String oaid = idSupplier.getOAID();
Log.d("OAID", "获取成功:" + oaid);
}
}
});
WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
String macAddress = wm.getConnectionInfo().getMacAddress();
权限要求:ACCESS_WIFI_STATE
注意事项:
从 Android 6.0 开始,非系统 app 获取的值是一个固定的伪值:02:00:00:00:00:00
。
推荐通过 NetworkInterface
类读取硬件层面地址。
描述:供广告用途使用,用户可重置。
获取方式:
需要通过 Google Play 服务:
AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
String adId = adInfo.getId();
特点:
用户可以在设置中重置该 ID,或选择不让 app 跟踪。
需要 Google Play 服务支持。
(推荐方式)
结合多种软硬件标识符并做哈希(如 Android ID + 设备品牌型号),生成伪唯一 ID:
String longId = androidId + Build.BOARD + Build.BRAND + Build.DEVICE + Build.HARDWARE + Build.ID + Build.MODEL + Build.PRODUCT + Build.SERIAL;
String uniqueID = UUID.nameUUIDFromBytes(longId.getBytes()).toString();
标识符 | 是否唯一 | 是否稳定 | 是否需权限 | Android 限制 | 推荐用途 |
---|---|---|---|---|---|
IMEI | 是 | 是 | 是(敏感权限) | Android 10+ 限制 | 不推荐 |
Android ID | 是 | 是(同 app) | 否 | Android 8+ 更安全 | 推荐,内部标识 |
OAID | 是 | 是 | 否 | 无 | 推荐 国内广告、反作弊、设备识别 |
MAC 地址 | 是 | 是 | 是 | Android 6+ 限制 | 不推荐 |
Advertising ID | 是 | 否(可重置) | 否 | 需要 Google Play 服务 | 广告用途 |
UUID(自生成) | 否 | 否 | 否 | 无限制 | 标识安装实例 |
自定义组合 ID | 是 | 是 | 否 | 可用 | 通用唯一标识 |
如需实现“设备唯一 ID”功能,建议优先考虑使用 Android ID + UUID + 加密存储。
[1]
MSA 官网: https://www.msa-alliance.cn/col.jsp?id=120