Conformidade com leis de privacidade de dados
Implemente a coleta de dados em conformidade com a privacidade notificando o Singular sobre as escolhas de consentimento dos usuários para GDPR, CCPA e outras regulamentações de privacidade do consumidor.
Quando os usuários consentem ou recusam o compartilhamento de suas informações com terceiros, utilize os métodos de privacidade do Singular para comunicar essa escolha. Isso garante a conformidade com regulamentações como a California Consumer Privacy Act (CCPA) e permite que os parceiros respeitem as preferências de privacidade do usuário.
Saiba mais: Consulte Privacidade do usuário e limitação do compartilhamento de dados para obter informações detalhadas sobre como o Singular processa o consentimento de privacidade.
Limitar o compartilhamento de dados
Controlar o compartilhamento de dados com terceiros
Notifique o Singular sobre se os usuários consentiram em compartilhar seus dados pessoais com parceiros terceirizados usando o método
limitDataSharing
.
Assinatura do método:
public static void limitDataSharing(boolean shouldLimitDataSharing);
Parâmetros:
- false: O usuário optou por participar e consentiu em compartilhar seus dados
- true: O usuário optou por não participar e não consente em compartilhar seus dados
Importante: Embora opcional, este método afeta o compartilhamento de dados de atribuição. Alguns parceiros só compartilham informações completas de atribuição quando são notificados explicitamente de que os usuários optaram por participar.
Exemplos 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"));
}
Como funciona:
O Singular usa essa configuração em postbacks de privacidade do usuário e a repassa para os parceiros que a exigem para conformidade regulatória.
Limitação do compartilhamento de dados por evento
Substituir o compartilhamento de dados em um único evento
Você pode substituir a configuração global
limitDataSharing
para um único evento ou chamada de receita personalizada passando o atributo
Attributes.sngAttrLimitDataSharing
junto com os demais argumentos do evento. Isso é útil quando o usuário atualiza o consentimento de forma simultânea a uma ação e deseja que esse evento específico reflita a nova escolha imediatamente, sem alterar a configuração global do SDK para os eventos subsequentes.
Valores aceitos:
- false: O usuário optou por participar apenas neste evento
- true: O usuário optou por não participar apenas neste evento
Importante:
O atributo deve ser um
Boolean
. Entradas que não sejam booleanas são ignoradas e a requisição recorre à configuração global
limitDataSharing
. Em qualquer caso, o atributo é removido dos argumentos do evento antes do envio da requisição, de modo que nunca aparece no payload do evento.
Exemplos 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);
Como funciona:
Quando um valor booleano válido é fornecido, o SDK remove o atributo dos argumentos do evento e o grava no campo
data_sharing_options.limit_data_sharing
da requisição — substituindo a configuração global
limitDataSharing
apenas para essa requisição. A configuração global e o resultado de
getLimitDataSharing
não são modificados, de modo que os eventos subsequentes que não fornecerem o atributo continuarão a usar a escolha global.
Métodos de conformidade com o GDPR
Gerencie o consentimento de rastreamento do usuário e controle a funcionalidade do SDK para estar em conformidade com o GDPR (Regulamento Geral sobre a Proteção de Dados) e outras regulamentações de privacidade.
Gerenciamento de consentimento de rastreamento
trackingOptIn
Registre o consentimento explícito do usuário para rastreamento enviando um evento de opt-in do GDPR para os servidores do Singular.
Assinatura do método:
Singular.trackingOptIn()
Quando usar:
- Conformidade com o GDPR: Chame quando os usuários consentirem explicitamente o rastreamento em regiões regulamentadas pelo GDPR
- Registro de consentimento: Marca os usuários como tendo fornecido consentimento do GDPR nos sistemas do Singular
- Comportamento padrão: Sem essa chamada, o SDK continua rastreando, mas não registra o consentimento de forma específica
// 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 controle de rastreamento
stopAllTracking
Desative completamente todas as atividades de rastreamento do SDK para o usuário atual neste dispositivo.
Assinatura do método:
Singular.stopAllTracking()
Aviso crítico:
Este método desativa o SDK permanentemente até que
resumeAllTracking()
seja chamado. O estado desativado persiste após reinicializações do app e só pode ser revertido por programação.
Comportamento:
- Efeito imediato: Interrompe todo o rastreamento, o envio de eventos e a coleta de dados instantaneamente
- Estado persistente: Permanece desativado mesmo após o app ser fechado e reaberto
-
Sem reinicialização automática:
É preciso chamar explicitamente
resumeAllTracking()para reativar
// 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
Reative o rastreamento depois que ele foi interrompido com
stopAllTracking()
.
Assinatura do método:
Singular.resumeAllTracking()
Casos de uso:
- Alteração do consentimento: O usuário altera as preferências de privacidade e opta novamente pelo rastreamento
- Configurações de privacidade: O usuário atualiza o consentimento por meio do menu de configurações do app
- Conformidade regional: Reativa o rastreamento quando o usuário muda para regiões não regulamentadas
// 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
Verifique se o rastreamento foi desativado para o usuário atual.
Assinatura do método:
public static boolean isAllTrackingStopped();
Retorna:
-
true:
O rastreamento está atualmente interrompido por
stopAllTracking() - false: O rastreamento está ativo (nunca foi interrompido ou foi retomado)
Retorna
false
se o SDK não tiver sido inicializado, independentemente de qualquer estado de rastreamento anterior. Sempre confirme que
Singular.init()
foi concluído antes de confiar nesse valor e interprete
false
como "não interrompido ou ainda não inicializado", e não como "rastreando ativamente".
// 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"));
}
Proteção da privacidade infantil
trackingUnder13
Notifique o Singular de que o usuário tem menos de 13 anos para estar em conformidade com a COPPA (Lei de Proteção da Privacidade Online de Crianças) e outras regulamentações de privacidade infantil.
Assinatura do método:
Singular.trackingUnder13()
Requisitos de conformidade:
- Conformidade com a COPPA: Necessário para apps que coletam dados de crianças menores de 13 anos nos Estados Unidos
- Conteúdo com restrição de idade: Use quando os usuários se identificarem como menores de 13 anos durante o registro ou a verificação de idade
- Rastreamento restrito: Limita a coleta de dados para estar em conformidade com as leis de proteção da privacidade 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: Chame este método o quanto antes após determinar que o usuário tem menos de 13 anos, idealmente durante a inicialização do app ou imediatamente após a verificação de idade. Isso garante que todo o rastreamento subsequente respeite as regulamentações de privacidade infantil.
setLimitAdvertisingIdentifiers
Restrinja a coleta e o uso de identificadores de publicidade (GAID no Android) após a inicialização do SDK em apps de audiência mista.
Assinatura do método:
public static void setLimitAdvertisingIdentifiers(boolean enabled);
Parâmetros:
-
enabled:
Passe
truepara limitar a coleta do identificador de publicidade;falsepara restaurar a coleta normal.
Não confunda com a variante em tempo de configuração.
O método em tempo de execução
Singular.setLimitAdvertisingIdentifiers(boolean)
exige um argumento booleano, enquanto o método em tempo de configuração
SingularConfig.withLimitAdvertisingIdentifiers()
não recebe argumentos e ativa o limite incondicionalmente. Chamar o método em tempo de execução sem argumentos não compila.
Casos de uso:
- Apps de audiência mista: Apps que atendem tanto adultos quanto crianças, em que a idade é determinada após o lançamento do app
- Controles de privacidade dinâmicos: Ajuste o rastreamento com base nas ações do usuário ou no conteúdo acessado
- Restrições em tempo de execução: Aplique as limitações do identificador de publicidade após a configuração inicial do 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 configuração:
Você também pode limitar os identificadores de publicidade durante a inicialização do SDK usando
SingularConfig.withLimitAdvertisingIdentifiers()
se conhecer os requisitos de privacidade antes do início do SDK.
Método de configuração
Defina as limitações dos identificadores de publicidade durante a inicialização do SDK para apps que conhecem os requisitos de privacidade antecipadamente.
// 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);
Boas práticas de implementação
Exemplo completo de gerenciamento de privacidade
Implemente controles de privacidade abrangentes que respeitem as preferências do usuário e estejam em conformidade com as regulamentações.
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();
}
}
Boas práticas:
- Armazenamento persistente: Salve as preferências do usuário no SharedPreferences ou em armazenamento seguro
- Inicialização antecipada: Aplique as configurações de privacidade antes da inicialização do SDK sempre que possível
-
Sincronização da UI:
Mantenha a UI de configurações sincronizada com o estado real do SDK usando
isAllTrackingStopped() - Comunicação clara: Forneça controles de privacidade claros e acessíveis nas configurações do app
- Verificação de idade: Implemente uma verificação de idade robusta para apps voltados a crianças
-
Controles combinados:
Para usuários menores de 13 anos, aplique tanto
trackingUnder13()quantosetLimitAdvertisingIdentifiers(true)