更新记录
1.1.0(2026-07-27)
1.0.1(2026-05-20)
更新插件文件
1.0.0(2026-05-11)
首次发布,提供 ATT + IDFA 广告标识符管理功能
查看更多平台兼容性
uni-app(4.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | 5.0 | 1.0.1 | 14 | 1.0.1 | 9 | 1.0.1 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.0)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
三端统一广告标识符管理插件
iOS ATT + IDFA / Android GAID → OAID / HarmonyOS OAID — 统一 API,一次集成三端可用
📋 功能概览
| 平台 | 广告标识符 | 权限机制 | 最低版本 |
|---|---|---|---|
| 🍎 iOS | IDFA | ATT 弹窗授权 | iOS 14.0 |
| 🤖 Android | GAID → OAID (自动降级, 6 厂商) | 无需运行时权限 | Android 5.0 (API 21) |
| 🦕 HarmonyOS | OAID | APP_TRACKING_CONSENT | HarmonyOS 3.0 (API 9) |
核心价值:
- 🎯 一次集成,三端可用 — 统一 API,同一套返回结构
- 🛡️ 完整隐私合规 — iOS ATT 弹窗 + Info.plist 声明 + 鸿蒙权限声明
- 🔄 Android 智能降级 — GAID 不可用时自动切换 OAID(覆盖华为/小米/OPPO/vivo/联想/三星)
- 👻 弱链接安全 — iOS < 14 不崩溃,
#available+NSClassFromString双重保护 - 内置诊断 —
getATTDiagnostics()一键输出各端环境状态
🚀 快速开始
安装
插件市场安装: 搜索 szy-att-manager,点击安装。
基础调用(ES Module — 推荐)
// 通过 ES Module 导入(推荐)
import {
getTrackingAuthorizationStatus,
requestTrackingAuthorization,
getAdvertisingInfo,
getATTDiagnostics
} from '@/uni_modules/szy-att-manager'
// 获取广告标识符(三端统一)
const info = await getAdvertisingInfo()
console.log('标识符:', info.advertisingId)
console.log('类型:', info.type) // "idfa" | "gaid" | "oaid"
console.log('平台:', info.platform) // "ios" | "android"
基础调用(NativePlugin — 兼容方式)
const attManager = uni.requireNativePlugin('szy-att-manager')
const info = await attManager.getAdvertisingInfo()
iOS ATT 授权流程
// 1. 检查当前状态
const status = getTrackingAuthorizationStatus()
if (status === 'notDetermined') {
// 2. 首次使用,弹出 ATT 弹窗
const newStatus = await requestTrackingAuthorization()
if (newStatus === 'authorized') {
// 3. 同意 → 获取 IDFA
const info = await getAdvertisingInfo()
sendToAnalytics(info)
} else {
// 拒绝 → 使用备选方案
useFallbackIdentifier()
}
}
HarmonyOS ATT 授权须知
由于底层问题,UTS 桥接层无法弹出系统权限对话框,因此需要提示手动开启相关权限
设置 → 隐私 → 权限管理 → 跨应用关联访问权限 → 找到「您的应用」→ 开启
或者:
设置 → 应用 → 应用管理 → 您的应用 → 权限 → 开启「跨应用关联访问权限」
📖 API 参考
核心 API
getATTDiagnostics() — 诊断信息
返回当前环境的完整诊断字符串(iOS ATT 状态、系统版本、框架可用性)。
| 平台 | 返回值类型 |
|---|---|
| iOS | string — 如 "ATT.available=true osVersion=26.3.0 ATTStatus=denied(raw=2) AdSupport=true" |
| Android | "ATT.notAvailable platform=android" |
iOS 26+ 的诊断信息会额外标注 ATTpersists=yes,表示 ATT 状态已持久化(删除重装不重置)。
getTrackingAuthorizationStatus() — 获取授权状态
返回当前 ATT 授权状态(不弹窗,同步方法)。
| 返回值 | 说明 |
|---|---|
"notDetermined" |
用户尚未决定,首次弹窗会出现 |
"restricted" |
设备限制(家长控制/MDM),无法弹窗 |
"denied" |
用户拒绝 |
"authorized" |
用户授权 |
"notSupported" |
非 iOS 平台 |
iOS: sync → ATTAuthorizationStatus
Android: sync → "notSupported"
requestTrackingAuthorization() — 请求授权
弹出 iOS 系统 ATT 授权弹窗。
⚠️ 每个 App 安装周期只弹窗一次。 iOS 17+ 起 ATT 状态开始持久化,iOS 26+ 删除重装不重置追踪权限。 如果需要重新授权,引导用户前往 设置 → 隐私→追踪 手动开启。
iOS: Promise<ATTAuthorizationStatus> (同步返回, Promise.resolve 包装)
Android: sync → "notSupported"
iOS 26+ 注意事项: 自 iOS 26 起 Apple 将 ATT 状态与 Bundle ID + Team ID 绑定,删除 App 不会重置追踪权限。
诊断输出会标注 ATTpersists=yes。插件内置 openAppSettings() 方法可一键跳转设置页。
getAdvertisingInfo() — 一站式获取
获取完整的广告标识符信息(推荐作为统一入口)。
iOS: Promise<AdvertisingIdResult> (ATT 未决定时自动弹窗)
Android: sync → AdvertisingIdResult
HarmonyOS: Promise<AdvertisingIdResult>
返回值 AdvertisingIdResult:
| 字段 | 类型 | iOS | Android | HarmonyOS |
|---|---|---|---|---|
advertisingId |
string |
IDFA | GAID→OAID (降级) | OAID |
type |
string |
"idfa" |
"gaid" / "oaid" |
"oaid" |
attStatus |
ATTAuthorizationStatus |
系统状态 | "notSupported" |
"notSupported" |
isTrackingLimited |
boolean |
全零 IDFA | GAID 限制开关 | false |
platform |
string |
"ios" |
"android" |
"harmony" |
const info = await getAdvertisingInfo()
if (info.advertisingId.length > 0) {
uploadToServer(info.advertisingId, info.type)
} else {
// 获取失败(iOS 未授权 / Android 无 GMS 也无 OAID)
useFallbackIdentifier()
}
getAdvertisingId() — 仅获取标识符字符串
| 平台 | 返回值 |
|---|---|
| iOS | IDFA 字符串(需 ATT 授权后) |
| Android | GAID 或 OAID 字符串 |
| HarmonyOS | 返回空字符串(OAID 获取是异步的,请使用 getAdvertisingInfo()) |
openAppSettings() — 跳转系统设置
iOS 14+ 打开 App 自身的系统设置页(含追踪开关)。ATT 状态为 denied/restricted 时使用。
iOS 专属 API
| 方法 | 说明 |
|---|---|
getAdvertisingIdInfo() |
同步获取完整广告标识信息(不弹窗) |
Android 专属 API
| 方法 | 说明 |
|---|---|
getOaidOnly() |
仅获取国内厂商 OAID(跳过 GAID) |
已覆盖厂商:
| 厂商 | ContentProvider URI |
|---|---|
| 华为 HMS | content://com.huawei.hwid.oaidProvider/getOaid |
| 小米 MIUI | content://com.miui.systemAdSolution/oaid |
| OPPO | content://com.heytap.openid.oaidProvider/getOaid |
| vivo | content://com.vivo.vms.IdProvider/IdentifierId/OAID |
| 联想 ZUI | content://com.zui.deviceidservice/oaid |
| 三星 | content://com.samsung.android.deviceidservice/oaid |
🧱 技术架构
┌────────────────────────────────────────────────┐
│ 你的 UniApp 代码层 │
│ import { ... } from '@/uni_modules/szy...' │
├───────────────────┬────────────────────────────┤
│ index.uts (入口) + interface.uts (类型定义) │
├────────┬──────────┴─────────┬──────────────────┤
│ iOS │ Android │ HarmonyOS │
│ UTS │ UTS │ UTS │
├──────┴──────┬──────────────┴──────────────────┤
│ATTManager │ Google Play Services │
│Bridge.swift │ + 厂商 OAID (6大厂商) │
│(Swift @objc)│ ContentProvider 降级策略 │
├─────────────┴─────────────────────────────────┤
│ weakFrameworks: AppTrackingTransparency │
│ AdSupport │
│ #available(iOS 14, *) + NSClassFromString │
│ 双重安全检测 │
└──────────────────────────────────────────────┘
iOS 兼容策略
| 保护层级 | 机制 | 说明 |
|---|---|---|
| 编译期 | #available(iOS 14, *) |
Swift 编译器信任,不检查内部 iOS 14 API |
| 运行时 | NSClassFromString("ATTrackingManager") |
弱链接框架,iOS < 14 返回 nil,不会崩溃 |
| 函数签名 | statusFromRaw(UInt) |
避免 ATTrackingManager.AuthorizationStatus 在函数签名中出现 |
| 云打包 | config.json + package.json 双重声明 |
同时声明 frameworks 和 weakFrameworks |
⚙️ 平台配置
iOS
插件自动声明以下配置(无需手动操作):
{
"frameworks": ["AppTrackingTransparency", "AdSupport"],
"weakFrameworks": ["AppTrackingTransparency", "AdSupport"],
"privacyDescription": {
"NSUserTrackingUsageDescription": "需要您的允许以提供个性化广告和内容体验。您的数据将仅用于改进服务质量,不会被出售给第三方。"
}
}
若使用云打包,请确保
package.json中frameworks字段包含AppTrackingTransparency和AdSupport。 云打包服务器依赖此字段配置 Xcode 项目链接。
Android
| 配置项 | 值 |
|---|---|
| 依赖 | com.google.android.gms:play-services-ads-identifier:18.0.1 |
| 最低 API | 21 (Android 5.0) |
HarmonyOS
重要:以下为鸿蒙平台完整配置说明,包括入口初始化、权限声明、已知限制及应对方案。
1. 入口初始化(必须)
在 harmony-configs/entry/src/main/ets/entryability/EntryAbility.ets 中调用 setGlobalContext:
import { setGlobalContext as setAttContext } from "@uni_modules/szy-att-manager";
export default class EntryAbility extends UniEntryAbility {
onCreate(want: object, launchParam: object): void {
super.onCreate(want, launchParam);
setAttContext(this.context); // ← 传入 UIAbilityContext
}
}
2. 权限声明
插件 module.json5 自动声明了 ohos.permission.APP_TRACKING_CONSENT。HBuilderX 打包时会自动合并到最终 module.json 的 requestPermissions 中,无需手动配置。
3. 已知限制:UTS 环境下无法弹系统对话框
requestPermissionsFromUser 和 promptAction.showDialog 在 UTS 桥接层中秒返无效果——系统授权弹窗和引导弹窗均无法显示。因此 OAID 获取依赖用户在系统设置中手动开启一次「跨应用关联访问权限」:
设置 → 隐私 → 权限管理 → 跨应用关联访问权限 → 找到本应用 → 开启
仅需操作一次。开启后,
getOAID()持续返回有效值。
4. needManualGrant 字段
AdvertisingIdResult 新增 needManualGrant: boolean 字段。当 OAID 为全零时,该字段为 true。调用方应在 JS 层弹窗引导用户:
import { getAdvertisingInfo, isOaidValid } from '@/uni_modules/szy-att-manager'
const info = await getAdvertisingInfo()
if (info.needManualGrant) {
uni.showModal({
title: '需要追踪授权',
content: '请在系统设置中为本应用开启「跨应用关联访问权限」。\n\n设置 → 隐私 → 权限管理 → 跨应用关联访问权限',
confirmText: '知道了',
showCancel: false
})
} else if (isOaidValid(info.advertisingId)) {
console.log('OAID:', info.advertisingId)
}
5. API 签名差异
| 方法 | iOS / Android | HarmonyOS |
|---|---|---|
getAdvertisingInfo() |
sync / sync | Promise<AdvertisingIdResult> |
getAdvertisingId() |
sync 返回标识符 | sync 返回 ""(OAID 异步获取) |
getOaidAsync() |
不可用 | Promise<string> OAID 字符串 |
setGlobalContext() |
不可用 | 必须调用(见上方初始化) |
isOaidValid() |
不可用 | 判断 OAID 是否非全零 |
🔧 故障排查
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| iOS ATT 弹窗不出现 | 模拟器测试;ATT 状态已被系统持久化;用户在设置中拒绝过 | 使用真机;iOS 26+ 状态持久化不会弹窗;引导用户去「设置→隐私→追踪」开启 |
| 鸿蒙 OAID 始终为全零 | UTS 桥接层无法弹系统权限对话框,用户从未授权 APP_TRACKING_CONSENT |
引导用户去系统设置手动开启一次「跨应用关联访问权限」(见上方 HarmonyOS §3 说明),开启后 OAID 持续有效 |
云打包报 cannot find type ATTAuthorizationStatus |
index.uts 从 interface.uts import 类型,但 UTS iOS 编译器找不到 |
将类型定义直接写在 iOS index.uts 中(不能从 utssdk/common/ import) |
云打包报 BUILD FAILED Swift 编译错误 |
函数签名暴露了 iOS 14+ 类型 | 所有 Swift @objc 方法参数和返回值使用基础类型 (String/Bool/NSNumber) |
requestTrackingAuthorization 返回 denied 但从未弹窗 |
iOS 26+ ATT 状态持久化,删除重装不重置 | 调用 openAppSettings() 跳转系统设置手动开启 |
| Android 获取失败 | 国内设备无 GMS | 正常行为,自动降级到 OAID |
| OAID 为空 | 厂商 ROM 不支持此插件版本 | 确认设备品牌在支持列表中,或等待系统分配 |
getAdvertisingId() HarmonyOS 返回空 |
同步方法无法获取异步 OAID | 使用 await getAdvertisingInfo() |
修改 index.uts 后依然报旧错误 |
UTS proxy 缓存 | 清理 unpackage/cache/uts_custom_ios/ 和 uts_custom_android/ 后重试 |
📊 平台行为对照
| 行为 | iOS | Android | HarmonyOS |
|---|---|---|---|
| 需要弹窗授权 | ✅ ATT | ❌ | ✅ 需手动去设置开启¹ |
| ATT 状态持久化(删除不重置) | ✅ iOS 26+ | — | — |
| 用户可重置标识符 | ✅ | ✅ | ✅ |
| 可获取限制追踪状态 | ✅ | ✅ (GAID) | ✅ (isTrackingLimited) |
| 获取失败自动降级 | ❌ | ✅ GAID→OAID | ❌ |
| 同步获取 | ✅ | ✅ | ❌ |
| 弱链接(低版本不崩溃) | ✅ | — | — |
¹ UTS 桥接层限制,
requestPermissionsFromUser无法弹系统对话框。用户需手动前往「设置 → 隐私 → 跨应用关联访问权限」开启一次。
🎯 典型应用场景
广告归因
const info = await getAdvertisingInfo()
attributionSDK.setDeviceId({
idfa: info.platform === 'ios' ? info.advertisingId : undefined,
gaid: info.type === 'gaid' ? info.advertisingId : undefined,
oaid: info.type === 'oaid' ? info.advertisingId : undefined,
})
隐私合规弹窗 + 标识符获取
import { getTrackingAuthorizationStatus, requestTrackingAuthorization, getAdvertisingInfo } from '@/uni_modules/szy-att-manager'
async function init() {
const status = getTrackingAuthorizationStatus()
if (status === 'notDetermined') {
// 弹出系统 ATT 弹窗
const newStatus = await requestTrackingAuthorization()
if (newStatus !== 'authorized') {
useFallbackId()
return
}
} else if (status !== 'authorized') {
useFallbackId()
return
}
const info = await getAdvertisingInfo()
if (info.advertisingId) {
initSDK(info.advertisingId)
}
}
📝 更新日志
v1.1.0 (2026-07-27)
- 🦕 鸿蒙 OAID 完整支持 — 基于
@kit.AdsKit深度适配,完整实现权限检查→授权请求→标识符获取链路 - 🏗️ EntryAbility Context 初始化 — 新增
setGlobalContext()方法,统一插件 Context 获取模式 - 🔐 APP_TRACKING_CONSENT 权限全链路 —
checkAccessToken+requestPermissionsFromUser权限管理 -
isOaidValid()工具方法 — 判断 OAID 是否为有效值(非全零),AdvertisingIdResult新增needManualGrant字段 - 📋 权限降级引导机制 — UTS 环境下系统弹窗受限时,通过
needManualGrant标记通知 JS 层引导用户手动授权 - 🐛 修复 ArkTS 严格模式编译 — 所有对象字面量显式类型声明,兼容 ArkTS
arkts-no-untyped-obj-literals规则 - 🐛 修复 context 类型一致性 —
AdvertisingIdResult.attStatus统一使用ATTAuthorizationStatus联合类型 - 📝 鸿蒙专项文档 — EntryAbility 初始化、已知限制说明、API 差异对照、故障排查指南
v1.0.1 (2026-06-15)
- 🎯 ES Module 导入 — 推荐使用
import { ... } from '@/uni_modules/szy-att-manager'替代uni.requireNativePlugin - 新增
getATTDiagnostics()— 诊断信息输出 ATT 状态、系统版本、框架可用性、ATT 持久化状态 - ⚙️ 新增
openAppSettings()— iOS 26+ 一键跳转系统设置页 - 🧱 Bridge 架构重构 — iOS ATT/AdSupport 原生逻辑全部迁移到
ATTManagerBridge.swift,UTS 端零原生框架 import - 🛡️ 双重安全保护 —
#available(iOS 14, *)编译期保护 +NSClassFromString运行时检测 - ☁️ 云打包兼容修复 —
package.jsonframeworks声明还原,config.json同时声明frameworks+weakFrameworks - 📐 interface.uts — 统一类型定义,跨平台类型一致性
- 📝 日志增强 — 38 处 NSLog 日志,25 处 demo 页面日志,覆盖 ATT 授权全流程
- 🔧 缓存机制兼容 — UTS proxy 缓存清理说明
v1.0.0 (2026-05-08)
- 🎉 首次发布
- ✅ iOS: ATT 权限弹窗 + IDFA 获取
- ✅ Android: Google Advertising ID + 国内 6 厂商 OAID
- ✅ HarmonyOS: OAID 获取
- ✅ 三端统一 API
📄 许可证
MIT License © szy
💡 问题反馈:DCloud 插件市场页面留言

收藏人数:
购买普通授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 20
赞赏 0
下载 12459826
赞赏 1935
赞赏
京公网安备:11010802035340号