Este guia para desenvolvedores descreve como implementar o Google Tag Manager em um aplicativo para dispositivos móveis.
Introdução
O Google Tag Manager permite que os desenvolvedores mudem os valores de configuração nos aplicativos para dispositivos móveis usando a interface do Google Tag Manager sem precisar recriar e reenviar os binários de aplicativos aos mercados de aplicativos.
Isso é útil para gerenciar valores ou flags de configuração no aplicativo que você pode precisar mudar no futuro, incluindo:
- Várias configurações de interface e strings de exibição
- Tamanhos, locais ou tipos de anúncios veiculados no aplicativo
- Configurações de jogos
Os valores de configuração também podem ser avaliados no tempo de execução usando regras, permitindo configurações dinâmicas, como:
- Usar o tamanho da tela para determinar o tamanho do banner de anúncio
- Usar o idioma e o local para configurar elementos da interface
O Google Tag Manager também permite a implementação dinâmica de tags e pixels de acompanhamento em aplicativos. Os desenvolvedores podem enviar eventos importantes para uma camada de dados e decidir mais tarde quais tags ou pixels de acompanhamento precisam ser disparados. O Tag Manager oferece suporte às seguintes tags:
- Google Mobile App Analytics
- Tag de chamada de função personalizada
Antes de começar
Antes de usar este guia de introdução, você vai precisar do seguinte:
- Uma conta do Google Tag Manager
- Um novo contêiner do Tag Manager e uma macro de coleta de valores
- Um aplicativo para dispositivos móveis Android em que implementar o Google Tag Manager
- O SDK de serviços do Google Analytics, que contém a biblioteca do Tag Manager.
Se você não conhece o Google Tag Manager, recomendamos que você saiba mais sobre contêineres, macros e regras (Central de Ajuda) antes de continuar este guia.
Primeiros passos
Esta seção orienta os desenvolvedores em um fluxo de trabalho típico do Tag Manager:
- Adicionar o SDK do Google Tag Manager ao seu projeto
- Definir valores de contêiner padrão
- Abrir o contêiner
- Receber valores de configuração do contêiner
- Enviar eventos para a camada de dados
- Visualizar e publicar o contêiner
1. Adicionar o SDK do Google Tag Manager ao seu projeto
Antes de usar o SDK do Google Tag Manager, você precisa extrair o pacote do SDK e adicionar a biblioteca ao caminho de build do seu projeto, além de adicionar permissões ao arquivo AndroidManifest.xml.
Primeiro, adicione a biblioteca do Google Tag Manager à pasta /libs do seu projeto.
Em seguida, atualize o arquivo AndroidManifest.xml para usar as seguintes permissões:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
2. Adicionar um arquivo de contêiner padrão ao seu projeto
O Google Tag Manager usa um contêiner padrão na primeira execução do aplicativo. O contêiner padrão será usado até que o app possa recuperar um novo contêiner pela rede.
Para fazer o download e adicionar um binário de contêiner padrão ao aplicativo, siga estas etapas:
- Faça login na interface da Web do Google Tag Manager.
- Selecione a versão do contêiner que você quer baixar.
- Clique no botão Fazer download para recuperar o binário do contêiner.
- Adicione o arquivo binário ao
seguinte caminho:
<project-root>/assets/tagmanager/
O nome de arquivo padrão precisa ser o ID do contêiner (por exemplo GTM-1234). Depois de
baixar o arquivo binário, remova o sufixo da versão do nome do arquivo
para garantir que você siga a convenção de nomenclatura correta.
Embora o uso do arquivo binário seja recomendado, se o contêiner não contiver regras ou tags,
você poderá usar um arquivo JSON. O arquivo precisa estar em uma nova /assets/tagmanager
pasta do seu Projeto do Android e seguir esta convenção de nomenclatura:
<Container_ID>.json. Por exemplo, se o ID do contêiner
for GTM-1234, adicione os valores do contêiner padrão a
/assets/tagmanager/GTM-1234.json.
3. Abrir um contêiner
Antes de recuperar valores de um contêiner, o aplicativo precisa abrir o contêiner. A abertura de um contêiner o carrega do disco (se disponível) ou o solicita da rede (se necessário).
A maneira mais fácil de abrir um contêiner no Android é usando ContainerOpener.openContainer(..., Notifier notifier), como no exemplo a seguir:
import com.google.tagmanager.Container; import com.google.tagmanager.ContainerOpener; import com.google.tagmanager.ContainerOpener.OpenType; import com.google.tagmanager.TagManager; import android.app.Activity; import android.os.Bundle; public class RacingGame { // Add your public container ID. private static final String CONTAINER_ID = "GTM-YYYY"; volatile private Container mContainer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TagManager mTagManager = TagManager.getInstance(this); // The container is returned to containerFuture when available. ContainerOpener.openContainer( mTagManager, // TagManager instance. CONTAINER_ID, // Tag Manager Container ID. OpenType.PREFER_NON_DEFAULT, // Prefer not to get the default container, but stale is OK. null, // Time to wait for saved container to load (ms). Default is 2000ms. new ContainerOpener.Notifier() { // Called when container loads. @Override public void containerAvailable(Container container) { // Handle assignment in callback to avoid blocking main thread. mContainer = container; } } ); // Rest of your onCreate code. } }
Neste exemplo, ContainerOpener.openContainer(..., Notifier notifier) é usado para solicitar um contêiner salvo do armazenamento local. Ao processar a atribuição de mContainer no callback containerAvailable, garantimos que a linha de execução principal não seja bloqueada. Se o contêiner salvo for mais antigo que 12 horas, a chamada também vai programar uma solicitação para recuperar de forma assíncrona um novo contêiner pela rede.
Esta implementação de amostra representa a maneira mais simples de abrir e recuperar valores de um contêiner usando a classe de conveniência ContainerOpener.
Para mais opções de implementação avançadas, consulte Configuração avançada.
4. Receber valores de configuração do contêiner
Depois que o contêiner estiver aberto, os valores de configuração poderão ser recuperados usando
os get<type>Value() métodos:
// Retrieving a configuration value from a Tag Manager Container. // Get the configuration value by key. String title = mContainer.getStringValue("title_string");
As solicitações feitas com uma chave inexistente vão retornar um valor padrão adequado ao tipo solicitado:
// Empty keys will return a default value depending on the type requested. // Key does not exist. An empty string is returned. string subtitle = container.getStringValue("Non-existent-key"); subtitle.equals(""); // Evaluates to true.
5. Enviar valores para a camada de dados
A camada de dados é um mapa que permite que informações de tempo de execução sobre seu app, como eventos de toque ou visualizações de tela, fiquem disponíveis para macros e tags do Tag Manager em um contêiner.
Por exemplo, ao enviar informações sobre visualizações de tela para o mapa da camada de dados, você pode configurar tags na interface da Web do Tag Manager para disparar pixels de conversão e chamadas de acompanhamento em resposta a essas visualizações de tela sem precisar codificá-las no app.
Os eventos são enviados para a camada de dados usando push() e o
DataLayer.mapOf() método auxiliar:
// // MainActivity.java // Pushing an openScreen event with a screen name into the data layer. // import com.google.tagmanager.TagManager; import com.google.tagmanager.DataLayer; import android.app.Activity; import android.os.Bundle; public MainActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } // This screen becomes visible when Activity.onStart() is called. public void onStart() { super.onStart(); // The container should have already been opened, otherwise events pushed to // the DataLayer will not fire tags in that container. DataLayer dataLayer = TagManager.getInstance(this).getDataLayer(); dataLayer.push(DataLayer.mapOf("event", "openScreen", // The event type. This value should be used consistently for similar event types. "screenName", // Writes a key "screenName" to the dataLayer map. "Home Screen") // Writes a value "Home Screen" for the "screenName" key. ); } // Rest of the Activity implementation }
Na interface da Web, agora é possível criar tags (como tags do Google Analytics) para disparar para cada visualização de tela criando esta regra: é igual a "openScreen". Para transmitir o nome da tela para uma dessas tags, crie uma macro de camada de dados que faça referência à chave "screenName" na camada de dados. Você também pode criar uma tag (como um pixel de conversão do Google Ads) para disparar apenas para visualizações de tela específicas, criando uma regra em que é igual a "openScreen" && é igual a "ConfirmationScreen".
6. Visualizar e publicar um contêiner
Os valores de macro sempre correspondem à versão publicada atual. Antes de publicar a versão mais recente de um contêiner, você pode visualizar o contêiner de rascunho.
Para visualizar um contêiner, gere um URL de visualização na interface da Web do Google Tag Manager. Para isso, escolha a versão do contêiner desejada e selecione Preview. Salve esse URL de visualização, porque você vai precisar dele nas etapas posteriores.
Em seguida, adicione a seguinte atividade ao arquivo AndroidManifest.xml do aplicativo:
<!-- Google Tag Manager Preview Activity --> <activity android:name="com.google.tagmanager.PreviewActivity" android:label="@string/app_name" android:noHistory="true" > <!-- Optional, removes the PreviewActivity from activity stack. --> <intent-filter> <data android:scheme="tagmanager.c.application_package_name" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE"/> </intent-filter> </activity>
Abra o link em um emulador ou dispositivo físico para visualizar o contêiner de rascunho no app.
Quando estiver tudo pronto para disponibilizar os valores de configuração de rascunho para o aplicativo, publique o contêiner.
Configuração avançada
O Google Tag Manager para dispositivos móveis tem várias opções de configuração avançadas que permitem selecionar valores com base em condições de tempo de execução usando regras, atualizar manualmente o contêiner e receber outras opções para abrir contêineres. As seções a seguir descrevem várias das configurações avançadas mais comuns.
Opções avançadas para abrir contêineres
O SDK do Google Tag Manager oferece vários métodos para abrir contêineres que podem oferecer mais controle sobre o processo de carregamento:
TagManager.openContainer()
TagManager.openContainer() é a API de nível mais baixo e mais flexível para abrir um contêiner. Ela retorna imediatamente com um contêiner padrão e também carrega de forma assíncrona um contêiner do disco ou da rede se nenhum contêiner salvo existir ou se o contêiner salvo não for novo (mais de 12 horas).
mContainer = tagManager.openContainer(CONTAINER_ID, new Container.Callback() { // Called when a refresh is about to begin for the given refresh type. @Override public void containerRefreshBegin(Container container, RefreshType refreshType) { // Notify UI that the Container refresh is beginning. } // Called when a successful refresh occurred for the given refresh type. @Override public void containerRefreshSuccess(Container container, RefreshType refreshType]) { // Notify UI that Container is ready. } // Called when a refresh failed for the given refresh type. @Override public void containerRefreshFailure(Container container, RefreshType refreshType, RefreshFailure refreshFailure) { // Notify UI that the Container refresh has failed. }
Durante todo o processo de carregamento, TagManager.openContainer() emite vários callbacks de ciclo de vida para que o código possa descobrir quando a solicitação de carregamento começa, se e por que ela falha ou é bem-sucedida e se o contêiner foi carregado do disco ou da rede.
A menos que seja aceitável que o aplicativo use os valores padrão, você precisará usar esses callbacks para saber quando um contêiner salvo ou de rede foi carregado. Não será possível carregar um contêiner salvo ou de rede se esta for a primeira vez que o app é executado e não houver conexão de rede.
TagManager.openContainer() transmite os seguintes valores enum como argumentos para esses callbacks:
RefreshType
| Valor | Descrição |
|---|---|
Container.Callback.SAVED
|
A solicitação de atualização está carregando um contêiner salvo localmente. |
Container.Callback.NETWORK
|
A solicitação de atualização está carregando um contêiner pela rede. |
RefreshFailure
| Valor | Descrição |
|---|---|
Container.Callback.NO_SAVED_CONTAINER
|
Não há contêiner salvo disponível. |
Container.Callback.IO_ERROR
|
Um erro de E/S impediu a atualização do contêiner. |
Container.Callback.NO_NETWORK
|
Não há conexão de rede disponível. |
Container.Callback.NETWORK_ERROR
|
Ocorreu um erro de rede. |
Container.Callback.SERVER_ERROR
|
Ocorreu um erro no servidor. |
Container.Callback.UNKNOWN_ERROR
|
Ocorreu um erro que não pode ser categorizado. |
Métodos para abrir contêineres não padrão e novos
ContainerOpener envolve TagManager.openContainer()
e fornece dois métodos de conveniência para abrir contêineres:
ContainerOpener.openContainer(..., Notifier notifier) e
ContainerOpener.openContainer(..., Long timeoutInMillis).
Cada um desses métodos usa uma enumeração que solicita um contêiner não padrão ou novo.
OpenType.PREFER_NON_DEFAULT é recomendado para a maioria dos aplicativos e tenta retornar o primeiro contêiner não padrão disponível dentro de um determinado período de tempo limite, do disco ou da rede, mesmo que esse contêiner tenha mais de 12 horas. Se ele retornar um contêiner salvo desatualizado, também fará uma solicitação de rede assíncrona para um novo.
Ao usar OpenType.PREFER_NON_DEFAULT, um contêiner padrão será retornado se nenhum outro contêiner estiver disponível ou se o período de tempo limite for excedido.
OpenType.PREFER_FRESH tenta retornar um novo contêiner do disco ou da rede dentro do período de tempo limite especificado.
Ele retorna um contêiner salvo se uma conexão de rede não estiver disponível e/ou o período de tempo limite for excedido.
Não é recomendável usar OpenType.PREFER_FRESH em locais em que um tempo de solicitação mais longo possa afetar consideravelmente a experiência do usuário, como com flags de interface ou strings de exibição. Você também pode usar
Container.refresh()
a qualquer momento
para forçar uma solicitação de contêiner de rede.
Esses dois métodos de conveniência não são bloqueadores.
ContainerOpener.openContainer(..., Long timeoutInMillis) retorna um
ContainerOpener.ContainerFuture objeto, cujo get método retorna um
Container assim que ele é carregado (mas que será bloqueado até então).
O método ContainerOpener.openContainer(..., Notifier notifier) usa um único callback, chamado quando o contêiner está disponível, que pode ser usado para evitar o bloqueio da linha de execução principal.
Os dois métodos têm um período de tempo limite padrão de 2000 milissegundos.
Avaliar macros no tempo de execução usando regras
Os contêineres podem avaliar valores no tempo de execução usando regras. As regras podem ser baseadas em critérios como idioma, plataforma ou qualquer outro valor de macro do dispositivo. Por exemplo, as regras podem ser usadas para selecionar uma string de exibição localizada com base no idioma do dispositivo no tempo de execução. Isso pode ser configurado usando a seguinte regra:
Em seguida, você pode criar macros de coleta de valores para cada idioma e adicionar essa regra a cada macro, inserindo o código de idioma apropriado. Quando esse contêiner for publicado, o aplicativo poderá mostrar strings de exibição localizadas, dependendo do idioma do dispositivo do usuário no tempo de execução.
Se o contêiner padrão precisar de regras, use um arquivo de contêiner binário como contêiner padrão.
Saiba mais sobre como configurar regras (Central de Ajuda).
Arquivos de contêiner padrão binários
Os contêineres padrão que precisam de regras precisam usar um arquivo de contêiner binário em vez de um arquivo JSON como contêiner padrão. Os contêineres binários oferecem suporte para determinar valores de macro no tempo de execução com regras do Google Tag Manager, enquanto JSON arquivos não.
Os arquivos de contêiner binários podem ser baixados da interface da Web do Google Tag Manager e precisam ser adicionados à pasta /assets/tagmanager/ do seu projeto e seguir este padrão: /assets/tagmanager/GTM-XXXX, em que o nome do arquivo representa o ID do contêiner.
Nos casos em que um arquivo JSON e um arquivo de contêiner binário estão presentes, o SDK vai usar o arquivo de contêiner binário como contêiner padrão.
Usar macros de chamada de função
As macros de chamada de função são macros definidas como o valor de retorno de uma função especificada no aplicativo. As macros de chamada de função podem ser usadas para incorporar valores de tempo de execução com as regras do Google Tag Manager, como determinar no tempo de execução qual preço mostrar a um usuário com base no idioma e na moeda configurados de um dispositivo.
Para configurar uma macro de chamada de função:
- Defina a macro de chamada de função na interface da Web do Google Tag Manager. Os argumentos podem ser configurados opcionalmente como pares de chave-valor.
- Registre um
FunctionCallMacroHandlerno aplicativo usandoContainer.registerFunctionCallMacroHandler()e o nome da função configurada na interface da Web do Google Tag Manager, substituindo o métodogetValue():/** * Registers a function call macro handler. * * @param functionName The function name field, as defined in the Google Tag * Manager web interface. */ mContainer.registerFunctionCallMacroHandler(functionName, new FunctionCallMacroHandler() { /** * This code will execute when any custom macro's rule(s) evaluate to true. * The code should check the functionName and process accordingly. * * @param functionName Corresponds to the function name field defined * in the Google Tag Manager web interface. * @param parameters An optional map of parameters * as defined in the Google Tag Manager web interface. */ @Override public Object getValue(String functionName, Map<String, Object> parameters)) { if (functionName.equals("myConfiguredFunctionName")) { // Process and return the calculated value of this macro accordingly. return macro_value } return null; } });
Usar tags de chamada de função
As tags de chamada de função permitem que funções pré-registradas sejam executadas sempre que
um evento é enviado para a camada de dados e as regras de tag
são avaliadas como true.
Para configurar uma tag de chamada de função:
- Defina a tag de chamada de função na interface da Web do Google Tag Manager. Os argumentos podem ser configurados opcionalmente como pares de chave-valor.
- Registre um gerenciador de tags de chamada de função no aplicativo usando
Container.registerFunctionCallTagHandler():/** * Register a function call tag handler. * * @param functionName The function name, which corresponds to the function name field * Google Tag Manager web interface. */ mContainer.registerFunctionCallTagHandler(functionName, new FunctionCallTagHandler() { /** * This method will be called when any custom tag's rule(s) evaluates to true. * The code should check the functionName and process accordingly. * * @param functionName The functionName passed to the functionCallTagHandler. * @param parameters An optional map of parameters as defined in the Google * Tag Manager web interface. */ @Override public void execute(String functionName, Map<String, Object> parameters) { if (functionName.equals("myConfiguredFunctionName")) { // Process accordingly. } } });
Definir um período de atualização personalizado
O SDK do Google Tag Manager vai tentar recuperar um novo contêiner se a idade do contêiner atual exceder 12 horas. Para definir um período de atualização de contêiner personalizado, use Timer, como no exemplo a seguir:
timer.scheduleTask(new TimerTask() { @Override public void run() { mContainer.refresh(); } }, delay, <new_period_in milliseconds>);
Depurar com o Logger
O SDK do Google Tag Manager imprime erros e avisos nos registros por padrão.
Ativar o registro mais detalhado pode ser útil para depuração e é possível implementando seu próprio Logger com
TagManager.setLogger, como neste exemplo:
TagManager tagManager = TagManager.getInstance(this); tagManager.setLogger(new Logger() { final String TAG = "myGtmLogger"; // Log output with verbosity level of DEBUG. @Override public void d(String arg0) { Log.d(TAG, arg0); } // Log exceptions when provided. @Override public void d(String arg0, Throwable arg1) { Log.d(TAG, arg0); arg1.printStackTrace(); } // Rest of the unimplemented Logger methods. });
Ou, você pode definir o LogLevel do Logger atual usando
TagManager.getLogger().setLogLevel(LogLevel)
,
como neste exemplo:
// Change the LogLevel to INFO to enable logging at INFO and higher levels. TagManager tagManager = TagManager.getInstance(this); tagManager.getLogger().setLogLevel(LogLevel.INFO);