DevCheck-lib/DeviceInfo-DeviceID和GAID使用示例.md
2025-12-24 15:32:35 +08:00

422 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DeviceInfo - Device ID 和 GAID 使用示例
## 概述
DeviceInfo 类现在提供了完整的设备标识符获取功能,包括 Android ID (Device ID) 和 Google Advertising ID (GAID)。
## 新增功能
### 1. Android ID (Device ID)
- `getAndroidId()` - 获取 Android ID
### 2. Google Advertising ID (GAID)
- `getAdvertisingId()` - 协程方式获取 GAID推荐
- `getAdvertisingIdSync()` - 同步方式获取 GAID不推荐
- `getDeviceIdentifiers()` - 获取所有标识符
### 3. 数据类
- `AdvertisingIdInfo` - GAID 信息
- `DeviceIdentifiers` - 设备标识符集合
## 使用方法
### 1. 初始化
```kotlin
import com.xyzshell.andinfo.AndInfo
// 在 Application 或 Activity 中初始化
AndInfo.init(applicationContext)
// 获取 DeviceInfo 实例
val deviceInfo = AndInfo.instance.device
```
### 2. 获取 Android ID (Device ID)
#### 基本使用
```kotlin
// 获取 Android ID
val androidId = deviceInfo.getAndroidId()
println("Android ID: $androidId")
// 输出示例: "Android ID: 9774d56d682e549c"
```
#### Android ID 特点
- **格式**: 64位十六进制字符串
- **生成时机**: 设备首次启动时随机生成
- **持久性**:
- 出厂重置后会改变
- 清除应用数据不会改变
- **作用域**:
- Android 8.0+ 后,每个应用和用户组合都会获得不同的 Android ID
- Android 8.0 之前,所有应用获得相同的 Android ID
- **权限**: 不需要特殊权限
#### 适用场景
```kotlin
// 1. 应用级设备标识
fun getDeviceTag(): String {
val deviceInfo = AndInfo.instance.device
return "device_${deviceInfo.getAndroidId()}"
}
// 2. 用户设备绑定
fun bindDeviceToUser(userId: String) {
val deviceInfo = AndInfo.instance.device
val androidId = deviceInfo.getAndroidId()
// 将 androidId 与 userId 关联存储
saveBinding(userId, androidId)
}
// 3. 设备唯一性校验
fun isNewDevice(): Boolean {
val deviceInfo = AndInfo.instance.device
val androidId = deviceInfo.getAndroidId()
return !isDeviceRegistered(androidId)
}
```
### 3. 获取 GAID (Google Advertising ID)
#### 协程方式(推荐)
```kotlin
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
// 在 Activity 或 Fragment 中
lifecycleScope.launch {
val deviceInfo = AndInfo.instance.device
val gaidInfo = deviceInfo.getAdvertisingId()
if (gaidInfo != null) {
println("GAID: ${gaidInfo.id}")
println("是否限制追踪: ${gaidInfo.isLimitAdTrackingEnabled}")
// 根据追踪限制状态决定是否使用
if (!gaidInfo.isLimitAdTrackingEnabled) {
// 用户允许广告追踪,可以使用 GAID
sendToAnalytics(gaidInfo.id)
} else {
// 用户限制了广告追踪,应该尊重用户选择
println("用户已限制广告追踪")
}
} else {
// Google Play Services 不可用
println("无法获取 GAID设备可能没有 Google Play Services")
}
}
```
#### 在 ViewModel 中使用
```kotlin
class MainViewModel : ViewModel() {
fun loadAdvertisingId() {
viewModelScope.launch {
val deviceInfo = AndInfo.instance.device
val gaidInfo = deviceInfo.getAdvertisingId()
gaidInfo?.let { info ->
_advertisingId.value = info.id
_isTrackingLimited.value = info.isLimitAdTrackingEnabled
}
}
}
}
```
#### 同步方式(不推荐)
```kotlin
// ⚠️ 警告:会阻塞当前线程,不要在主线程调用
Thread {
val deviceInfo = AndInfo.instance.device
val gaidInfo = deviceInfo.getAdvertisingIdSync()
gaidInfo?.let { info ->
println("GAID: ${info.id}")
}
}.start()
```
#### GAID 特点
- **格式**: UUID 格式的字符串
- **示例**: "38400000-8cf0-11bd-b23e-10b96e40000d"
- **依赖**: 需要 Google Play Services
- **用户控制**:
- 用户可以在设置中重置 GAID
- 用户可以选择限制广告追踪
- **权限**: 不需要特殊权限,但需要 Google Play Services
- **线程**: 必须在后台线程调用
### 4. 获取所有设备标识符
```kotlin
// 一次性获取所有标识符
lifecycleScope.launch {
val deviceInfo = AndInfo.instance.device
val identifiers = deviceInfo.getDeviceIdentifiers()
println("=== 设备标识符 ===")
println("Android ID: ${identifiers.androidId}")
identifiers.advertisingId?.let { gaid ->
println("GAID: ${gaid.id}")
println("限制追踪: ${gaid.isLimitAdTrackingEnabled}")
} ?: run {
println("GAID: 不可用")
}
}
```
### 5. 完整示例:设备信息收集
```kotlin
class DeviceInfoActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycleScope.launch {
collectDeviceInfo()
}
}
private suspend fun collectDeviceInfo() {
val deviceInfo = AndInfo.instance.device
// 基本设备信息
val brand = deviceInfo.brand
val model = deviceInfo.model
val manufacturer = deviceInfo.manufacturer
// 设备标识符
val androidId = deviceInfo.getAndroidId()
val gaidInfo = deviceInfo.getAdvertisingId()
// 显示信息
val info = buildString {
appendLine("=== 设备信息 ===")
appendLine("品牌: $brand")
appendLine("型号: $model")
appendLine("制造商: $manufacturer")
appendLine()
appendLine("=== 设备标识符 ===")
appendLine("Android ID: $androidId")
if (gaidInfo != null) {
appendLine("GAID: ${gaidInfo.id}")
appendLine("限制追踪: ${if (gaidInfo.isLimitAdTrackingEnabled) "是" else "否"}")
} else {
appendLine("GAID: 不可用(可能没有 Google Play Services")
}
}
println(info)
// 或显示在 UI 上
// textView.text = info
}
}
```
## 数据结构
### AdvertisingIdInfo
```kotlin
/**
* 广告标识符信息数据类
*/
data class AdvertisingIdInfo(
val id: String, // GAID
val isLimitAdTrackingEnabled: Boolean // 是否限制广告追踪
)
```
### DeviceIdentifiers
```kotlin
/**
* 设备标识符集合数据类
*/
data class DeviceIdentifiers(
val androidId: String, // Android ID
val advertisingId: AdvertisingIdInfo? // GAID可能为 null
)
```
## Android ID vs GAID 对比
| 特性 | Android ID | GAID |
|------|-----------|------|
| **格式** | 64位十六进制 | UUID |
| **示例** | 9774d56d682e549c | 38400000-8cf0-11bd-b23e-10b96e40000d |
| **依赖** | 无 | Google Play Services |
| **权限** | 无需权限 | 无需权限 |
| **重置** | 出厂重置后改变 | 用户可随时重置 |
| **作用域** | Android 8.0+ 按应用区分 | 全局统一 |
| **用户控制** | 不可控制 | 可限制追踪 |
| **适用场景** | 应用内标识、设备绑定 | 广告追踪、分析 |
| **隐私友好** | 中等 | 高(用户可控) |
## 典型应用场景
### 1. 广告归因
```kotlin
suspend fun trackAdConversion(campaignId: String) {
val deviceInfo = AndInfo.instance.device
val gaidInfo = deviceInfo.getAdvertisingId()
if (gaidInfo != null && !gaidInfo.isLimitAdTrackingEnabled) {
// 用户允许追踪,上报转化数据
analyticsService.trackConversion(
gaid = gaidInfo.id,
campaignId = campaignId
)
} else {
// 使用匿名方式或不追踪
analyticsService.trackAnonymousConversion(campaignId)
}
}
```
### 2. 用户设备管理
```kotlin
suspend fun registerDevice() {
val deviceInfo = AndInfo.instance.device
val identifiers = deviceInfo.getDeviceIdentifiers()
// 注册设备信息
val deviceProfile = DeviceProfile(
androidId = identifiers.androidId,
brand = deviceInfo.brand,
model = deviceInfo.model,
timestamp = System.currentTimeMillis()
)
saveDeviceProfile(deviceProfile)
}
```
### 3. 防作弊检测
```kotlin
suspend fun checkDeviceFraud(): Boolean {
val deviceInfo = AndInfo.instance.device
val androidId = deviceInfo.getAndroidId()
// 检查设备是否被标记为作弊
return fraudDetectionService.isDeviceFlagged(androidId)
}
```
### 4. A/B 测试分组
```kotlin
suspend fun getExperimentGroup(): String {
val deviceInfo = AndInfo.instance.device
val gaidInfo = deviceInfo.getAdvertisingId()
// 使用 GAID 的哈希值进行分组
val deviceId = gaidInfo?.id ?: deviceInfo.getAndroidId()
val hash = deviceId.hashCode()
return if (hash % 2 == 0) "GroupA" else "GroupB"
}
```
### 5. 隐私合规检查
```kotlin
suspend fun checkPrivacyCompliance(): PrivacyStatus {
val deviceInfo = AndInfo.instance.device
val gaidInfo = deviceInfo.getAdvertisingId()
return PrivacyStatus(
hasGooglePlayServices = gaidInfo != null,
isTrackingLimited = gaidInfo?.isLimitAdTrackingEnabled ?: true,
canUsePersonalizedAds = gaidInfo?.let { !it.isLimitAdTrackingEnabled } ?: false
)
}
```
## 依赖配置
要使用 GAID 功能,需要在 `build.gradle` 中添加依赖:
```gradle
dependencies {
// Google Play Services - Advertising ID
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
// Kotlin Coroutines如果项目中还没有
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}
```
## 注意事项
### 1. Android ID
- ⚠️ Android 8.0+ 后,每个应用获得的 Android ID 不同
- ⚠️ 出厂重置后会改变
- ⚠️ 不应用于跨应用追踪
- ✅ 适合应用内设备标识
### 2. GAID
- ⚠️ 需要 Google Play Services国内设备可能不可用
- ⚠️ 必须尊重用户的"限制广告追踪"设置
- ⚠️ 必须在后台线程调用
- ⚠️ 用户可以随时重置
- ✅ 适合广告归因和分析
- ✅ 符合 Google Play 政策
### 3. 隐私合规
- 📋 遵守 GDPR、CCPA 等隐私法规
- 📋 在隐私政策中说明标识符用途
- 📋 尊重用户的追踪限制选择
- 📋 提供用户删除数据的选项
### 4. 最佳实践
```kotlin
suspend fun getDeviceIdentifierForAnalytics(): String? {
val deviceInfo = AndInfo.instance.device
// 1. 优先使用 GAID如果可用且用户允许
val gaidInfo = deviceInfo.getAdvertisingId()
if (gaidInfo != null && !gaidInfo.isLimitAdTrackingEnabled) {
return gaidInfo.id
}
// 2. 用户限制了追踪,不应该使用任何标识符
if (gaidInfo?.isLimitAdTrackingEnabled == true) {
return null // 返回 null 表示不追踪
}
// 3. GAID 不可用(可能是国内设备),使用 Android ID
// 注意:这种情况下应该获得用户明确同意
return if (hasUserConsent()) {
deviceInfo.getAndroidId()
} else {
null
}
}
```
## 示例输出
```
=== 设备信息 ===
品牌: Samsung
型号: SM-G998B
制造商: samsung
=== 设备标识符 ===
Android ID: 9774d56d682e549c
GAID: 38400000-8cf0-11bd-b23e-10b96e40000d
限制追踪: 否
```
## 完成度
**100%** - 所有功能都已实现
- Android ID (Device ID) 获取 ✅
- GAID 获取(协程方式)✅
- GAID 获取(同步方式)✅
- 追踪限制状态检测 ✅
- 综合标识符获取 ✅
- 完整的中文注释 ✅
- 详细的使用文档 ✅
- 隐私合规建议 ✅