news 2026/5/26 16:26:33

HarmonyOS ArkTS DeviceUtil 设备标识符完整指南:DeviceId、ODID、OAID、AAID

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS ArkTS DeviceUtil 设备标识符完整指南:DeviceId、ODID、OAID、AAID

文章目录

    • 前言
    • 一、为什么有这么多"设备 ID"?
    • 二、DeviceUtil 标识符相关方法源码
    • 三、DeviceId 的特殊设计:卸载后不消失
    • 四、Demo 完整演示代码
    • 五、四种 ID 选择建议
    • 六、小结

前言

近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦

案例demo导航展示

↓↓↓↓↓↓接下来言归正传 ↓↓↓↓

一、为什么有这么多"设备 ID"?

不同场景需要不同类型的设备标识符:

标识符作用特点
DeviceId应用内持久化标识卸载后不变(用 AssetUtil 存储)
ODID开发者匿名标识同开发者的不同应用相同,用户可重置
OAID广告标识用于精准广告,用户可关闭
AAID推送标识用于消息推送(华为 Push),可删除重置

二、DeviceUtil 标识符相关方法源码

// DeviceUtil.ets(工具类源码)// 获取设备ID(卸载APP后依旧不变)// 需要权限:ohos.permission.STORE_PERSISTENT_DATAstaticgetDeviceId(rule:boolean=true,generateId?:string):string{letdeviceId=DeviceUtil.deviceId;if(StrUtil.isEmpty(deviceId)){// 优先从关键资产服务读取(持久化存储)if(AssetUtil.canIUse()){deviceId=StrUtil.toStr(AssetUtil.getSync(DEVICE_ID_KEY));}else{// 降级:使用 PreferencesdeviceId=StrUtil.toStr(PreferencesUtil.getStringSync(DEVICE_ID_KEY));}// 首次启动,生成新 IDif(StrUtil.isEmpty(deviceId)){deviceId=generateId||RandomUtil.generateRandomUUID(true);if(AssetUtil.canIUse()){AssetUtil.addSync(DEVICE_ID_KEY,deviceId);// 存入关键资产(卸载保留)}else{PreferencesUtil.putSync(DEVICE_ID_KEY,deviceId);}}DeviceUtil.deviceId=deviceId;}if(!rule){deviceId=deviceId.replace(/-/g,'');// 去除横线}returndeviceId;}// 移除设备IDstaticdeleteDeviceId():void{DeviceUtil.deviceId='';if(AssetUtil.canIUse()){AssetUtil.removeSync(DEVICE_ID_KEY);}else{PreferencesUtil.deleteSync(DEVICE_ID_KEY);}}// 获取开发者匿名设备标识符 ODIDstaticgetODID():string{returndeviceInfo.ODID;}// 获取开放匿名设备标识符 OAID(需权限)// @permission ohos.permission.APP_TRACKING_CONSENTstaticasyncgetOAID():Promise<string>{returnidentifier.getOAID();}// 获取 AAID(推送服务标识)staticasyncgetAAID():Promise<string>{returnAAID.getAAID();}// 删除 AAIDstaticasyncdeleteAAID():Promise<void>{returnAAID.deleteAAID();}

三、DeviceId 的特殊设计:卸载后不消失

DeviceUtil.getDeviceId最特别的地方是:普通应用数据卸载后会清除,但它借助**关键资产服务(AssetUtil)**将 ID 存储在系统级存储区,即使卸载应用也不会丢失。

首次安装应用: 1. 读取 AssetUtil → 空 2. 生成 UUID (如 550e8400-e29b-41d4-a716-446655440000) 3. 存入 AssetUtil 4. 返回 UUID 卸载应用 → 重装: 1. 读取 AssetUtil → 550e8400-e29b-41d4-a716-446655440000 2. 直接返回(ID 不变!)

四、Demo 完整演示代码

