Implementar a API Topics no Android

Configuração

Para implementar a API Topics, primeiro configure seu ambiente de desenvolvimento. Para isso, siga estas etapas:

  1. Use o SDK do Sandbox de privacidade do Android mais recente para ter a versão mais atualizada das APIs que preservam a privacidade.

  2. Adicione o seguinte ao manifesto:

    • Permissão:inclua a permissão ACCESS_ADSERVICES_TOPICS para permitir que seu app acesse a API Topics:

      <uses-permission android:name="android.permission.ACCESS_ADSERVICES_TOPICS" />
      
    • Configuração de serviços de publicidade:faça referência a um arquivo de configuração de serviços de publicidade no elemento <application> do manifesto.

      <property android:name="android.adservices.AD_SERVICES_CONFIG"
      android:resource="@xml/ad_services_config" />
      

      Especifique o recurso XML dos serviços de publicidade referenciados no manifesto, como res/xml/ad_services_config.xml. Use o atributo allowAllToAccess para conceder acesso a todos os SDKs, ou o atributo allowSdksToAccess para conceder acesso a SDKs individuais. Saiba mais sobre as permissões dos serviços de anúncios e o controle de acesso do SDK.

      <ad-services-config>
          <topics allowAllToAccess="true"/>
      </ad-services-config>
      
  3. Registre sua adtech no Sandbox de privacidade para chamar a API Topics no seu SDK. Para testar localmente, desative a verificação de inscrição no Topics com os seguintes comandos:

    adb shell setprop debug.adservices.disable_topics_enrollment_check true
    
  4. Ative o acesso à API Topics. Por padrão, a API Topics fica desativada. É necessário ativar usando comandos ADB:

    adb shell device_config put adservices ppapi_app_signature_allow_list \"\*\"
    adb shell setprop debug.adservices.disable_topics_enrollment_check true
  5. Comece sua implementação copiando a versão Java ou Kotlin (links em inglês) do app de exemplo para se familiarizar com a extração de temas em um dispositivo.

Solicitar um conjunto de temas

A principal funcionalidade da API Topics fica no método getTopics() dentro do objeto TopicsManager, como mostrado neste exemplo:

Kotlin

fun getTopics(
        getTopicsRequest: GetTopicsRequest,
        executor: Executor,
        callback: OutcomeReceiver<GetTopicsResponse, Exception>
    ) { }

Java

public void getTopics (@NonNull GetTopicsRequest getTopicsRequest,
    @NonNull Executor executor,
    @NonNull OutcomeReceiver<GetTopicsResponse, Exception> callback)

Para usar esse método, inicialize o objeto TopicsManager e os parâmetros necessários para receber dados de temas. A GetTopicsRequest transmite as informações necessárias para extrair os dados da API Topics, incluindo uma sinalização para indicar se o autor da chamada vai atuar como um observador ou não. Quando não atuar como observador, a chamada getTopics vai retornar um tema da época anterior, mas não vai influenciar os dados do tema para a próxima época. O callback OutcomeReceiver processa o resultado de forma assíncrona. Exemplo:

Kotlin

private fun topicGetter() {
    val mContext = baseContext
    val mTopicsManager = mContext.getSystemService(TopicsManager::class.java)
    val mExecutor: Executor = Executors.newCachedThreadPool()
    val shouldRecordObservation = false
    val mTopicsRequestBuilder: GetTopicsRequest.Builder = GetTopicsRequest.Builder()
    mTopicsRequestBuilder.setAdsSdkName(baseContext.packageName)
    mTopicsRequestBuilder.setShouldRecordObservation(shouldRecordObservation)
    mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor,
        mCallback as OutcomeReceiver<GetTopicsResponse, Exception>)
}
private var mCallback: OutcomeReceiver<GetTopicsResponse, java.lang.Exception> =
object : OutcomeReceiver<GetTopicsResponse, java.lang.Exception> {
    override fun onResult(result: GetTopicsResponse) {
        // handle successful result
        val topicsResult = result.topics
        for (i in topicsResult.indices) {
            Log.i("Topic", topicsResult[i].getTopicId().toString())
        }
        if (topicsResult.size == 0) {
            Log.i("Topic", "Returned Empty")
        }
    }
    override fun onError(error: java.lang.Exception) {
        // handle error
        Log.i("Topic", "Error, did not return successfully")
    }
}

Java

