Cumplimiento de las leyes de privacidad de datos
Implemente la recolección de datos conforme a la privacidad notificando a Singular las elecciones de consentimiento del usuario para GDPR, CCPA y otras regulaciones de privacidad del consumidor.
Cuando los usuarios consientan o se nieguen a compartir su información con terceros, utilice los métodos de privacidad de Singular para comunicar su elección. Esto garantiza el cumplimiento de regulaciones como la California Consumer Privacy Act (CCPA) y permite que los partners respeten las preferencias de privacidad del usuario.
Más información: Consulte Privacidad del usuario y limitación del intercambio de datos para obtener información detallada sobre cómo Singular procesa el consentimiento de privacidad.
Limitar el intercambio de datos
Controlar el intercambio de datos con terceros
Notifique a Singular si los usuarios han consentido en compartir sus datos personales con partners externos utilizando el método
limitDataSharing
.
Firma del método:
public static void limitDataSharing(boolean shouldLimitDataSharing);
Parámetros:
- false: El usuario ha optado por participar y ha consentido en compartir sus datos
- true: El usuario ha optado por no participar y no consiente en compartir sus datos
Importante: Aunque es opcional, este método afecta al intercambio de datos de atribución. Algunos partners solo comparten información de atribución completa cuando se les notifica explícitamente que los usuarios han optado por participar.
Ejemplos de uso
// 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"));
}
Cómo funciona:
Singular utiliza esta configuración en postbacks de privacidad del usuario y la transmite a los partners que la requieren para el cumplimiento normativo.
Limitación del intercambio de datos por evento
Anular el intercambio de datos en un único evento
Puede anular la configuración global de
limitDataSharing
para un único evento o llamada de ingreso personalizado pasando el atributo
Attributes.sngAttrLimitDataSharing
junto con los demás argumentos del evento. Esto es útil cuando un usuario actualiza su consentimiento de manera simultánea a una acción y desea que ese evento específico refleje la nueva elección de inmediato, sin cambiar la configuración global del SDK para los eventos siguientes.
Valores aceptados:
- false: El usuario ha optado por participar solo para este evento
- true: El usuario ha optado por no participar solo para este evento
Importante:
El atributo debe ser un
Boolean
. Las entradas que no sean booleanas se ignoran y la solicitud recurre a la configuración global de
limitDataSharing
. En cualquier caso, el atributo se elimina de los argumentos del evento antes de enviar la solicitud, por lo que nunca aparece en la carga útil del evento.
Ejemplos de uso
// Example 1: Standard event, opt out only for this event
val args = JSONObject()
.put(Attributes.sngAttrLimitDataSharing.toString(), true)
.put("order_id", "12345")
Singular.event("checkout_completed", args.toString())
// Example 2: Custom revenue, opt in only for this event
val attributes = mutableMapOf<String, Any>().apply {
put(Attributes.sngAttrLimitDataSharing.toString(), false)
put("sku", "premium_monthly")
}
Singular.customRevenue("premium_purchase", "USD", 9.99, attributes)
// Example 1: Standard event, opt out only for this event
JSONObject args = new JSONObject();
args.put(Attributes.sngAttrLimitDataSharing.toString(), true);
args.put("order_id", "12345");
Singular.event("checkout_completed", args.toString());
// Example 2: Custom revenue, opt in only for this event
Map<String, Object> attributes = new HashMap<>();
attributes.put(Attributes.sngAttrLimitDataSharing.toString(), false);
attributes.put("sku", "premium_monthly");
Singular.customRevenue("premium_purchase", "USD", 9.99, attributes);
Cómo funciona:
Cuando se proporciona un valor booleano válido, el SDK elimina el atributo de los argumentos del evento y lo escribe en el campo
data_sharing_options.limit_data_sharing
de la solicitud, anulando la configuración global de
limitDataSharing
solo para esa solicitud. La configuración global y el resultado de
getLimitDataSharing
no se modifican, por lo que los eventos posteriores que no proporcionen el atributo seguirán utilizando la elección global.
Métodos de cumplimiento del GDPR
Gestione el consentimiento de seguimiento del usuario y controle la funcionalidad del SDK para cumplir con el GDPR (Reglamento General de Protección de Datos) y otras regulaciones de privacidad.
Gestión del consentimiento de seguimiento
trackingOptIn
Registre el consentimiento explícito del usuario para el seguimiento enviando un evento de opt-in del GDPR a los servidores de Singular.
Firma del método:
Singular.trackingOptIn()
Cuándo utilizarlo:
- Cumplimiento del GDPR: Llamar cuando los usuarios consientan explícitamente al seguimiento en regiones reguladas por el GDPR
- Registro de consentimiento: Marca a los usuarios como proveedores del consentimiento del GDPR en los sistemas de Singular
- Comportamiento por defecto: Sin esta llamada, el SDK continúa con el seguimiento, pero no registra específicamente el consentimiento
// 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");
}
Métodos de control del seguimiento
stopAllTracking
Desactive por completo todas las actividades de seguimiento del SDK para el usuario actual en este dispositivo.
Firma del método:
Singular.stopAllTracking()
Advertencia crítica:
Este método desactiva el SDK de forma permanente hasta que se llame a
resumeAllTracking()
. El estado desactivado persiste tras los reinicios de la app y solo se puede revertir mediante programación.
Comportamiento:
- Efecto inmediato: Detiene todo el seguimiento, el reporte de eventos y la recolección de datos al instante
- Estado persistente: Permanece desactivado incluso después de cerrar y reabrir la app
-
Sin reinicio automático:
Debe llamar explícitamente a
resumeAllTracking()para volver a activarlo
// 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);
}
resumeAllTracking
Vuelva a activar el seguimiento después de detenerlo con
stopAllTracking()
.
Firma del método:
Singular.resumeAllTracking()
Casos de uso:
- Cambio de consentimiento: El usuario cambia sus preferencias de privacidad y vuelve a aceptar el seguimiento
- Ajustes de privacidad: El usuario actualiza el consentimiento desde el menú de configuración de la app
- Cumplimiento regional: Reactivar el seguimiento cuando el usuario se traslada a regiones no reguladas
// 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);
}
isAllTrackingStopped
Compruebe si el seguimiento ha sido desactivado para el usuario actual.
Firma del método:
public static boolean isAllTrackingStopped();
Devuelve:
-
true:
El seguimiento está actualmente detenido mediante
stopAllTracking() - false: El seguimiento está activo (nunca se detuvo o se reanudó)
Devuelve
false
si el SDK no se ha inicializado, independientemente del estado de seguimiento anterior. Confirme siempre que
Singular.init()
se haya completado antes de basarse en este valor, e interprete
false
como "no detenido o aún no inicializado" en lugar de "haciendo seguimiento activamente".
// 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"));
}
Protección de la privacidad infantil
trackingUnder13
Notifique a Singular que el usuario es menor de 13 años para cumplir con la COPPA (Ley de Protección de la Privacidad Infantil en Línea) y otras regulaciones de privacidad infantil.
Firma del método:
Singular.trackingUnder13()
Requisitos de cumplimiento:
- Cumplimiento de la COPPA: Necesario para apps que recopilan datos de niños menores de 13 años en Estados Unidos
- Contenido con restricción de edad: Utilícelo cuando los usuarios se identifiquen como menores de 13 años durante el registro o la verificación de edad
- Seguimiento restringido: Limita la recopilación de datos para cumplir con las leyes de protección de la privacidad infantil
// 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");
}
}
Importante: Llame a este método lo antes posible después de determinar que el usuario es menor de 13 años, idealmente durante la inicialización de la app o inmediatamente después de la verificación de edad. Esto garantiza que todo el seguimiento posterior respete las regulaciones de privacidad infantil.
setLimitAdvertisingIdentifiers
Restrinja la recopilación y el uso de identificadores publicitarios (GAID en Android) después de la inicialización del SDK para apps de audiencia mixta.
Firma del método:
public static void setLimitAdvertisingIdentifiers(boolean enabled);
Parámetros:
-
enabled:
Pase
truepara limitar la recopilación del identificador publicitario;falsepara restaurar la recopilación normal.
No lo confunda con la variante en tiempo de configuración.
El método en tiempo de ejecución
Singular.setLimitAdvertisingIdentifiers(boolean)
requiere un argumento booleano, mientras que el método en tiempo de configuración
SingularConfig.withLimitAdvertisingIdentifiers()
no toma argumentos y activa el límite incondicionalmente. Llamar al método en tiempo de ejecución sin argumentos no compila.
Casos de uso:
- Apps de audiencia mixta: Apps que atienden tanto a adultos como a niños cuando la edad se determina después del lanzamiento
- Controles de privacidad dinámicos: Ajuste el seguimiento según las acciones del usuario o el contenido al que accede
- Restricciones en tiempo de ejecución: Aplica las limitaciones del identificador publicitario después de la configuración inicial del SDK
// Limit advertising identifiers after initialization
Singular.setLimitAdvertisingIdentifiers(true)
// Example: Mixed audience app with age gate
fun onKidsModeSwitched(isKidsMode: Boolean) {
if (isKidsMode) {
Singular.setLimitAdvertisingIdentifiers(true)
Log.d("Privacy", "Advertising identifiers limited for kids mode")
}
}
// Example: Content-based restrictions
fun onViewingChildrensContent() {
Singular.setLimitAdvertisingIdentifiers(true)
Log.d("Privacy", "Ad identifiers restricted for children's content")
}
// Limit advertising identifiers after initialization
Singular.setLimitAdvertisingIdentifiers(true);
// Example: Mixed audience app with age gate
public void onKidsModeSwitched(boolean isKidsMode) {
if (isKidsMode) {
Singular.setLimitAdvertisingIdentifiers(true);
Log.d("Privacy", "Advertising identifiers limited for kids mode");
}
}
// Example: Content-based restrictions
public void onViewingChildrensContent() {
Singular.setLimitAdvertisingIdentifiers(true);
Log.d("Privacy", "Ad identifiers restricted for children's content");
}
Alternativa de configuración:
También puede limitar los identificadores publicitarios durante la inicialización del SDK utilizando
SingularConfig.withLimitAdvertisingIdentifiers()
si conoce los requisitos de privacidad antes del inicio del SDK.
Método de configuración
Establezca las limitaciones de identificadores publicitarios durante la inicialización del SDK para apps que conozcan los requisitos de privacidad de antemano.
// 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);
Mejores prácticas de implementación
Ejemplo completo de gestión de la privacidad
Implemente controles de privacidad integrales que respeten las preferencias del usuario y cumplan con las regulaciones.
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(true)
}
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(true)
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(true);
}
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(true);
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();
}
}
Mejores prácticas:
- Almacenamiento persistente: Guarde las preferencias del usuario en SharedPreferences o almacenamiento seguro
- Inicialización temprana: Aplique los ajustes de privacidad antes de la inicialización del SDK siempre que sea posible
-
Sincronización de la UI:
Mantenga la UI de configuración sincronizada con el estado real del SDK utilizando
isAllTrackingStopped() - Comunicación clara: Proporcione controles de privacidad claros y accesibles en los ajustes de la app
- Verificación de edad: Implemente una verificación de edad robusta para apps dirigidas a niños
-
Controles combinados:
Para usuarios menores de 13 años, aplique tanto
trackingUnder13()comosetLimitAdvertisingIdentifiers(true)