遵守数据隐私法
通过通知 Singular 用户同意 GDPR、CCPA 和其他消费者隐私法规的选择,实施符合隐私法规的数据收集。
当用户同意或拒绝与第三方共享其信息时,使用 Singular 的隐私方法来传达他们的选择。这将确保遵守《加州消费者隐私法案》(CCPA)等法规,并使合作伙伴尊重用户的隐私偏好。
了解更多信息:有关Singular如何处理隐私同意的详细信息,请参阅用户隐私和限制数据共享。
限制数据共享
控制第三方数据共享
通知Singular用户是否同意使用LimitDataSharing 方法与第三方合作伙伴共享个人数据。
方法签名:
SingularSDK.LimitDataSharing(bool shouldLimitDataSharing)
参数:
- false:用户已选择并同意共享其数据
- true: true:用户已退出,不同意共享其数据
重要:虽然此方法是可选的,但它会影响属性数据的共享。一些合作伙伴只有在明确通知用户已选择加入时,才会共享完整的属性信息。
使用示例
using UnityEngine;
using Singular;
public class PrivacyManager : MonoBehaviour
{
// User has opted in to share their data
public void OnUserOptedInToDataSharing()
{
SingularSDK.LimitDataSharing(false);
Debug.Log("Data sharing enabled");
}
// User has opted out and declined to share their data
public void OnUserOptedOutOfDataSharing()
{
SingularSDK.LimitDataSharing(true);
Debug.Log("Data sharing limited");
}
// Example: Set based on user preference
public void HandlePrivacyConsent(bool userConsented)
{
// Pass inverse: false = opted in, true = opted out
SingularSDK.LimitDataSharing(!userConsented);
Debug.Log($"Data sharing: {(userConsented ? "Enabled" : "Limited")}");
}
}
如何使用:
Singular 在用户隐私回邮中使用此设置,并将其传递给需要遵守法规的合作伙伴。
GDPR 合规方法
管理用户跟踪同意和控制SDK功能,以符合GDPR(通用数据保护条例)和其他隐私法规。
跟踪同意管理
跟踪同意
通过向 Singular 服务器发送 GDPR 选入事件,记录用户对跟踪的明确同意。
方法签名:
SingularSDK.TrackingOptIn()
何时使用:
- GDPR 合规性:当用户明确同意在受 GDPR 监管的地区进行跟踪时调用
- 同意记录:在 Singular 系统中将用户标记为已提供 GDPR 同意
- 默认行为:如果没有此调用,SDK 会继续跟踪,但不会明确记录同意信息
using UnityEngine;
using Singular;
public class GDPRManager : MonoBehaviour
{
// User accepted tracking consent
public void OnUserAcceptedTracking()
{
SingularSDK.TrackingOptIn();
Debug.Log("User opted in to tracking");
}
// Example: Call after consent dialog
public void ShowGDPRConsentDialog()
{
// Your consent dialog UI logic here
// ...
// If user accepts:
OnUserAcceptedTracking();
}
}
跟踪控制方法
停止所有跟踪
完全禁用当前用户在此设备上的所有 SDK 跟踪活动。
方法签名:
SingularSDK.StopAllTracking()
严重警告:此方法会永久禁用 SDK,直到调用ResumeAllTracking() 。禁用状态会在应用程序重启时持续存在,只能通过编程方式逆转。
行为:
- 立即生效:立即停止所有跟踪、事件报告和数据收集功能
- 持续状态:即使在应用程序关闭和重新打开后也会保持禁用状态
-
无法自动重置:必须明确调用
ResumeAllTracking()才能重新启用
using UnityEngine;
using Singular;
public class TrackingController : MonoBehaviour
{
// User declined all tracking
public void OnUserDeclinedTracking()
{
SingularSDK.StopAllTracking();
Debug.Log("All tracking stopped");
// Optionally store preference
PlayerPrefs.SetInt("tracking_enabled", 0);
PlayerPrefs.Save();
}
// Example: Handle user opt-out from settings menu
public void HandlePrivacySettingsChange(bool trackingEnabled)
{
if (!trackingEnabled)
{
SingularSDK.StopAllTracking();
Debug.Log("Privacy settings: Tracking disabled");
}
}
}
恢复所有跟踪
在使用StopAllTracking() 停止跟踪后重新启用跟踪。
方法签名:
SingularSDK.ResumeAllTracking()
使用案例:
- 同意更改:用户更改隐私偏好并选择恢复跟踪
- 隐私设置:用户通过应用程序设置菜单更新同意
- 地区合规性:当用户转移到非监管区域时重新启用跟踪功能
using UnityEngine;
using Singular;
public class TrackingController : MonoBehaviour
{
// User opted back in to tracking
public void OnUserResumedTracking()
{
SingularSDK.ResumeAllTracking();
Debug.Log("Tracking resumed");
// Optionally update stored preference
PlayerPrefs.SetInt("tracking_enabled", 1);
PlayerPrefs.Save();
}
// Example: Handle consent update from settings
public void HandlePrivacySettingsChange(bool trackingEnabled)
{
if (trackingEnabled)
{
SingularSDK.ResumeAllTracking();
Debug.Log("Privacy settings: Tracking enabled");
}
}
}
IsAllTrackingStopped
检查当前用户是否已禁用跟踪功能。
方法签名:
bool SingularSDK.IsAllTrackingStopped()
返回 返回 返回 返回值值值值
-
true:当前已通过
StopAllTracking()停止跟踪 - false:跟踪处于活动状态(从未停止或恢复
using UnityEngine;
using UnityEngine.UI;
using Singular;
public class PrivacySettingsUI : MonoBehaviour
{
public Toggle trackingToggle;
public Text statusText;
void Start()
{
// Check current tracking status on startup
UpdatePrivacyUI();
}
// Check current tracking status
public bool IsTrackingEnabled()
{
return !SingularSDK.IsAllTrackingStopped();
}
// Example: Display privacy status in settings
public string GetPrivacyStatusText()
{
if (SingularSDK.IsAllTrackingStopped())
{
return "Tracking: Disabled";
}
else
{
return "Tracking: Enabled";
}
}
// Example: Sync UI with tracking state
public void UpdatePrivacyUI()
{
bool isStopped = SingularSDK.IsAllTrackingStopped();
if (trackingToggle != null)
{
trackingToggle.isOn = !isStopped;
}
if (statusText != null)
{
statusText.text = GetPrivacyStatusText();
}
Debug.Log($"Current tracking state: {(isStopped ? "Stopped" : "Active")}");
}
// Handle toggle change from UI
public void OnTrackingToggleChanged(bool enabled)
{
if (enabled)
{
SingularSDK.ResumeAllTracking();
}
else
{
SingularSDK.StopAllTracking();
}
UpdatePrivacyUI();
}
}
儿童隐私保护
13 岁以下用户跟踪
通知 Singular 用户未满 13 周岁,以遵守 COPPA(儿童在线隐私保护法案)和其他儿童隐私法规。
方法签名:
SingularSDK.TrackingUnder13()
合规要求:
- COPPA 合规性:收集美国 13 岁以下儿童数据的应用程序必须遵守
- 有年龄限制的内容:当用户在注册或年龄验证时表明自己未满 13 岁时使用
- 限制跟踪:限制数据收集,以遵守儿童隐私保护法
using UnityEngine;
using Singular;
public class COPPAManager : MonoBehaviour
{
// User identified as under 13
public void OnUserUnder13()
{
SingularSDK.TrackingUnder13();
Debug.Log("COPPA mode enabled for user under 13");
}
// Example: Call after age verification
public void OnAgeVerified(int userAge)
{
if (userAge < 13)
{
SingularSDK.TrackingUnder13();
Debug.Log("COPPA restrictions applied");
// Also limit advertising identifiers
SingularSDK.SetLimitAdvertisingIdentifiers(true);
}
}
}
重要提示:在确定用户未满 13 周岁后尽早调用此方法,最好是在应用程序初始化期间或年龄验证后立即调用。这样可确保所有后续跟踪都遵守儿童隐私保护法规。
设置广告标识符限制
在混合受众应用程序的 SDK 初始化后,限制广告标识符(Android 上为 GAID,iOS 上为 IDFA)的收集和使用。
方法签名:
SingularSDK.SetLimitAdvertisingIdentifiers(bool isEnabled)
参数:
- true:启用限制广告标识符模式(限制收集
- false:禁用有限广告标识符模式:禁用有限广告标识符模式(正常收集
使用案例:
- 混合受众应用程序:同时为成人和儿童服务的应用程序,其年龄在应用程序启动后确定
- 动态隐私控制:根据用户操作或访问内容调整跟踪
- 运行时限制:在初始 SDK 设置后应用广告标识符限制
using UnityEngine;
using Singular;
public class AdvertisingIdentifierManager : MonoBehaviour
{
// Limit advertising identifiers after initialization
public void EnableLimitedMode()
{
SingularSDK.SetLimitAdvertisingIdentifiers(true);
Debug.Log("Advertising identifiers limited");
}
// Example: Mixed audience app with age gate
public void OnKidsModeSwitched(bool isKidsMode)
{
if (isKidsMode)
{
SingularSDK.SetLimitAdvertisingIdentifiers(true);
Debug.Log("Advertising identifiers limited for kids mode");
}
else
{
SingularSDK.SetLimitAdvertisingIdentifiers(false);
Debug.Log("Advertising identifiers unrestricted for adult mode");
}
}
// Example: Content-based restrictions
public void OnViewingChildrensContent()
{
SingularSDK.SetLimitAdvertisingIdentifiers(true);
Debug.Log("Ad identifiers restricted for children's content");
}
// Example: Combined with TrackingUnder13
public void OnAgeVerified(int age)
{
if (age < 13)
{
SingularSDK.TrackingUnder13();
SingularSDK.SetLimitAdvertisingIdentifiers(true);
Debug.Log("Full COPPA restrictions applied");
}
}
}
配置替代方案:如果您在 SDK 启动前就知道隐私要求,也可以在 SDK 初始化期间通过设置 Singular SDK 配置中的limitAdvertisingIdentifiers 属性来限制广告标识符。
配置属性
在 SDK 初始化期间为预先知道隐私要求的应用程序设置广告标识符限制。
using UnityEngine;
using Singular;
public class SDKInitializer : MonoBehaviour
{
void Start()
{
// Get reference to SingularSDK component
var singularSDK = GetComponent<SingularSDK>();
// Limit advertising identifiers at initialization
singularSDK.limitAdvertisingIdentifiers = true;
// Initialize SDK
if (!singularSDK.InitializeOnAwake)
{
SingularSDK.InitializeSingularSDK();
}
}
}
实施最佳实践
完整隐私管理示例
实施全面的隐私控制,尊重用户偏好并遵守法规。
using UnityEngine;
using Singular;
public class ComprehensivePrivacyManager : MonoBehaviour
{
private const string PREF_USER_CONSENT = "privacy_user_consent";
private const string PREF_DATA_SHARING = "privacy_data_sharing";
void Start()
{
// Initialize privacy settings on app start
InitializePrivacySettings();
}
/// <summary>
/// Initialize privacy settings on app startup based on stored preferences
/// </summary>
public void InitializePrivacySettings()
{
bool hasUserConsent = GetUserConsent();
bool allowDataSharing = GetDataSharingPreference();
// Apply stored tracking preference
if (hasUserConsent)
{
SingularSDK.TrackingOptIn();
SingularSDK.ResumeAllTracking();
Debug.Log("Privacy initialized: Tracking enabled with consent");
}
else
{
SingularSDK.StopAllTracking();
Debug.Log("Privacy initialized: Tracking disabled");
}
// Set data sharing preference (inverse logic)
SingularSDK.LimitDataSharing(!allowDataSharing);
Debug.Log($"Privacy initialized: consent={hasUserConsent}, sharing={allowDataSharing}");
}
/// <summary>
/// User accepts tracking via consent dialog
/// </summary>
public void OnUserAcceptedTracking()
{
SaveUserConsent(true);
SingularSDK.TrackingOptIn();
SingularSDK.ResumeAllTracking();
Debug.Log("User accepted tracking");
}
/// <summary>
/// User declines tracking
/// </summary>
public void OnUserDeclinedTracking()
{
SaveUserConsent(false);
SingularSDK.StopAllTracking();
Debug.Log("User declined tracking");
}
/// <summary>
/// User updates data sharing preference
/// </summary>
/// <param name="enabled">True to enable data sharing, false to limit it</param>
public void SetDataSharingEnabled(bool enabled)
{
SaveDataSharingPreference(enabled);
// Note: LimitDataSharing uses inverse logic
// false = data sharing enabled, true = data sharing limited
SingularSDK.LimitDataSharing(!enabled);
Debug.Log($"Data sharing: {(enabled ? "Enabled" : "Limited")}");
}
/// <summary>
/// Check if tracking is currently enabled
/// </summary>
/// <returns>True if tracking is active, false if stopped</returns>
public bool IsTrackingEnabled()
{
return !SingularSDK.IsAllTrackingStopped();
}
/// <summary>
/// Get current privacy status as readable text
/// </summary>
/// <returns>Human-readable tracking status</returns>
public string GetPrivacyStatus()
{
bool isEnabled = !SingularSDK.IsAllTrackingStopped();
bool dataSharingEnabled = GetDataSharingPreference();
return $"Tracking: {(isEnabled ? "Enabled" : "Disabled")}\n" +
$"Data Sharing: {(dataSharingEnabled ? "Enabled" : "Limited")}";
}
// Private helper methods for PlayerPrefs storage
private bool GetUserConsent()
{
return PlayerPrefs.GetInt(PREF_USER_CONSENT, 0) == 1;
}
private void SaveUserConsent(bool consent)
{
PlayerPrefs.SetInt(PREF_USER_CONSENT, consent ? 1 : 0);
PlayerPrefs.Save();
}
private bool GetDataSharingPreference()
{
return PlayerPrefs.GetInt(PREF_DATA_SHARING, 0) == 1;
}
private void SaveDataSharingPreference(bool enabled)
{
PlayerPrefs.SetInt(PREF_DATA_SHARING, enabled ? 1 : 0);
PlayerPrefs.Save();
}
}
最佳实践:
- 持久存储:使用 PlayerPrefs 或安全存储解决方案保存用户首选项
- 尽早初始化:尽可能在 SDK 初始化之前应用隐私设置
-
UI 同步:使用
IsAllTrackingStopped()保持设置 UI 与实际 SDK 状态同步 - 清晰沟通:在应用设置中提供清晰、易用的隐私控制
-
反向逻辑:请记住,
LimitDataSharing(false)意味着启用数据共享,而true则意味着限制数据共享 - 合规文档:保留用户何时以及如何提供或撤销同意的记录