文章目录前言一、为什么有这么多设备 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:booleantrue,generateId?:string):string{letdeviceIdDeviceUtil.deviceId;if(StrUtil.isEmpty(deviceId)){// 优先从关键资产服务读取持久化存储if(AssetUtil.canIUse()){deviceIdStrUtil.toStr(AssetUtil.getSync(DEVICE_ID_KEY));}else{// 降级使用 PreferencesdeviceIdStrUtil.toStr(PreferencesUtil.getStringSync(DEVICE_ID_KEY));}// 首次启动生成新 IDif(StrUtil.isEmpty(deviceId)){deviceIdgenerateId||RandomUtil.generateRandomUUID(true);if(AssetUtil.canIUse()){AssetUtil.addSync(DEVICE_ID_KEY,deviceId);// 存入关键资产卸载保留}else{PreferencesUtil.putSync(DEVICE_ID_KEY,deviceId);}}DeviceUtil.deviceIddeviceId;}if(!rule){deviceIddeviceId.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():Promisestring{returnidentifier.getOAID();}// 获取 AAID推送服务标识staticasyncgetAAID():Promisestring{returnAAID.getAAID();}// 删除 AAIDstaticasyncdeleteAAID():Promisevoid{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.etsDemo 源码// 加载所有设备标识符loadDeviceId(){// DeviceId带横线 vs 无横线this.deviceIdResultDeviceUtil.getDeviceId(true);// 带横线this.deviceIdRawDeviceUtil.getDeviceId(false);// 无横线this.addLog(DeviceId,获取成功带横线:${this.deviceIdResult.substring(0,20)}...,info);// ODID同步直接返回this.odidResultDeviceUtil.getODID();this.addLog(ODID,ODID:${this.odidResult},info);// OAID异步需用户授权DeviceUtil.getOAID().then((oaid:string){this.oaidResultoaid;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.aaidResultaaid;this.addLog(AAID,AAID:${aaid},success);}).catch((e:Error){this.aaidResult获取失败:${e.message};this.addLog(AAID,获取失败:${e.message},error);});// Serial Udid系统应用专用this.serialResultDeviceUtil.getSerial();this.udidResultDeviceUtil.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 实现卸载后不变的持久化 IDgetODID同一开发者下的多应用互通标识无需权限getOAID广告行业标准需要用户明确授权getAAID华为推送专用可由用户删除重置