遵守数据隐私法
通过通知 Singular 用户同意 GDPR、CCPA 和其他消费者隐私法规的选择,实施符合隐私法规的数据收集。
当用户同意或拒绝与第三方共享其信息时,使用 Singular 的隐私方法来传达他们的选择。这将确保遵守《加州消费者隐私法案》(CCPA)等法规,并使合作伙伴尊重用户的隐私偏好。
了解更多信息:有关Singular如何处理隐私同意的详细信息,请参阅用户隐私和限制数据共享。
限制数据共享
控制第三方数据共享
通知Singular用户是否同意使用limitDataSharing方法与第三方合作伙伴共享个人数据。
方法签名:
Singular.limitDataSharing(boolean shouldLimitDataSharing)
参数:
- false:用户已选择并同意共享其数据
- true: true:用户已退出,不同意共享其数据
重要:虽然此方法是可选的,但它会影响属性数据的共享。一些合作伙伴只有在明确通知用户已选择加入时,才会共享完整的归因信息。
使用示例
// 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"}")
}
// 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
public void handlePrivacyConsent(boolean userConsented) {
// Pass inverse: false = opted in, true = opted out
Singular.limitDataSharing(!userConsented);
Log.d("Privacy", "Data sharing: " + (userConsented ? "Enabled" : "Limited"));
}
如何使用:
Singular 在用户隐私回邮中使用此设置,并将其传递给需要遵守法规的合作伙伴。
GDPR 合规方法
管理用户跟踪同意和控制SDK功能,以符合GDPR(通用数据保护条例)和其他隐私法规。
跟踪同意管理
跟踪同意
通过向 Singular 服务器发送 GDPR 选入事件,记录用户对跟踪的明确同意。
方法签名:
Singular.trackingOptIn()
何时使用:
- GDPR 合规性:当用户明确同意在受 GDPR 监管的地区进行跟踪时调用
- 同意记录:在 Singular 系统中将用户标记为已提供 GDPR 同意
- 默认行为:如果没有此调用,SDK 会继续跟踪,但不会明确记录同意信息
// User accepted tracking consent
Singular.trackingOptIn()
// Example: Call after consent dialog
fun onUserAcceptedTracking() {
Singular.trackingOptIn()
Log.d("GDPR", "User opted in to tracking")
}
// User accepted tracking consent
Singular.trackingOptIn();
// Example: Call after consent dialog
public void onUserAcceptedTracking() {
Singular.trackingOptIn();
Log.d("GDPR", "User opted in to tracking");
}
跟踪控制方法
停止所有跟踪
完全禁用当前用户在此设备上的所有 SDK 跟踪活动。
方法签名:
Singular.stopAllTracking()
严重警告:此方法会永久禁用 SDK,直到调用resumeAllTracking() 。禁用状态会在应用程序重启时持续存在,只能通过编程方式逆转。
行为:
- 立即生效:立即停止所有跟踪、事件报告和数据收集功能
- 持续状态:即使在应用程序关闭和重新打开后也会保持禁用状态
-
无法自动重置:必须明确调用
resumeAllTracking()才能重新启用
// 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)
}
// User declined all tracking
Singular.stopAllTracking();
// Example: Handle user opt-out
public void onUserDeclinedTracking() {
Singular.stopAllTracking();
Log.d("Privacy", "All tracking stopped");
// Optionally store preference
saveUserTrackingPreference(false);
}
恢复所有跟踪
在使用stopAllTracking() 停止跟踪后重新启用跟踪。
方法签名:
Singular.resumeAllTracking()
使用案例:
- 同意更改:用户更改隐私偏好并选择恢复跟踪
- 隐私设置:用户通过应用程序设置菜单更新同意
- 地区合规性:当用户移动到非监管区域时,重新启用追踪功能
// 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)
}
// User opted back in to tracking
Singular.resumeAllTracking();
// Example: Handle consent update
public void onUserResumedTracking() {
Singular.resumeAllTracking();
Log.d("Privacy", "Tracking resumed");
// Optionally update stored preference
saveUserTrackingPreference(true);
}
是否已停止所有跟踪
检查当前用户是否已禁用跟踪功能。
方法签名:
boolean Singular.isAllTrackingStopped()
返回值
-
true:当前已通过
stopAllTracking()停止跟踪 - false:跟踪处于活动状态(从未停止或恢复
// 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"}")
}
// Check current tracking status
boolean isTrackingStopped = Singular.isAllTrackingStopped();
// Example: Display privacy status in settings
public String getPrivacyStatusText() {
if (Singular.isAllTrackingStopped()) {
return "Tracking: Disabled";
} else {
return "Tracking: Enabled";
}
}
// Example: Sync UI with tracking state
public void updatePrivacyToggle() {
boolean isStopped = Singular.isAllTrackingStopped();
privacyToggle.setChecked(!isStopped);
Log.d("Privacy", "Current tracking state: " + (isStopped ? "Stopped" : "Active"));
}
儿童隐私保护
trackingUnder13
通知Singular用户未满13岁,以遵守COPPA(儿童在线隐私保护法案)和其他儿童隐私保护规定。
方法签名:
Singular.trackingUnder13()
合规要求:
- COPPA 合规性:在美国收集 13 岁以下儿童数据的应用程序必须遵守
- 有年龄限制的内容:当用户在注册或年龄验证时表明自己未满 13 岁时使用
- 限制跟踪:限制数据收集,以遵守儿童隐私保护法
// 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")
}
}
// User identified as under 13
Singular.trackingUnder13();
// Example: Call after age verification
public void onAgeVerified(int userAge) {
if (userAge < 13) {
Singular.trackingUnder13();
Log.d("Privacy", "COPPA mode enabled for user under 13");
}
}
重要提示:在确定用户未满 13 周岁后尽早调用此方法,最好是在应用程序初始化期间或年龄验证后立即调用。这样可以确保所有后续跟踪都遵守儿童隐私保护法规。
设置广告标识符限制
限制混合受众应用程序在 SDK 初始化后收集和使用广告标识符(Android 上为 GAID)。
方法签名:
Singular.setLimitAdvertisingIdentifiers()
使用案例:
- 混合受众应用程序:同时为成人和儿童服务的应用程序,其年龄在应用程序启动后确定
- 动态隐私控制:根据用户操作或访问内容调整跟踪
- 运行时限制:在初始 SDK 设置后应用广告标识符限制
// 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")
}
// Limit advertising identifiers after initialization
Singular.setLimitAdvertisingIdentifiers();
// Example: Mixed audience app with age gate
public void onKidsModeSwitched(boolean isKidsMode) {
if (isKidsMode) {
Singular.setLimitAdvertisingIdentifiers();
Log.d("Privacy", "Advertising identifiers limited for kids mode");
}
}
// Example: Content-based restrictions
public void onViewingChildrensContent() {
Singular.setLimitAdvertisingIdentifiers();
Log.d("Privacy", "Ad identifiers restricted for children's content");
}
配置替代方案:如果您在 SDK 启动前就知道隐私要求,也可以在 SDK 初始化期间使用SingularConfig.withLimitAdvertisingIdentifiers() 限制广告标识符。
配置方法
在 SDK 初始化期间为预先知道隐私要求的应用程序设置广告标识符限制。
// Limit advertising identifiers at initialization
val config = SingularConfig("SDK_KEY", "SDK_SECRET")
.withLimitAdvertisingIdentifiers()
Singular.init(applicationContext, config)
// Limit advertising identifiers at initialization
SingularConfig config = new SingularConfig("SDK_KEY", "SDK_SECRET")
.withLimitAdvertisingIdentifiers();
Singular.init(getApplicationContext(), config);
实施最佳实践
完整隐私管理示例
实施尊重用户偏好并符合法规的全面隐私控制。
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()
}
}
public class PrivacyManager {
private Context context;
private SharedPreferences prefs;
public PrivacyManager(Context context) {
this.context = context;
this.prefs = context.getSharedPreferences("privacy_prefs", Context.MODE_PRIVATE);
}
// Initialize privacy settings on app start
public void initializePrivacy() {
boolean hasUserConsent = getUserConsent();
boolean allowDataSharing = getDataSharingPreference();
int 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
public void userAcceptedTracking() {
saveUserConsent(true);
Singular.trackingOptIn();
Singular.resumeAllTracking();
Log.d("Privacy", "User accepted tracking");
}
// User declines tracking
public void userDeclinedTracking() {
saveUserConsent(false);
Singular.stopAllTracking();
Log.d("Privacy", "User declined tracking");
}
// User updates data sharing preference
public void setDataSharingEnabled(boolean enabled) {
saveDataSharingPreference(enabled);
// Note: limitDataSharing uses inverse logic
Singular.limitDataSharing(!enabled);
Log.d("Privacy", "Data sharing: " + (enabled ? "Enabled" : "Limited"));
}
// Handle age verification result
public void onAgeVerified(int age) {
saveUserAge(age);
if (age < 13) {
Singular.trackingUnder13();
Singular.setLimitAdvertisingIdentifiers();
Log.d("Privacy", "COPPA restrictions applied for user under 13");
}
}
// Get current tracking status
public boolean isTrackingEnabled() {
return !Singular.isAllTrackingStopped();
}
// Private helper methods
private boolean getUserConsent() {
return prefs.getBoolean("user_consent", false);
}
private void saveUserConsent(boolean consent) {
prefs.edit().putBoolean("user_consent", consent).apply();
}
private boolean getDataSharingPreference() {
return prefs.getBoolean("data_sharing", false);
}
private void saveDataSharingPreference(boolean enabled) {
prefs.edit().putBoolean("data_sharing", enabled).apply();
}
private int getUserAge() {
return prefs.getInt("user_age", 0);
}
private void saveUserAge(int age) {
prefs.edit().putInt("user_age", age).apply();
}
}
最佳实践:
- 持久存储:将用户偏好保存在共享偏好或安全存储中
- 尽早初始化:尽可能在 SDK 初始化前应用隐私设置
-
UI 同步:使用
isAllTrackingStopped()保持设置 UI 与实际 SDK 状态同步 - 清晰沟通:在应用程序设置中提供清晰、易用的隐私控件
- 年龄验证:对面向儿童的应用程序实施强大的年龄验证
-
组合控制:对于 13 岁以下用户,同时应用
trackingUnder13()和setLimitAdvertisingIdentifiers()