安卓 SDK - 数据隐私

文件

遵守数据隐私法

通过通知 Singular 用户同意 GDPR、CCPA 和其他消费者隐私法规的选择,实施符合隐私法规的数据收集。

当用户同意或拒绝与第三方共享其信息时,使用 Singular 的隐私方法来传达他们的选择。这将确保遵守《加州消费者隐私法案》(CCPA)等法规,并使合作伙伴尊重用户的隐私偏好。

了解更多信息:有关Singular如何处理隐私同意的详细信息,请参阅用户隐私和限制数据共享


限制数据共享

控制第三方数据共享

通知Singular用户是否同意使用limitDataSharing方法与第三方合作伙伴共享个人数据。

方法签名

Singular.limitDataSharing(boolean shouldLimitDataSharing)

参数

  • false:用户已选择并同意共享其数据
  • true: true:用户已退出,不同意共享其数据

重要:虽然此方法是可选的,但它会影响属性数据的共享。一些合作伙伴只有在明确通知用户已选择加入时,才会共享完整的归因信息。

使用示例

KotlinJava
// User has opted in to share their data
Singular.limitDataSharing(false)

// User has opted out and declined to share their data
Singular.limitDataSharing(true)

// Example: Set based on user preference
fun handlePrivacyConsent(userConsented: Boolean) {
    // Pass inverse: false = opted in, true = opted out
    Singular.limitDataSharing(!userConsented)
    
    Log.d("Privacy", "Data sharing: ${if (userConsented) "Enabled" else "Limited"}")
}

如何使用

Singular 在用户隐私回邮中使用此设置,并将其传递给需要遵守法规的合作伙伴。


GDPR 合规方法

管理用户跟踪同意和控制SDK功能,以符合GDPR(通用数据保护条例)和其他隐私法规。

跟踪同意管理

跟踪同意

通过向 Singular 服务器发送 GDPR 选入事件,记录用户对跟踪的明确同意。

方法签名

Singular.trackingOptIn()

何时使用

  • GDPR 合规性:当用户明确同意在受 GDPR 监管的地区进行跟踪时调用
  • 同意记录:在 Singular 系统中将用户标记为已提供 GDPR 同意
  • 默认行为:如果没有此调用,SDK 会继续跟踪,但不会明确记录同意信息
KotlinJava
// User accepted tracking consent
Singular.trackingOptIn()

// Example: Call after consent dialog
fun onUserAcceptedTracking() {
    Singular.trackingOptIn()
    Log.d("GDPR", "User opted in to tracking")
}

跟踪控制方法

停止所有跟踪

完全禁用当前用户在此设备上的所有 SDK 跟踪活动。

方法签名

Singular.stopAllTracking()

严重警告:此方法会永久禁用 SDK,直到调用resumeAllTracking() 。禁用状态会在应用程序重启时持续存在,只能通过编程方式逆转。

行为

  • 立即生效:立即停止所有跟踪、事件报告和数据收集功能
  • 持续状态:即使在应用程序关闭和重新打开后也会保持禁用状态
  • 无法自动重置:必须明确调用resumeAllTracking() 才能重新启用
KotlinJava
// User declined all tracking
Singular.stopAllTracking()

// Example: Handle user opt-out
fun onUserDeclinedTracking() {
    Singular.stopAllTracking()
    Log.d("Privacy", "All tracking stopped")
    
    // Optionally store preference
    saveUserTrackingPreference(false)
}

恢复所有跟踪

在使用stopAllTracking() 停止跟踪后重新启用跟踪。

方法签名

Singular.resumeAllTracking()

使用案例

  • 同意更改:用户更改隐私偏好并选择恢复跟踪
  • 隐私设置:用户通过应用程序设置菜单更新同意
  • 地区合规性:当用户移动到非监管区域时,重新启用追踪功能
KotlinJava
// User opted back in to tracking
Singular.resumeAllTracking()

// Example: Handle consent update
fun onUserResumedTracking() {
    Singular.resumeAllTracking()
    Log.d("Privacy", "Tracking resumed")
    
    // Optionally update stored preference
    saveUserTrackingPreference(true)
}

是否已停止所有跟踪

检查当前用户是否已禁用跟踪功能。

方法签名

boolean Singular.isAllTrackingStopped()