public void TopicGetter() {
    @NonNull Context mContext = getBaseContext();
    TopicsManager mTopicsManager = mContext.getSystemService(TopicsManager.class);
    Executor mExecutor = Executors.newCachedThreadPool();
    boolean shouldRecordObservation = false;
    GetTopicsRequest.Builder mTopicsRequestBuilder = new GetTopicsRequest.Builder();
    mTopicsRequestBuilder.setAdsSdkName(getBaseContext().getPackageName());
    mTopicsRequestBuilder.setShouldRecordObservation(shouldRecordObservation);
    mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor, mCallback);
}
OutcomeReceiver mCallback = new OutcomeReceiver<GetTopicsResponse, Exception>() {
    @Override
    public void onResult(@NonNull GetTopicsResponse result) {
        //Handle Successful Result
        List<Topic> topicsResult = result.getTopics();
        for (int i = 0; i < topicsResult.size(); i++) {
            Log.i("Topic", topicsResult.get(i).getTopicId().toString());
        }
        if (topicsResult.size() == 0) {
            Log.i("Topic", "Returned Empty");
        }
    }
    @Override
    public void onError(@NonNull Exception error) {
        // Handle error
        Log.i("Topic", "Experienced an error, and did not return successfully");
    }
};

Quando a configuração estiver pronta, você poderá fazer uma chamada para receber um GetTopicsResponse como resultado do método getTopics():

Kotlin

mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor,
        mCallback as OutcomeReceiver<GetTopicsResponse, java.lang.Exception>)

Java

mTopicsManager.getTopics(mTopicsRequestBuilder.build(), mExecutor, mCallback);

Essa invocação vai fornecer uma lista de objetos de temas que contêm valores de ID correspondentes aos tópicos na taxonomia de código aberto relevantes ao usuário ou a um erro pertinente. Os temas vão ser parecidos com este exemplo:

/Internet & Telecom/Text & Instant Messaging

Consulte a taxonomia (link em inglês) para uma lista de possíveis temas que podem ser retornados. A taxonomia é de código aberto, e você pode registrar as mudanças sugeridas usando o botão de feedback na parte de cima da página.

Testar

A API Topics fornece temas relevantes e atualizados com base no uso do app. Essa versão antecipada oferece uma prévia dos comportamentos da API, e vamos melhorar a qualidade dos temas em versões futuras.

Para ter a experiência mais completa, recomendamos um ambiente de teste com vários apps em que você chame getTopics() para ver como os temas são selecionados. O repositório do SDK Runtime e de APIs para preservação de privacidade (em inglês) no GitHub contém um conjunto de projetos individuais do Android Studio para ajudar você a começar, incluindo exemplos que demonstram como inicializar e chamar a API Topics.

O cálculo dos temas é realizado no final de uma época. Por padrão, cada época tem sete dias de duração, mas você pode modificar esse intervalo para extrair um resultado. Este comando do shell do Android Debug Bridge encurta a duração da época para 5 minutos:

adb shell device_config put adservices topics_epoch_job_period_ms 300000

Você pode confirmar o valor de topics_epoch_job_period_ms com get:

adb shell device_config get adservices topics_epoch_job_period_ms

Para acionar manualmente o cálculo da época, execute este comando:

adb shell cmd jobscheduler run -f com.google.android.adservices.api 2

Além de usar o app de exemplo, você pode usar o Colab para testar diferentes combinações de informações do app com o classificador de temas. Use o Colab para conferir os tipos de resultados que seu app provavelmente terá ao chamar getTopics.

Detalhes de criptografia

Com a introdução da criptografia, as chamadas para GetTopics() agora vão gerar uma resposta com uma lista de objetos EncryptedTopic. A descriptografia desses resultados vai gerar um objeto com o mesmo formato JSON do objeto Topic anterior.

A API Topics é compatível com a implementação única de HPKE (criptografia de chave pública híbrida). Esperamos que o usuário inscrito hospede uma chave pública de 32 bits no endpoint público do URL de criptografia fornecido durante a inscrição. Essas chaves precisam ser codificadas em Base64.

Os objetos EncryptedTopic têm três campos. A lista de tópicos retornados pode ser obtida usando a chave privada correspondente à chave pública.

Para fins de desenvolvimento, teste a criptografia da API Topics desativando a verificação de inscrição. Isso forçaria a API a usar a chave pública de teste para criptografar suas respostas. É possível descriptografar os tópicos criptografados usando a chave privada correspondente.

Limitações

Para ver uma lista de recursos em desenvolvimento para a API Topics, consulte as notas da versão.

Informar bugs e problemas

Seu feedback é uma parte crucial do Sandbox de privacidade no Android. Avise nossa equipe sobre problemas encontrados ou ideias para melhorar esse recurso.

Próximas etapas

Saiba como usuários e desenvolvedores podem gerenciar e personalizar a API Topics de acordo com as preferências e necessidades do usuário.
Entenda como o Topics funciona no Android e saiba mais sobre as principais etapas do fluxo da API.

Consulte também

Confira nossos recursos para entender melhor a API Topics no Android.