更新记录

0.0.3(2026-10-29) 下载此版本

  • 新增 HarmonyOS(HarmonyOS NEXT)原生支持:utssdk/app-harmony/(编译为 ArkTS,无需云打包基座)
    • OAID:@kit.AdsKit identifier.getOAID(),需在鸿蒙工程 module.json5 声明 ohos.permission.APP_TRACKING_CONSENT,首次获取触发系统授权弹窗,未授权返回空
    • AAID:@kit.PushKit AAID.getAAID(),免权限
    • GUID:@ohos.data.preferences 持久化随机 UUID
    • 鸿蒙无 IMEI / AndroidID / WidevineID / PseudoID,相应字段恒为空;最优设备 ID 优先级 OAID > AAID > GUID
  • js 层条件编译新增 APP-HARMONY 分支(根路径导入),兜底条件收紧为 #ifndef APP-PLUS || APP-HARMONY

平台兼容性

uni-app(4.73)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- √ √ √ √ - 5.0 - √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
√ √ × × × × × × × × - -

ant-device-id 设备唯一标识(OAID)

获取设备唯一标识的原生(UTS)插件,能力对齐 Ba-IdCode 并有所增强:安卓端支持国内各手机厂商 OAID、海外平台 AAID(GMS 广告标识),同时提供 IMEI、AndroidID、WidevineID、PseudoID、GUID、clientId(含 MD5/SHA1 摘要) 等标识;鸿蒙端(HarmonyOS NEXT)支持 OAID、AAID、GUID;并给出按优先级自动挑选的综合最优设备 ID。

H5 / 小程序自动降级为本地持久化 GUID,一套 API 全端一致,字段结构完全相同。

⚠️ 重要:安卓原生能力生效前,必须在 HBuilderX 中重新「制作自定义调试基座 / 云打包」(原生 gradle 依赖变更必须重打基座,直接运行标准基座会取不到 OAID 等原生标识)。

特性

  • 📱 安卓原生实现:UTS 编译为 Kotlin,OAID 获取基于开源库 Android_CN_OAID 4.2.17(Mulan PSL v2),通过 gradle 远程依赖集成,覆盖华为、荣耀、小米、OPPO、vivo、三星、联想、魅族等主流厂商
  • 🌏 鸿蒙原生实现:UTS 编译为 ArkTS,OAID / AAID 走系统 @kit.AdsKit / @kit.PushKit,本地编译直跑真机,无需云打包基座
  • 🌍 海内外双通道:oaid 走厂商通道,aaid 走 GMS(Google Play 服务)广告标识通道
  • 🧩 全量标识一次拿齐:getIdCodes() 返回 12 个字段,结构在所有平台一致
  • 🎯 综合最优设备 ID:getDeviceId() 按优先级自动挑选并标明来源类型
  • 🔄 Promise + success/fail 双风格:与 ant-watermark 等本仓库插件用法一致
  • 💡 全端兜底:非安卓平台返回本地持久化 GUID,业务代码无需写平台判断

快速上手

import { register, getOAID, getIdCodes, getDeviceId } from '@/uni_modules/ant-device-id/interface.js'

// 1. 注册初始化(建议在用户同意隐私政策后、App 启动时调用一次;后续获取方法内部也会自动兜底注册)
await register()

// 2. 全量标识码
const codes = await getIdCodes()
console.log(codes.oaid, codes.androidId, codes.guid)

// 3. 只要 OAID
const { oaid } = await getOAID()

// 4. 综合最优设备 ID(优先级:OAID > AAID > AndroidID > WidevineID > PseudoID > GUID)
const { deviceId, type } = await getDeviceId()

也支持回调风格:

getIdCodes({
    success: (res) => console.log(res.oaid),
    fail: (err) => console.error(err)
})

完整演示见 pages/index/index.vue。

API

register(options?)

注册初始化,等价于 Ba-IdCode 的 register。内部有去重,可安全多次调用。应在用户同意隐私政策之后调用。

参数 类型 必填 说明
options.success Function 否 成功回调,参数 { ok: boolean }
options.fail Function 否 失败回调,参数 Error

getOAID(options?)