返回值

  • true:当前已通过stopAllTracking()停止跟踪
  • false:跟踪处于活动状态(从未停止或恢复
KotlinJava
// Check current tracking status
val isTrackingStopped = Singular.isAllTrackingStopped()

// Example: Display privacy status in settings
fun getPrivacyStatusText(): String {
    return if (Singular.isAllTrackingStopped()) {
        "Tracking: Disabled"
    } else {
        "Tracking: Enabled"
    }
}

// Example: Sync UI with tracking state
fun updatePrivacyToggle() {
    val isStopped = Singular.isAllTrackingStopped()
    privacyToggle.isChecked = !isStopped
    Log.d("Privacy", "Current tracking state: ${if (isStopped) "Stopped" else "Active"}")
}

儿童隐私保护

trackingUnder13

通知Singular用户未满13岁,以遵守COPPA(儿童在线隐私保护法案)和其他儿童隐私保护规定。

方法签名

Singular.trackingUnder13()

合规要求

  • COPPA 合规性:在美国收集 13 岁以下儿童数据的应用程序必须遵守
  • 有年龄限制的内容:当用户在注册或年龄验证时表明自己未满 13 岁时使用
  • 限制跟踪:限制数据收集,以遵守儿童隐私保护法
KotlinJava
// User identified as under 13
Singular.trackingUnder13()

// Example: Call after age verification
fun onAgeVerified(userAge: Int) {
    if (userAge < 13) {
        Singular.trackingUnder13()
        Log.d("Privacy", "COPPA mode enabled for user under 13")
    }
}

重要提示:在确定用户未满 13 周岁后尽早调用此方法,最好是在应用程序初始化期间或年龄验证后立即调用。这样可以确保所有后续跟踪都遵守儿童隐私保护法规。


设置广告标识符限制

限制混合受众应用程序在 SDK 初始化后收集和使用广告标识符(Android 上为 GAID)。

方法签名

Singular.setLimitAdvertisingIdentifiers()

使用案例

  • 混合受众应用程序:同时为成人和儿童服务的应用程序,其年龄在应用程序启动后确定
  • 动态隐私控制:根据用户操作或访问内容调整跟踪
  • 运行时限制:在初始 SDK 设置后应用广告标识符限制
KotlinJava
// Limit advertising identifiers after initialization
Singular.setLimitAdvertisingIdentifiers()

// Example: Mixed audience app with age gate
fun onKidsModeSwitched(isKidsMode: Boolean) {
    if (isKidsMode) {
        Singular.setLimitAdvertisingIdentifiers()
        Log.d("Privacy", "Advertising identifiers limited for kids mode")
    }
}

// Example: Content-based restrictions
fun onViewingChildrensContent() {
    Singular.setLimitAdvertisingIdentifiers()
    Log.d("Privacy", "Ad identifiers restricted for children's content")
}

配置替代方案:如果您在 SDK 启动前就知道隐私要求,也可以在 SDK 初始化期间使用SingularConfig.withLimitAdvertisingIdentifiers() 限制广告标识符。

配置方法

在 SDK 初始化期间为预先知道隐私要求的应用程序设置广告标识符限制。

KotlinJava
// Limit advertising identifiers at initialization
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
    .withLimitAdvertisingIdentifiers()

Singular.init(applicationContext, config)

实施最佳实践

完整隐私管理示例

实施尊重用户偏好并符合法规的全面隐私控制。

KotlinJava
class PrivacyManager(private val context: Context) {
    
    private val prefs = context.getSharedPreferences("privacy_prefs", Context.MODE_PRIVATE)
    
    // Initialize privacy settings on app start
    fun initializePrivacy() {
        val hasUserConsent = getUserConsent()
        val allowDataSharing = getDataSharingPreference()
        val userAge = getUserAge()
        
        // Apply stored preferences
        if (hasUserConsent) {
            Singular.trackingOptIn()
            Singular.resumeAllTracking()
        } else {
            Singular.stopAllTracking()
        }
        
        // Set data sharing preference
        Singular.limitDataSharing(!allowDataSharing)
        
        // Handle children's privacy
        if (userAge > 0 && userAge < 13) {
            Singular.trackingUnder13()
            Singular.setLimitAdvertisingIdentifiers()
        }
        
        Log.d("Privacy", "Initialized: consent=$hasUserConsent, sharing=$allowDataSharing, age=$userAge")
    }
    
    // User accepts tracking via consent dialog
    fun userAcceptedTracking() {
        saveUserConsent(true)
        Singular.trackingOptIn()
        Singular.resumeAllTracking()
        Log.d("Privacy", "User accepted tracking")
    }
    
    // User declines tracking
    fun userDeclinedTracking() {
        saveUserConsent(false)
        Singular.stopAllTracking()
        Log.d("Privacy", "User declined tracking")
    }
    
    // User updates data sharing preference
    fun setDataSharingEnabled(enabled: Boolean) {
        saveDataSharingPreference(enabled)
        // Note: limitDataSharing uses inverse logic
        Singular.limitDataSharing(!enabled)
        Log.d("Privacy", "Data sharing: ${if (enabled) "Enabled" else "Limited"}")
    }
    
    // Handle age verification result
    fun onAgeVerified(age: Int) {
        saveUserAge(age)
        if (age < 13) {
            Singular.trackingUnder13()
            Singular.setLimitAdvertisingIdentifiers()
            Log.d("Privacy", "COPPA restrictions applied for user under 13")
        }
    }
    
    // Get current tracking status
    fun isTrackingEnabled(): Boolean {
        return !Singular.isAllTrackingStopped()
    }
    
    // Private helper methods
    private fun getUserConsent(): Boolean {
        return prefs.getBoolean("user_consent", false)
    }
    
    private fun saveUserConsent(consent: Boolean) {
        prefs.edit().putBoolean("user_consent", consent).apply()
    }
    
    private fun getDataSharingPreference(): Boolean {
        return prefs.getBoolean("data_sharing", false)
    }
    
    private fun saveDataSharingPreference(enabled: Boolean) {
        prefs.edit().putBoolean("data_sharing", enabled).apply()
    }
    
    private fun getUserAge(): Int {
        return prefs.getInt("user_age", 0)
    }
    
    private fun saveUserAge(age: Int) {
        prefs.edit().putInt("user_age", age).apply()
    }
}

最佳实践

  • 持久存储:将用户偏好保存在共享偏好或安全存储中
  • 尽早初始化:尽可能在 SDK 初始化前应用隐私设置
  • UI 同步:使用isAllTrackingStopped()保持设置 UI 与实际 SDK 状态同步
  • 清晰沟通:在应用程序设置中提供清晰、易用的隐私控件
  • 年龄验证:对面向儿童的应用程序实施强大的年龄验证
  • 组合控制:对于 13 岁以下用户,同时应用trackingUnder13()setLimitAdvertisingIdentifiers()