Guia de recuperação de dados do dispositivo
Guia abrangente para recuperar identificadores de dispositivos específicos da plataforma e parâmetros necessários para uma atribuição precisa da API S2S e medição de campanhas.
Identificadores de dispositivos necessários: A Singular requer identificadores de dispositivo específicos em todos os pedidos de API para uma atribuição exacta.
Plataformas móveis:
- Android (Google Play): ID de publicidade do Google (GAID/AIFA) e ID do conjunto de aplicativos (ASID)
- Android (Amazon): Amazon Advertising ID (AMID) para dispositivos Fire
- Android (OEMs chineses): Open Advertising ID (OAID) para dispositivos sem Google Play Services
- Android (Fallback): Android ID (ANDI) apenas quando não existem outros identificadores disponíveis
- iOS: Identificador para Fornecedores (IDFV) e Identificador para Anunciantes (IDFA) quando disponível
Parâmetros do dispositivo: Localidade, marca do dispositivo, modelo do dispositivo e versão de compilação necessários para plataformas móveis
Os exemplos de código abaixo demonstram métodos de recuperação para cada plataforma e tipo de identificador.
Exemplos de aplicações
Implementações de referência
Exemplos de trabalho completos para iOS e Android que demonstram padrões de recuperação de dados do dispositivo.
Identificadores de dispositivos iOS
Os dispositivos iOS requerem IDFV (sempre) e IDFA (quando o utilizador concede permissão de rastreio) mais o estado de autorização ATT para uma atribuição precisa.
Identificadores iOS necessários
Requisitos do identificador:
- IDFV: Necessário em todos os pedidos S2S, independentemente da permissão de rastreamento
- IDFA: Deve ser fornecido se o utilizador der autorização de transparência de rastreio da aplicação
- Estado ATT: Código de estado da autorização exigido em todos os pedidos (0-3)
Guia de implementação
Identificador para anunciantes (IDFA)
O Identificador para Anunciantes (IDFA) permite que os anunciantes acompanhem e atribuam acções do utilizador (cliques em anúncios, instalações de aplicações) a campanhas específicas para uma segmentação e otimização precisas.
A partir do iOS 14.5, os utilizadores devem optar por participar através da estrutura App Tracking Transparency (ATT) antes de as aplicações acederem ao IDFA. Sem o consentimento do utilizador, o IDFA devolve todos os zeros, limitando as capacidades de rastreio.
Identificador para Fornecedores (IDFV)
O Identificador para Fornecedores (IDFV) é um identificador único atribuído pela Apple ao dispositivo, específico do fornecedor/desenvolvedor. Mantém-se consistente em todas as aplicações do mesmo fornecedor no dispositivo, permitindo o seguimento do comportamento entre aplicações sem identificação pessoal.
Passos de implementação:
- Assegurar que o aviso ATT é apresentado e tratado antes de tentar aceder ao IDFA
- Capturar IDFA (se autorizado) e passar para o servidor para pedidos de API
- Capturar IDFV e passar para o servidor para pedidos de API (sempre necessário)
- Incluir o estado de autorização ATT em todos os pedidos
Exemplos de código
Pedido de autorização ATT e recuperação de IDFA/IDFV
#import <AdSupport/AdSupport.h>
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <UIKit/UIKit.h>
- (void)retrieveIdentifiers {
// Request ATT authorization (iOS 14.5+)
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
dispatch_async(dispatch_get_main_queue(), ^{
switch (status) {
case ATTrackingManagerAuthorizationStatusAuthorized: {
// ATT authorized, retrieve IDFA
NSUUID *idfa = [[ASIdentifierManager sharedManager] advertisingIdentifier];
NSLog(@"IDFA: %@", [idfa UUIDString]);
NSLog(@"ATT Status: %ld", (long)status); // Status = 3
break;
}
case ATTrackingManagerAuthorizationStatusDenied:
NSLog(@"ATT Status: Denied (%ld)", (long)status); // Status = 2
break;
case ATTrackingManagerAuthorizationStatusRestricted:
NSLog(@"ATT Status: Restricted (%ld)", (long)status); // Status = 1
break;
case ATTrackingManagerAuthorizationStatusNotDetermined:
NSLog(@"ATT Status: Not Determined (%ld)", (long)status); // Status = 0
break;
default:
NSLog(@"Unknown ATT status.");
break;
}
// Retrieve IDFV (always available)
NSUUID *idfv = [[UIDevice currentDevice] identifierForVendor];
if (idfv != nil) {
NSLog(@"IDFV: %@", [idfv UUIDString]);
} else {
NSLog(@"Unable to retrieve IDFV.");
}
});
}];
}
// Call the method to retrieve identifiers
[self retrieveIdentifiers];
import AdSupport
import AppTrackingTransparency
import UIKit
func retrieveIdentifiers() {
// Request ATT authorization (iOS 14.5+)
ATTrackingManager.requestTrackingAuthorization { status in
DispatchQueue.main.async {
switch status {
case .authorized:
// ATT authorized, retrieve IDFA
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
print("IDFA: \(idfa)")
print("ATT Status: \(status.rawValue)") // Status = 3
case .denied:
print("ATT Status: Denied (\(status.rawValue))") // Status = 2
case .restricted:
print("ATT Status: Restricted (\(status.rawValue))") // Status = 1
case .notDetermined:
print("ATT Status: Not Determined (\(status.rawValue))") // Status = 0
@unknown default:
print("Unknown ATT status.")
}
// Retrieve IDFV (always available)
if let idfv = UIDevice.current.identifierForVendor?.uuidString {
print("IDFV: \(idfv)")
} else {
print("Unable to retrieve IDFV.")
}
}
}
}
// Call the function to retrieve identifiers
retrieveIdentifiers()
Disponibilidade do identificador:
- IDFA: Requer autorização da ATT a partir do iOS 14.5+. Sem autorização, devolve todos os zeros
- IDFV: sempre disponível - incluir em todas as solicitações da API Singular
- Valores de status da ATT: 0=Indeterminado, 1=Restrito, 2=Negado, 3=Autorizado
Identificadores de dispositivos Android (Google Play)
Os dispositivos Android com Google Play Services requerem o App Set ID (ASID) em todos os pedidos, com o Google Advertising ID (GAID/AIFA) quando disponível.
Identificadores obrigatórios do Google Play
Requisitos de identificador:
- ASID: necessário em todos os pedidos S2S para dispositivos Google Play
- AIFA/GAID: Deve ser fornecido quando disponível (não deve ser desativado)
Guia de implementação
Identificador de publicidade do Google (GAID)
O Google Advertising Identifier (GAID), também conhecido como AIFA ou Android Advertising ID (AAID), é um identificador único, redefinível pelo utilizador, atribuído a dispositivos Android, que permite aos anunciantes e programadores acompanhar e atribuir acções do utilizador em aplicações para segmentação e otimização de campanhas, mantendo a privacidade.
Dependências
Adicione a dependência necessária no seu build.gradle:
dependencies {
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
}
Permissões
Se estiver a visar o Android 12/API nível 31+, adicione a permissão em AndroidManifest.xml:
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
Utilização
AdIdUtils.getGoogleAdId(getApplicationContext());
Implementação
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
import com.google.android.gms.ads.identifier.AdvertisingIdClient.Info;
public class AdIdUtils {
public static void getGoogleAdId(Context context) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
try {
Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
String adId = adInfo.getId();
boolean isLimitAdTrackingEnabled = adInfo.isLimitAdTrackingEnabled();
Log.d("GoogleAdID", "Advertising ID: " + adId);
Log.d("GoogleAdID", "Limit Ad Tracking: " + isLimitAdTrackingEnabled);
} catch (Exception e) {
Log.e("GoogleAdID", "Error retrieving GAID", e);
}
}
});
}
}
Dependências
dependencies {
implementation 'com.google.android.gms:play-services-ads-identifier:18.0.1'
}
Permissões
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
Utilização
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
lifecycleScope.launch {
val googleAdId = AdIdUtils.getGoogleAdId(applicationContext)
Log.d("MainActivity", "Retrieved Google Ad ID: $googleAdId")
}
}
}
Implementação
import android.content.Context
import android.util.Log
import com.google.android.gms.ads.identifier.AdvertisingIdClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
object AdIdUtils {
suspend fun getGoogleAdId(context: Context): String? {
return withContext(Dispatchers.IO) {
try {
val adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context)
val adId = adInfo.id
val isLimitAdTrackingEnabled = adInfo.isLimitAdTrackingEnabled
Log.d("GoogleAdID", "Advertising ID: $adId")
Log.d("GoogleAdID", "Limit Ad Tracking: $isLimitAdTrackingEnabled")
adId
} catch (e: Exception) {
Log.e("GoogleAdID", "Error retrieving GAID", e)
null
}
}
}
}
ID do conjunto de aplicações (ASID)
O ID do conjunto de aplicações do Android permite o rastreio de aplicações cruzadas com privacidade para o mesmo programador. Útil para análise e prevenção de fraudes, mas não pode ser utilizado para publicidade personalizada.
Dependências
dependencies {
implementation 'com.google.android.gms:play-services-appset:16.1.0'
}
Utilização
AppSetIdUtils.getAppSetId(getApplicationContext());
Implementação
import android.content.Context;
import android.util.Log;
import com.google.android.gms.appset.AppSet;
import com.google.android.gms.appset.AppSetIdClient;
import com.google.android.gms.appset.AppSetIdInfo;
import com.google.android.gms.tasks.Task;
public class AppSetIdUtils {
public static void getAppSetId(Context context) {
AppSetIdClient client = AppSet.getClient(context);
Task task = client.getAppSetIdInfo();
task.addOnSuccessListener(info - {
String appSetId = info.getId();
int scope = info.getScope();
Log.d("AppSetID", "App Set ID: " + appSetId);
Log.d("AppSetID", "Scope: " + (scope == AppSetIdInfo.SCOPE_DEVELOPER ? "Developer" : "App"));
}).addOnFailureListener(e - {
Log.e("AppSetID", "Failed to retrieve App Set ID", e);
});
}
}
Dependências
dependencies {
implementation 'com.google.android.gms:play-services-appset:16.1.0'
}
Utilização
AppSetIdUtils.getAppSetId(applicationContext)
Implementação
import android.content.Context
import android.util.Log
import com.google.android.gms.appset.AppSet
import com.google.android.gms.appset.AppSetIdClient
import com.google.android.gms.appset.AppSetIdInfo
object AppSetIdUtils {
fun getAppSetId(context: Context) {
val client: AppSetIdClient = AppSet.getClient(context)
val task = client.appSetIdInfo
task.addOnSuccessListener { info -
val appSetId: String = info.id
val scope: Int = info.scope
Log.d("AppSetID", "App Set ID: $appSetId")
Log.d("AppSetID", "Scope: ${if (scope == AppSetIdInfo.SCOPE_DEVELOPER) "Developer" else "App"}")
}.addOnFailureListener { exception -
Log.e("AppSetID", "Failed to retrieve App Set ID", exception)
}
}
}
Identificadores de dispositivos Android (não-Google Play)
Os dispositivos Android sem Google Play Services requerem identificadores alternativos com base no fabricante do dispositivo e no método de distribuição.
Identificador de dispositivo da Amazon
AMID: O Amazon Advertising ID deve ser fornecido para dispositivos Amazon Fire sem o Google Play Services.
ID da Amazon (AMID)
O Amazon Advertising Identifierpermite o rastreio de publicidade redefinível pelo utilizador em dispositivos Amazon Fire sem o Google Play Services, mantendo a privacidade do utilizador e permitindo a atribuição.
Requisitos:
- Funciona em dispositivos Amazon Fire com Fire OS 5.1+
- Respeita a preferência do utilizador de Limitar a localização de anúncios
- Pode não estar disponível em dispositivos não Fire OS
Utilização
AdvertisingIdHelper.getAmazonAdvertisingId(getContentResolver());
Implementação
import android.content.ContentResolver;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.util.Log;
public class AdvertisingIdHelper {
public static void getAmazonAdvertisingId(ContentResolver contentResolver) {
String advertisingID = "";
boolean limitAdTracking = false;
try {
limitAdTracking = Settings.Secure.getInt(contentResolver, "limit_ad_tracking") != 0;
advertisingID = Settings.Secure.getString(contentResolver, "advertising_id");
Log.d("AdvertisingID", "Amazon Advertising ID: " + advertisingID);
Log.d("LimitAdTracking", "Limit Ad Tracking: " + limitAdTracking);
} catch (SettingNotFoundException e) {
Log.e("AdvertisingID", "Advertising ID not supported on this device", e);
}
}
}
Utilização
AdvertisingIdHelper.getAmazonAdvertisingId(contentResolver)
Implementação
import android.content.ContentResolver
import android.provider.Settings
import android.util.Log
object AdvertisingIdHelper {
fun getAmazonAdvertisingId(contentResolver: ContentResolver) {
try {
val limitAdTracking = Settings.Secure.getInt(contentResolver, "limit_ad_tracking") != 0
val advertisingID = Settings.Secure.getString(contentResolver, "advertising_id")
Log.d("AdvertisingID", "Amazon Advertising ID: $advertisingID")
Log.d("LimitAdTracking", "Limit Ad Tracking: $limitAdTracking")
} catch (e: Settings.SettingNotFoundException) {
Log.e("AdvertisingID", "Advertising ID not supported on this device", e)
}
}
}
Identificador OEM chinês
OAID: O Identificador de publicidade aberta deve ser fornecido para dispositivos fabricados na China sem o Google Play Services.
Identificador de publicidade aberta (OAID)
O Open Advertising Identifier (OAID) é um identificador único e anónimo para publicidade em dispositivos Android fabricados na China. Introduzido pela Mobile Security Alliance (MSA) como alternativa ao GAID para dispositivos onde o Google Play Services não está disponível.
Dispositivos suportados: Huawei, Xiaomi, OPPO, Vivo e outros dispositivos Android de fabrico chinês
Acesso via MSA SDKou Huawei Mobile Services (HMS).
Dependências
dependencies {
implementation 'com.bun.msa.sdk:msa:1.0.26'
}
Implementação
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import com.bun.msa.sdk.DeviceId;
import com.bun.msa.sdk.DeviceIdSupplier;
import com.bun.msa.sdk.IIdentifierListener;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "OAIDExample";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getOAID();
}
private void getOAID() {
try {
DeviceId deviceId = new DeviceId(this);
deviceId.getDeviceIds(new IIdentifierListener() {
@Override
public void onSupport(boolean isSupport, DeviceIdSupplier supplier) {
if (isSupport && supplier != null) {
String oaid = supplier.getOAID();
Log.d(TAG, "OAID: " + oaid);
} else {
Log.e(TAG, "OAID not supported on this device");
}
}
});
} catch (Exception e) {
Log.e(TAG, "Error retrieving OAID", e);
}
}
}
Dependências
dependencies {
implementation 'com.bun.msa.sdk:msa:1.0.26'
}
Implementação
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.bun.msa.sdk.DeviceId
import com.bun.msa.sdk.DeviceIdSupplier
import com.bun.msa.sdk.IIdentifierListener
class MainActivity : AppCompatActivity() {
companion object {
private const val TAG = "OAIDExample"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getOAID()
}
private fun getOAID() {
try {
val deviceId = DeviceId(this)
deviceId.getDeviceIds(object : IIdentifierListener {
override fun onSupport(isSupport: Boolean, supplier: DeviceIdSupplier?) {
if (isSupport && supplier != null) {
val oaid = supplier.oAID
Log.d(TAG, "OAID: $oaid")
} else {
Log.e(TAG, "OAID not supported on this device")
}
}
})
} catch (e: Exception) {
Log.e(TAG, "Error retrieving OAID", e)
}
}
}
Recusa de ID Android
Restrições ANDI: O ID Android só pode ser fornecido se não existirem outros identificadores disponíveis E se a aplicação não for distribuída através da Google Play Store. Proibido para aplicações Google Play.
ID do Android (ANDI)
A partir do Android 8.0 (Oreo), com escopo por aplicativo e por usuário - aplicativos diferentes recebem IDs Android diferentes, a menos que compartilhem a mesma chave de assinatura.
Persistência: Mantém-se constante, exceto se o dispositivo for reposto de fábrica ou se a aplicação for desinstalada/reinstalada após uma atualização OTA.
import android.provider.Settings;
import android.content.Context;
String androidId = Settings.Secure.getString(
context.getContentResolver(),
Settings.Secure.ANDROID_ID
);
import android.provider.Settings
val androidId: String = Settings.Secure.getString(
contentResolver,
Settings.Secure.ANDROID_ID
)
Identificadores Web e multiplataforma
As aplicações Web e as implementações multiplataforma requerem um SDID (Singular Device ID) para um acompanhamento preciso da atribuição.
Identificador da Web necessário
SDID: ID de Dispositivo Singular exigido em todos os pedidos S2S para plataformas Web, PC, Consola e CTV.
ID de Dispositivo Singular Web SDK
O SDID (Singular Device ID) fornece rastreamento consistente entre sessões para aplicativos da Web e plataformas não móveis.
Pré-requisitos: o Singular Web SDK deve ser implementado e inicializado antes de recuperar o SDID.
Uso
// Retrieve SDID after Singular SDK initialization
const sdid = window.singularSdk.getSingularDeviceId();
console.log("Singular Device ID:", sdid);
Nota de implementação: Chame getSingularDeviceId()somente depois que o Singular SDK for inicializado com sucesso - tentar recuperar antes da inicialização retorna nulo.
Parâmetros do dispositivo móvel
Os parâmetros necessários do dispositivo fornecem contexto essencial para atribuição e análise em plataformas móveis.
Parâmetros necessários
Plataformas móveis: Localidade, Marca do Dispositivo, Modelo do Dispositivo e Construção necessários em todas as solicitações S2S para iOS e Android.
Recuperação de parâmetros
Recolha de informações de localidade, fabricante, modelo e construção para obter um perfil completo do dispositivo.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <sys/sysctl.h>
// Retrieve Locale
NSString *retrieveLocale() {
NSString *locale = [[NSLocale currentLocale] localeIdentifier];
NSLog(@"Locale: %@", locale);
return locale;
}
// Retrieve Manufacturer (always Apple for iOS)
NSString *retrieveManufacturer() {
return @"Apple";
}
// Retrieve Device Model
NSString *deviceModel() {
size_t bufferSize = 64;
char model[bufferSize];
int status = sysctlbyname("hw.machine", model, &bufferSize, NULL, 0);
if (status == 0) {
NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
NSLog(@"Device Model: %@", deviceModel);
return deviceModel;
} else {
NSLog(@"Unable to retrieve device model.");
return nil;
}
}
// Retrieve Build Version
NSString *buildVersion() {
size_t bufferSize = 64;
char build[bufferSize];
int status = sysctlbyname("kern.osversion", build, &bufferSize, NULL, 0);
if (status == 0) {
NSString *buildVersion = [NSString stringWithCString:build encoding:NSUTF8StringEncoding];
NSLog(@"Build Version: %@", buildVersion);
return buildVersion;
} else {
NSLog(@"Unable to retrieve build version.");
return nil;
}
}
import Foundation
import UIKit
// Retrieve Locale
func retrieveLocale() - String {
let locale = Locale.current.identifier
print("Locale: \(locale)")
return locale
}
// Retrieve Manufacturer (always Apple for iOS)
func retrieveManufacturer() - String {
return "Apple"
}
// Retrieve Device Model
func deviceModel() - String? {
var systemInfo = utsname()
uname(&systemInfo)
let machineMirror = Mirror(reflecting: systemInfo.machine)
let identifier = machineMirror.children.reduce("") { identifier, element in
guard let value = element.value as? Int8, value != 0 else { return identifier }
return identifier + String(UnicodeScalar(UInt8(value)))
}
print("Device Model: \(identifier)")
return identifier
}
// Retrieve Build Version
func buildVersion() - String? {
var size: Int = 0
sysctlbyname("kern.osversion", nil, &size, nil, 0)
var build = [CChar](repeating: 0, count: size)
sysctlbyname("kern.osversion", &build, &size, nil, 0)
let buildVersion = String(cString: build)
print("Build Version: \(buildVersion)")
return buildVersion
}
import android.os.Build;
import java.util.Locale;
// Locale (lc parameter)
String locale = Locale.getDefault().toString();
// Device Make (ma parameter)
String deviceMake = Build.MANUFACTURER;
// Device Model (mo parameter)
String deviceModel = Build.MODEL;
// Build (bd parameter)
String build = "Build/" + Build.ID;
import android.os.Build
import java.util.Locale
// Locale (lc parameter)
val locale: String = Locale.getDefault().toString()
// Device Make (ma parameter)
val deviceMake: String = Build.MANUFACTURER
// Device Model (mo parameter)
val deviceModel: String = Build.MODEL
// Build (bd parameter)
val build: String = "Build/" + Build.ID
Mapeamento de parâmetros:
- Localidade (lc): Código de idioma e região (por exemplo, en_US, zh_CN)
- Marca (ma): Fabricante do dispositivo (Apple, Samsung, Xiaomi)
- Modelo (mo): Modelo específico do dispositivo (iPhone14,2, SM-G991B)
- Compilação (bd): Versão de compilação do SO prefixada com "Build/"