异步获取 OAID,不支持或获取失败时 oaid 为空字符串。

参数 类型 必填 说明
options.success Function 否 成功回调,参数 { oaid: string }
options.fail Function 否 失败回调,参数 Error

getIdCodes(options?)

一次性获取全部标识码。

参数 类型 必填 说明
options.success Function 否 成功回调,参数 IdCodes
options.fail Function 否 失败回调,参数 Error

返回值 res(IdCodes)字段:

字段 类型 说明
oaid string 开放匿名设备标识符(国内厂商);不支持时为空
aaid string 海外平台广告标识(GMS Advertising ID);不支持时为空
imei string 设备 IMEI;仅 Android 9 及以下且已授予 READ_PHONE_STATE 时可能非空
androidId string AndroidID(SSAID);恢复出厂 / 刷机后会变化
widevineId string Widevine 设备唯一 ID
pseudoId string 由硬件信息拼装出的伪设备 ID
guid string 随机生成并持久化的 GUID;卸载重装会变化
clientId string 库内部综合出的客户端唯一标识
clientIdMd5 string clientId 的 MD5 摘要
clientIdSha1 string clientId 的 SHA1 摘要
uniqueId string 唯一设备标识(OAID 优先、失败降级)
supportedOAID boolean 设备是否支持获取 OAID / AAID(鸿蒙侧含义为"本次已成功取到 OAID")

所有字符串字段获取失败即为空字符串,不会为 null,可放心直接使用。

getDeviceId(options?)

获取综合最优设备 ID。

参数 类型 必填 说明
options.success Function 否 成功回调,参数 { deviceId: string, type: string }
options.fail Function 否 失败回调,参数 Error

type 取值:oaid / aaid / androidid / widevine / pseudo / guid / unknown(兜底平台恒为 guid)。

权限与隐私合规

  • register() 及各获取方法涉及读取设备标识,必须在用户同意隐私政策之后调用,否则可能导致 OPPO、荣耀等厂商应用市场审核不通过
  • IMEI 仅 Android 9 及以下且应用已授予 READ_PHONE_STATE 运行时权限时可得(Android 10+ 系统禁止普通应用获取,返回空字符串属正常现象)
  • 依赖库自 4.1.1 起会在打包时合并 READ_PHONE_STATE、WRITE_SETTINGS、WRITE_EXTERNAL_STORAGE 权限声明;如需移除,可在项目原生配置中添加:
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:node="remove" />

平台差异说明

平台 实现方式 备注
App-Android UTS 原生(Kotlin) 需自定义基座 / 云打包;全量标识
App-Harmony UTS 原生(ArkTS) 本地编译直跑真机,无需云打包基座;OAID / AAID / GUID
App-iOS 未适配 如需 iOS 打包,可临时注释 interface.js 中的 APP-PLUS 原生分支走 JS 兜底,或后续补充 utssdk/app-ios 实现
H5 JS 兜底 localStorage 持久化 GUID
微信 / 支付宝小程序 JS 兜底 storage 持久化 GUID

安卓集成说明

utssdk/app-android/config.json 已声明 gradle 远程依赖与 JitPack 仓库,云打包时自动拉取:

{
    "minSdkVersion": 21,
    "dependencies": ["com.github.gzu-liyujiang:Android_CN_OAID:4.2.17"],
    "project": { "repositories": ["maven { url 'https://jitpack.io' }"] }
}

可选增强(提升华为 / 荣耀机型 OAID 获取成功率),替换 dependencies 与 repositories 为:

{
    "dependencies": [
        "com.github.gzu-liyujiang:Android_CN_OAID:4.2.17",
        "com.huawei.hms:ads-identifier:3.4.62.300",
        "com.hihonor.mcs:ads-identifier:1.0.2.301"
    ],
    "project": {
        "repositories": [
            "maven { url 'https://jitpack.io' }",
            "maven { url 'https://developer.huawei.com/repo/' }",
            "maven { url 'https://repo.hihonor.com/repository/releases/' }"
        ]
    }
}

备选方案:若云打包未能解析 JitPack 仓库,可从 JitPack 手动下载 Android_CN_OAID-4.2.17.aar,放入 utssdk/app-android/libs/ 并删除 config.json 中的 dependencies 与 project 字段。

