device_id_all 0.0.1 copy "device_id_all: ^0.0.1" to clipboard
device_id_all: ^0.0.1 copied to clipboard

Best-effort Flutter plugin for Android and iOS device identifiers, including Android ID, OAID, GAID, IDFA and app UUID.

device_id_all #

一个 Flutter 插件,用于在 Android 和 iOS 上尽可能读取常见设备标识。

能力边界 #

这些标识受系统版本、权限、用户授权、厂商 SDK 和应用商店政策限制。插件遵循一个规则:能合法读取就返回字符串,不能读取就返回 null

字段 平台 说明
bestEffortDeviceId Android/iOS Android 为 ANDROID_ID;iOS 为 identifierForVendor
androidId Android Settings.Secure.ANDROID_ID
androidImei Android 需要 READ_PHONE_STATE;Android 10+ 普通应用通常不可读。
appInstanceUuid Android/iOS 插件生成并保存在 App 沙盒内的 UUID,卸载重装会变化。
iosUdid iOS Apple 禁止普通 App 获取真实 UDID,正常返回 null
androidOaid Android 尝试常见系统来源;宿主 App 集成 HMS/厂商 SDK 时可提高成功率。
iosIdfa iOS iOS 14+ 需要 ATT 授权;未授权返回 null
androidGaid Android 需要 Google Play 服务及宿主 App 中存在 Advertising ID 客户端类。

Android OAID 配置 #

插件已接入 Android_CN_OAID,Android 侧会优先通过它读取 OAID/AAID,再回退到插件内置的少量厂商 Provider 方案。

如果宿主 App 使用 Gradle 7.0+,并且在 settings.gradlesettings.gradle.kts 中启用了 dependencyResolutionManagement,需要确认仓库里包含:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        google()
        mavenCentral()
        maven { url 'https://storage.googleapis.com/download.flutter.io' }
        maven { url 'https://jitpack.io' }
        maven { url 'https://developer.huawei.com/repo' }
        maven { url 'https://developer.hihonor.com/repo' }
    }
}

如果已有 dependencyResolutionManagement,只需要合并仓库配置:

repositories {
    maven { url 'https://jitpack.io' }
    maven { url 'https://developer.huawei.com/repo' }
    maven { url 'https://developer.hihonor.com/repo' }
}

Kotlin DSL 写法:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        google()
        mavenCentral()
        maven("https://storage.googleapis.com/download.flutter.io")
        maven("https://jitpack.io")
        maven("https://developer.huawei.com/repo")
        maven("https://developer.hihonor.com/repo")
    }
}

如果已有 dependencyResolutionManagement,只需要合并仓库配置:

repositories {
    maven("https://jitpack.io")
    maven("https://developer.huawei.com/repo")
    maven("https://developer.hihonor.com/repo")
}

建议在用户同意隐私政策后预取 OAID:

final plugin = DeviceIdAll();
await plugin.preloadAndroidOaid();
final oaid = await plugin.getAndroidOaid();

注意:OAID 只在部分国产 Android 真机和支持 AAID 的 Google Play 服务环境中可用;模拟器、用户关闭广告标识、系统服务缺失或厂商接口不可用时仍会返回 null

使用方式 #

final plugin = DeviceIdAll();
final identifiers = await plugin.getAllDeviceIdentifiers();

print(identifiers.bestEffortDeviceId);
print(identifiers.androidId);
print(identifiers.iosIdfa);

注意:getAllDeviceIdentifiers() 只负责读取当前可用值,不会自动弹出 iOS ATT 授权框。需要 IDFA 时,应先按“iOS IDFA 授权”一节主动请求授权。

也可以按标识单独读取:

final androidId = await plugin.getAndroidId();
final appUuid = await plugin.getAppInstanceUuid();
final gaid = await plugin.getAndroidGaid();

iOS IDFA 授权 #

IDFA 不是普通设备 ID。iOS 14+ 必须先通过 App Tracking Transparency 授权,用户允许后才可能读取到非空 iosIdfa

宿主 App 必须先在 Info.plist 中配置:

<key>NSUserTrackingUsageDescription</key>
<string>用于提供更准确的广告归因和效果统计。</string>

推荐调用流程:

final plugin = DeviceIdAll();

final status = await plugin.getIosTrackingAuthorizationStatus();

if (status == IosTrackingAuthorizationStatus.notDetermined) {
  final newStatus = await plugin.requestIosTrackingAuthorization();
  if (newStatus == IosTrackingAuthorizationStatus.authorized) {
    final idfa = await plugin.getIosIdfa();
    print(idfa);
  }
} else if (status == IosTrackingAuthorizationStatus.authorized) {
  final idfa = await plugin.getIosIdfa();
  print(idfa);
}

如果页面刚启动就请求授权,部分系统版本可能不会马上展示弹窗。更稳妥的做法是在首帧渲染后再请求,或者由用户点击按钮触发:

WidgetsBinding.instance.addPostFrameCallback((_) async {
  await Future<void>.delayed(const Duration(milliseconds: 600));
  final status = await plugin.requestIosTrackingAuthorization();
  final idfa = status == IosTrackingAuthorizationStatus.authorized
      ? await plugin.getIosIdfa()
      : null;
});

系统不弹 ATT 授权框的常见原因:

  • Info.plist 没有配置 NSUserTrackingUsageDescription
  • 当前状态已经是 denied,用户之前拒绝过;系统不会重复弹窗。
  • 系统设置中关闭了“允许 App 请求跟踪”。
  • 当前状态是 restricted,例如儿童账号、受管理设备或系统策略限制。
  • 已经授权过,状态是 authorized,此时不会再弹窗,直接读取 IDFA。

可以通过 getIosTrackingAuthorizationStatus() 判断当前状态。example 页面也展示了 trackingStatus,并提供“请求 IDFA 授权”按钮,方便真机验证。

Android IMEI 权限 #

如果宿主 App 确实需要尝试读取 IMEI,需要自行在 AndroidManifest 中声明,并在运行时申请权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />

注意:Android 10 及以上普通应用即使有权限也通常无法读取 IMEI。上架应用商店前应评估合规风险。

1
likes
0
points
223
downloads

Publisher

unverified uploader

Weekly Downloads

Best-effort Flutter plugin for Android and iOS device identifiers, including Android ID, OAID, GAID, IDFA and app UUID.

Homepage

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on device_id_all

Packages that implement device_id_all