// DeviceUtilDemoPage.ets(Demo 源码)// 加载所有设备标识符loadDeviceId(){// DeviceId(带横线 vs 无横线)this.deviceIdResult=DeviceUtil.getDeviceId(true);// 带横线this.deviceIdRaw=DeviceUtil.getDeviceId(false);// 无横线this.addLog('DeviceId',`获取成功(带横线:${this.deviceIdResult.substring(0,20)}...)`,'info');// ODID(同步,直接返回)this.odidResult=DeviceUtil.getODID();this.addLog('ODID',`ODID:${this.odidResult}`,'info');// OAID(异步,需用户授权)DeviceUtil.getOAID().then((oaid:string)=>{this.oaidResult=oaid;this.addLog('OAID',`OAID:${oaid.substring(0,20)}...`,'success');}).catch((e:Error)=>{this.oaidResult=`获取失败:${e.message}`;this.addLog('OAID',`获取失败:${e.message}`,'error');});// AAID(异步)DeviceUtil.getAAID().then((aaid:string)=>{this.aaidResult=aaid;this.addLog('AAID',`AAID:${aaid}`,'success');}).catch((e:Error)=>{this.aaidResult=`获取失败:${e.message}`;this.addLog('AAID',`获取失败:${e.message}`,'error');});// Serial & Udid(系统应用专用)this.serialResult=DeviceUtil.getSerial();this.udidResult=DeviceUtil.getUdid();}// 删除并重新生成设备IDtestDeleteDeviceId(){DeviceUtil.deleteDeviceId();this.addLog('DeviceId','设备ID已删除,重新生成...','warn');this.loadDeviceId();// 删除后立即重新生成}
// UI 展示Column(){Text('设备标识符').fontSize(13).fontColor('#666').fontWeight(FontWeight.Medium).alignSelf(ItemAlign.Start).margin({bottom:10})// Device ID(带横线)Column(){Text('Device ID(带横线)').fontSize(11).fontColor('#888').alignSelf(ItemAlign.Start)Text(this.deviceIdResult).fontSize(11).fontFamily('monospace').fontColor('#D63384').margin({top:2}).width('100%')}.width('100%').padding(10).backgroundColor('#F5F6FA').borderRadius(8).margin({bottom:6})// Device ID(无横线)Column(){Text('Device ID(无横线)').fontSize(11).fontColor('#888').alignSelf(ItemAlign.Start)Text(this.deviceIdRaw).fontSize(11).fontFamily('monospace').fontColor('#D63384').margin({top:2}).width('100%')}.width('100%').padding(10).backgroundColor('#F5F6FA').borderRadius(8).margin({bottom:6})Row(){Button('刷新 DeviceId').fontSize(12).height(34).backgroundColor('#4080FF').fontColor('#FFF').onClick(()=>{this.loadDeviceId();})Button('删除并重新生成').fontSize(12).height(34).margin({left:8}).backgroundColor('#FF5252').fontColor('#FFF').onClick(()=>{this.testDeleteDeviceId();})}.width('100%')}.width('100%').padding(14).backgroundColor('#FFFFFF').borderRadius(12)// OAID 展示(含权限提示)Column(){Text('OAID(开放匿名设备标识符)').fontSize(11).fontColor('#888').alignSelf(ItemAlign.Start)Text(this.oaidResult||'加载中...').fontSize(12).fontFamily('monospace').fontColor(this.oaidResult&&!this.oaidResult.startsWith('获取失败')?'#D63384':'#888').margin({top:4}).width('100%')Text('⚠️ 需要用户授权 ohos.permission.APP_TRACKING_CONSENT').fontSize(10).fontColor('#FF9800').margin({top:4})}.width('100%').padding(14).backgroundColor('#FFFFFF').borderRadius(12)

五、四种 ID 选择建议

需求推荐 ID权限要求
用户行为分析(不跨应用)DeviceIdSTORE_PERSISTENT_DATA(可选)
同一开发者多应用打通ODID
精准广告投放OAID用户授权
华为推送通知AAID无(Push 服务)
设备序列号(系统应用)getSerial/getUdid系统权限

六、小结

  • getDeviceId首选方案,利用 AssetUtil 实现卸载后不变的持久化 ID
  • getODID:同一开发者下的多应用互通标识,无需权限
  • getOAID:广告行业标准,需要用户明确授权
  • getAAID:华为推送专用,可由用户删除重置
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/26 16:25:17

小样本学习与注意力机制在婴儿表情识别中的实战应用

1. 项目概述&#xff1a;当深度学习遇见婴儿的“喜怒哀乐”在计算机视觉的浩瀚海洋里&#xff0c;面部表情识别一直是个既迷人又充满挑战的领域。我们成年人可以通过语言和复杂的表情传递情绪&#xff0c;但对于尚在襁褓中的婴儿&#xff0c;他们的“语言”几乎完全由面部表情、…

作者头像 李华
网站建设 2026/5/26 16:24:26

Java算法练习day3

一、游游的重组偶数Java代码import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {// 纯数学运算实现 dep 函数&#xff0c;和你C逻辑完全一样public static int dep(int x) {int temp x;int k 0;// 保存最后一位数字int last …

作者头像 李华
网站建设 2026/5/26 16:24:08

ApuEmo混合模型:基于SaBERT与多路RNN的西班牙语社交媒体情感分类实践

1. 项目概述与核心挑战情感分类&#xff0c;或者说情绪识别&#xff0c;是自然语言处理领域里一个既经典又充满挑战的任务。简单来说&#xff0c;就是让机器读懂文字背后的喜怒哀乐。在英语世界&#xff0c;得益于海量的标注数据和成熟的预训练模型&#xff0c;这项技术已经相当…

作者头像 李华
网站建设 2026/5/26 16:23:03

CZSC缠论量化插件:如何用算法自动化解决传统缠论分析的三大难题

CZSC缠论量化插件&#xff1a;如何用算法自动化解决传统缠论分析的三大难题 【免费下载链接】Indicator 通达信缠论可视化分析插件 项目地址: https://gitcode.com/gh_mirrors/ind/Indicator 缠论作为一套完整的技术分析体系&#xff0c;在实际应用中面临识别准确性、分…

作者头像 李华
网站建设 2026/5/26 16:19:08

TypeScript类型体操构建AI修心智能体生成引擎——从2300+豆包智能体到七境宇宙的类型安全实践

导读:本文将东方修心七境(真诚/清净/平等/华光/无畏/欢喜/自在)与五行(金木水火土)抽象为TypeScript类型系统,通过”类型体操”实现2300+AI智能体的编译期安全批量生成。这不是技术炫技,而是用代码书写修行——每一个类型约束都是宇宙法则的数字化表达。 一、为什么修心…

作者头像 李华