鸿蒙集成说明

  • OAID 获取需在鸿蒙工程 entry/src/main/module.json5 的 requestPermissions 中声明广告跟踪权限(缺省时系统恒返回全零值,插件会转为空字符串):
{
    "module": {
        "requestPermissions": [
            {
                "name": "ohos.permission.APP_TRACKING_CONSENT",
                "reason": "$string:app_tracking_consent_reason",
                "usedScene": {
                    "abilities": ["EntryAbility"],
                    "when": "inuse"
                }
            }
        ]
    }
}

其中 $string:app_tracking_consent_reason 需在鸿蒙工程 entry/src/main/resources/base/element/string.json 中补充(如"用于获取设备标识以提供个性化服务"),否则打包校验不通过。

  • 首次调用 getOAID() 会触发系统授权弹窗;用户拒绝或"跨应用关联访问"开关关闭时系统返回全零值,插件返回空字符串,getDeviceId() 自动降级到 AAID / GUID。
  • AAID 免权限,重置广告标识或卸载重装后会变化。
  • 运行方式:HBuilderX「运行 → 运行到手机或模拟器 → 运行到鸿蒙」,需在 HBuilderX 设置中配好鸿蒙环境(DevEco Studio / HarmonyOS SDK)。UTS 在鸿蒙侧编译为 ArkTS 本地直跑真机,无需制作云打包基座。
  • 鸿蒙不存在 IMEI / AndroidID / WidevineID / PseudoID 等安卓标识,相应字段恒为空字符串;supportedOAID 在鸿蒙的含义是"本次已成功取到 OAID"。

常见问题

  • 安卓上取不到 OAID / 只返回了 GUID? 依次确认:① 已按上述说明重新制作自定义调试基座(原生依赖变更必须重打);② js/vue 里的条件编译必须用 APP-PLUS——uni-app 项目中 APP-ANDROID 仅在 uts 文件内有效,写在 js/vue 里不会命中;③ register() 已调用;④ 测试机为国产主流 ROM 且非模拟器(模拟器和原生 Android(如 Pixel 国际版)本身不提供厂商 OAID 通道,此时 supportedOAID 为 false,属正常现象,可改用 aaid 或 getDeviceId() 的降级结果)
  • 本地编译报 Could not resolve "io.dcloud.uts"? js/vue 引用 UTS 原生能力必须从插件根路径导入(from '@/uni_modules/ant-device-id',由 HBuilderX 走 UTS 编译管线);直接写 .uts 文件路径(如 ./utssdk/app-android/index.uts)会被当成普通 TS 打包而报此错
  • 想看具体失败原因? HBuilderX 控制台会输出 [ant-device-id] 标识获取失败:... 日志(0.0.2 起)
  • 云打包报 Interface 'xxx' does not have constructors? UTS 中需要用对象字面量构造、返回给 JS 的数据结构必须声明为 export type X = {...};export interface 会编译为 Kotlin 接口,不可实例化
  • 编辑器里 import ... from 'com.github.gzuliyujiang.oaid' 标红? 本地 IDE 未编译原生依赖属正常现象,以云打包 / 自定义基座构建结果为准;若构建报某个方法不存在,可将调用在 DeviceID 与 DeviceIdentifier 两个类之间互换(二者互为镜像委托)
  • 同一设备 GUID 变了? GUID 持久化在应用私有存储,卸载重装、清数据后会重新生成;H5 下清浏览器存储同理

测试

node test/run-device-id.mjs   # 兜底层纯逻辑:UUID 生成 / GUID 持久化 / 优先级选择 / 字段完整性

致谢

安卓 OAID 能力基于 gzu-liyujiang/Android_CN_OAID(版权所有 © 大定府羡民,Mulan PSL v2 许可)。

隐私、权限声明

1. 本插件需要申请的系统权限列表:

android.permission.READ_PHONE_STATE(仅 Android 9 及以下获取 IMEI 时需要)

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

读取设备标识符(OAID/AAID/IMEI/AndroidID 等)用于设备识别,不上传任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议

暂无用户评论。