安卓设备唯一标识解决方案,可作为移动安全联盟统一 SDK (miit_mdid_xxx.aar)的替代方案。本项目提供了国内各大手机厂商获取 OAID(开放匿名设备标识)及海外手机平台获取 AAID (安卓广告标识)的便携接口,另外也提供了 IMEI/MEID、AndroidID、WidevineID、PseudoID、GUID 等常见的设备标识的获取方法。
GitHub:https://github.com/gzu-liyujiang/Android_CN_OAID码云(GitEE):https://gitee.com/li_yu_jiang/Android_CN_OAID 接入指引最新版本 | 更新日志 | Java Doc
依赖配置 allprojects { repositories { maven { url 'https://www.jitpack.io' } }} dependencies { implementation 'com.github.gzu-liyujiang:Android_CN_OAID:4.1.2'}自 4.1.1 开始默认加入了 READ_PHONE_STATE、WRITE_SETTINGS及WRITE_EXTERNAL_STORAGE 权限以便适配低版本安卓系统。为遵循最小必要原则保护用户隐私,若项目中没用到 IMEI 及 GUID,那么可酌情在 AndroidManifest.xml 中加入如下代码移除相关权限:
<manifest> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" tools:node="remove" /></manifest> 代码示例获取多个可能的设备标识,结合服务端引入拜占庭容错方案得到可靠的稳定的设备唯一标识:
用法一:实时获取设备标识符 final StringBuilder builder = new StringBuilder(); builder.append("UniqueID: "); // 获取设备唯一标识,只支持Android 10之前的系统,需要READ_PHONE_STATE权限,可能为空 String uniqueID = DeviceID.getUniqueID(this); if (TextUtils.isEmpty(uniqueID)) { builder.append("DID/IMEI/MEID获取失败"); } else { builder.append(uniqueID); } builder.append("n"); builder.append("AndroidID: "); // 获取安卓ID,可能为空 String androidID = DeviceID.getAndroidID(this); if (TextUtils.isEmpty(androidID)) { builder.append("AndroidID获取失败"); } else { builder.append(androidID); } builder.append("n"); builder.append("WidevineID: "); // 获取数字版权管理ID,可能为空 String widevineID = DeviceID.getWidevineID(this); if (TextUtils.isEmpty(widevineID)) { builder.append("WidevineID获取失败"); } else { builder.append(widevineID); } builder.append("n"); builder.append("PseudoID: "); // 获取伪造ID,根据硬件信息生成,不会为空,有大概率会重复 builder.append(DeviceID.getPseudoID()); builder.append("n"); builder.append("GUID: "); // 获取GUID,随机生成,不会为空 builder.append(DeviceID.getGUID(this)); builder.append("n"); // 是否支持OAID/AAID builder.append("supported:").append(DeviceID.supportedOAID(this)); builder.append("n"); // 获取OAID/AAID,异步回调 DeviceID.getOAID(this, new IGetter() { @Override public void onOAIDGetComplete(@NonNull String result) { // 不同厂商的OAID/AAID格式是不一样的,可进行MD5、SHA1之类的哈希运算统一 builder.append("OAID/AAID: ").append(result); tvDeviceIdResult.setText(builder); } @Override public void onOAIDGetError(@NonNull Exception error) { // 获取OAID/AAID失败 builder.append("OAID/AAID: 失败,").append(error); tvDeviceIdResult.setText(builder); } }); 用法二:预先获取设备标识符(建议不要和用法一同时存在) // 在 Application#onCreate 里调用预取。注意:如果不需要调用`getClientId()`及`getOAID()`,请不要调用这个方法 DeviceID.register(this); // 在需要用到设备标识的地方获取 // 客户端标识原始值:DeviceID.getClientId() // 客户端标识统一格式为MD5:DeviceID.getClientIdMD5() // 客户端标识统一格式为SHA1:DeviceID.getClientIdSHA1() // 开放匿名设备标识原始值:DeviceID.getOAID() tvDeviceIdResult.setText(String.format("ClientID: %s", DeviceID.getClientIdMD5())); 混淆规则本库自带consumer-rules.pro如下混淆规则,不混淆厂商的相关接口及类。若通过远程依赖的方式引用,则无需进行额外配置:
-keep class repeackage.com.uodis.opendevice.aidl.** { *; }-keep interface repeackage.com.uodis.opendevice.aidl.** { *; }-keep class repeackage.com.asus.msa.SupplementaryDID.** { *; }-keep interface repeackage.com.asus.msa.SupplementaryDID.** { *; }-keep class repeackage.com.bun.lib.** { *; }-keep interface repeackage.com.bun.lib.** { *; }-keep class repeackage.com.heytap.openid.** { *; }-keep interface repeackage.com.heytap.openid.** { *; }-keep class repeackage.com.samsung.android.deviceidservice.** { *; }-keep interface repeackage.com.samsung.android.deviceidservice.** { *; }-keep class repeackage.com.zui.deviceidservice.** { *; }-keep interface repeackage.com.zui.deviceidservice.** { *; } 支持情况 厂商或品牌系统或框架华为(HuaWei、Honor)HMS Core 2.6.2+ 、Google Play Service 4.0+小米(XiaoMi、RedMi、BlackShark)MIUI 10.2+、Google Play Service 4.0+维沃(VIVO、IQOO)Funtouch OS 9+、Origin OS 1.0+、Google Play Service 4.0+欧珀(OPPO、RealMe)Color OS 7.0+、Google Play Service 4.0+三星(Samsung)Android 10+、Google Play Service 4.0+联想(Lenovo)ZUI 11.4+、Google Play Service 4.0+华硕(ASUS)Android 10+、Google Play Service 4.0+魅族(Meizu)Android 10+、Google Play Service 4.0+一加(OnePlus)Android 10+、Google Play Service 4.0+努比亚(Nubia)Android 10+、Google Play Service 4.0+其他(ZTE、HTC、Motorola、……)Freeme OS、SSUI、Google Play Service 4.0+注:本项目的 OAID 获取接口主要参考北京数字联盟公开的代码以及逆向分析参考移动安全联盟的 SDK、HUAWEI Ads SDK、小米 DeviceId.jar、Google Play Services SDK 等。
效果预览 OAID(开放匿名设备标识符)
OAID 是移动智能终端补充设备标识体系中的一员,官方定义为 Open Anonymous Device Identifier(开放匿名设备标识符),
华为称之为 Open Advertising ID (开放广告标识符),谷歌称之为 Android Advertising ID (安卓广告标识符)。