Android 3. (starsza wersja) – omówienie

Z tego przewodnika dla deweloperów dowiesz się, jak zaimplementować Menedżera tagów Google w aplikacji mobilnej.

Wprowadzenie

Menedżer tagów Google umożliwia deweloperom zmianę wartości konfiguracji w aplikacjach mobilnych za pomocą interfejsu Menedżera tagów Google bez konieczności ponownego tworzenia i przesyłania plików binarnych aplikacji do sklepów z aplikacjami.

Jest to przydatne do zarządzania dowolnymi wartościami konfiguracji lub flagami w aplikacji, które mogą wymagać zmiany w przyszłości, w tym:

  • różne ustawienia interfejsu i ciągi wyświetlane;
  • rozmiary, lokalizacje lub typy reklam wyświetlanych w aplikacji;
  • ustawienia gier.

Wartości konfiguracji można też oceniać w czasie działania aplikacji za pomocą reguł, co umożliwia dynamiczne konfiguracje, takie jak:

  • określanie rozmiaru banera reklamowego na podstawie rozmiaru ekranu;
  • konfigurowanie elementów interfejsu na podstawie języka i lokalizacji.

Menedżer tagów Google umożliwia też dynamiczną implementację tagów śledzących i pikseli w aplikacjach. Deweloperzy mogą przekazywać ważne zdarzenia do warstwy danych i później decydować, które tagi lub piksele śledzące mają się uruchamiać. Menedżer tagów obsługuje te tagi:

  • Google Analytics dla aplikacji mobilnych
  • niestandardowy tag wywołania funkcji.

Zanim zaczniesz

Zanim zaczniesz korzystać z tego przewodnika, musisz mieć:

Jeśli dopiero zaczynasz korzystać z Menedżera tagów Google, przed kontynuowaniem lektury tego przewodnika zapoznaj się z informacjami o kontenerach, makrach i regułach (Centrum pomocy).

Pierwsze kroki

W tej sekcji deweloperzy dowiedzą się, jak wygląda typowy proces pracy z Menedżerem tagów:

  1. Dodaj pakiet SDK Menedżera tagów Google do projektu.
  2. Ustaw domyślne wartości kontenera.
  3. Otwórz kontener.
  4. Pobierz wartości konfiguracji z kontenera.
  5. Przekaż zdarzenia do warstwy danych.
  6. Wyświetl podgląd kontenera i opublikuj go.

1. Dodawanie pakietu SDK Menedżera tagów Google do projektu

Zanim zaczniesz korzystać z pakietu SDK Menedżera tagów Google, musisz wyodrębnić pakiet SDK, dodać bibliotekę do ścieżki kompilacji projektu i dodać uprawnienia do pliku AndroidManifest.xml.

Najpierw dodaj bibliotekę Menedżera tagów Google do folderu /libs w projekcie.

Następnie zaktualizuj plik AndroidManifest.xml, aby używać tych uprawnień:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

2. Dodawanie do projektu domyślnego pliku kontenera

Przy pierwszym uruchomieniu aplikacji Menedżer tagów Google używa domyślnego kontenera. Domyślny kontener będzie używany, dopóki aplikacja nie będzie mogła pobrać nowego kontenera przez sieć.

Aby pobrać i dodać do aplikacji domyślny plik binarny kontenera, wykonaj te czynności:

  1. Zaloguj się w interfejsie Menedżera tagów Google.
  2. Wybierz wersję kontenera, którą chcesz pobrać.
  3. Kliknij przycisk Pobierz , aby pobrać plik binarny kontenera.
  4. Dodaj plik binarny do tej ścieżki: <project-root>/assets/tagmanager/

Domyślna nazwa pliku powinna być taka sama jak identyfikator kontenera (np. GTM-1234). Po pobraniu pliku binarnego usuń z nazwy pliku sufiks wersji, aby zachować prawidłową konwencję nazewnictwa.

Chociaż zalecamy używanie pliku binarnego, jeśli kontener nie zawiera reguł ani tagów, możesz użyć pliku JSON. Plik musi znajdować się w nowym /assets/tagmanager folderze w projekcie aplikacji na Androida i powinien być zgodny z tą konwencją nazewnictwa: <Container_ID>.json. Jeśli na przykład identyfikator kontenera to GTM-1234, musisz dodać domyślne wartości kontenera do /assets/tagmanager/GTM-1234.json.

3. Otwieranie kontenera

Zanim pobierzesz wartości z kontenera, musisz otworzyć go w aplikacji. Otwarcie kontenera spowoduje jego wczytanie z dysku (jeśli jest dostępny) lub pobranie z sieci (jeśli jest to konieczne).

Najłatwiejszym sposobem otwarcia kontenera na Androidzie jest użycie ContainerOpener.openContainer(..., Notifier notifier), jak w tym przykładzie:

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.
  }
}

W tym przykładzie ContainerOpener.openContainer(..., Notifier notifier) służy do wysyłania żądania zapisanego kontenera z pamięci lokalnej. Obsługując przypisanie mContainer w wywołaniu zwrotnym containerAvailable, zapewniamy, że wątek główny nie zostanie zablokowany. Jeśli zapisany kontener jest starszy niż 12 godzin, wywołanie zaplanuje też asynchroniczne żądanie pobrania nowego kontenera przez sieć.

Ta przykładowa implementacja przedstawia najprostszy sposób otwierania kontenera i pobierania z niego wartości za pomocą klasy pomocniczej ContainerOpener. Więcej informacji o zaawansowanych opcjach implementacji znajdziesz w sekcji Konfiguracja zaawansowana.

4. Pobieranie wartości konfiguracji z kontenera

Po otwarciu kontenera wartości konfiguracji można pobierać za pomocą metod get<type>Value():

// Retrieving a configuration value from a Tag Manager Container.

// Get the configuration value by key.
String title = mContainer.getStringValue("title_string");

Żądania wysyłane z użyciem nieistniejącego klucza będą zwracać wartość domyślną odpowiednią dla żądanego typu:

// 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. Przekazywanie wartości do warstwy danych

Warstwa danych to mapa, która umożliwia udostępnianie makrom i tagom w kontenerze informacji o aplikacji w czasie działania, takich jak zdarzenia dotknięcia czy wyświetlenia ekranu, do udostępnienia makrom i tagom Menedżera tagów w kontenerze.

Na przykład, przekazując informacje o wyświetleniach ekranu do mapy warstwy danych, możesz skonfigurować w interfejsie Menedżera tagów tagi, które będą uruchamiać piksele konwersji i wywołania śledzące w odpowiedzi na te wyświetlenia ekranu bez konieczności kodowania ich w aplikacji.

Zdarzenia są przekazywane do warstwy danych za pomocą push() i metody pomocniczej DataLayer.mapOf():

//
// 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
}

W interfejsie możesz teraz tworzyć tagi (np. tagi Google Analytics) które będą się uruchamiać przy każdym wyświetleniu ekranu, tworząc tę regułę: equals "openScreen". Aby przekazać nazwę ekranu do jednego z tych tagów, utwórz makro warstwy danych, które odwołuje się do klucza „screenName” w warstwie danych. Możesz też utworzyć tag (np. piksel śledzenia konwersji Google Ads), który będzie się uruchamiać tylko w przypadku określonych wyświetleń ekranu, tworząc regułę, w której equals "openScreen" && equals "ConfirmationScreen".

6. Wyświetlanie podglądu i publikowanie kontenera

Wartości makr zawsze odpowiadają bieżącej opublikowanej wersji. Zanim opublikujesz najnowszą wersję kontenera, możesz wyświetlić podgląd jego wersji roboczej.

Aby wyświetlić podgląd kontenera, wygeneruj adres URL podglądu w interfejsie Menedżera tagów Google . W tym celu wybierz wersję kontenera , której podgląd chcesz wyświetlić, a następnie kliknij Preview. Zapisz ten adres URL podglądu, ponieważ będzie Ci potrzebny w kolejnych krokach.

Adresy URL podglądu są dostępne w oknie podglądu interfejsu internetowego Menedżera tagów.
Rysunek 1. Pobieranie adresu URL podglądu z interfejsu Menedżera tagów Google.

Następnie dodaj do pliku AndroidManifest.xml aplikacji tę aktywność:

<!-- 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>
  

Otwórz link w emulatorze lub na urządzeniu fizycznym, aby wyświetlić podgląd wersji roboczej kontenera w aplikacji.

Gdy wersja robocza wartości konfiguracji będzie gotowa do udostępnienia w aplikacji, opublikuj kontener.

Konfiguracja zaawansowana

Menedżer tagów Google do aplikacji mobilnych ma szereg zaawansowanych opcji konfiguracji, które umożliwiają wybieranie wartości na podstawie warunków w czasie działania aplikacji za pomocą reguł, ręczne odświeżanie kontenera i uzyskiwanie dodatkowych opcji otwierania kontenerów. W kolejnych sekcjach opisujemy kilka najczęstszych zaawansowanych konfiguracji.

Zaawansowane opcje otwierania kontenerów

Pakiet SDK Menedżera tagów Google udostępnia kilka metod otwierania kontenerów, które mogą zapewnić większą kontrolę nad procesem wczytywania:

TagManager.openContainer()

TagManager.openContainer() to interfejs API najniższego poziomu i najbardziej elastyczny do otwierania kontenera. Natychmiast zwraca domyślny kontener i asynchronicznie wczytuje kontener z dysku lub sieci, jeśli nie ma zapisanego kontenera lub jeśli zapisany kontener jest nieaktualny (starszy niż 12 godzin).

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.
  }

Podczas procesu wczytywania TagManager.openContainer() wysyła kilka wywołań zwrotnych cyklu życia, dzięki czemu kod może się dowiedzieć, kiedy rozpoczyna się żądanie wczytania, czy i dlaczego się nie powiodło lub powiodło, oraz czy kontener został ostatecznie wczytany z dysku czy z sieci.

Jeśli nie akceptujesz używania w aplikacji wartości domyślnych, musisz użyć tych wywołań zwrotnych, aby wiedzieć, kiedy wczytano zapisany lub sieciowy kontener. Pamiętaj, że nie będzie można wczytać zapisanego ani sieciowego kontenera, jeśli aplikacja jest uruchamiana po raz pierwszy i nie ma połączenia z siecią.

TagManager.openContainer() przekazuje do tych wywołań zwrotnych te wartości enum jako argumenty:

RefreshType

WartośćOpis
Container.Callback.SAVED Żądanie odświeżenia wczytuje zapisany lokalnie kontener.
Container.Callback.NETWORK Żądanie odświeżenia wczytuje kontener przez sieć.

RefreshFailure

WartośćOpis
Container.Callback.NO_SAVED_CONTAINER Nie ma zapisanego kontenera.
Container.Callback.IO_ERROR Błąd wejścia/wyjścia uniemożliwił odświeżenie kontenera.
Container.Callback.NO_NETWORK Brak połączenia sieciowego.
Container.Callback.NETWORK_ERROR Wystąpił błąd sieci.
Container.Callback.SERVER_ERROR Wystąpił błąd serwera.
Container.Callback.UNKNOWN_ERROR Wystąpił błąd, którego nie można sklasyfikować.

Metody otwierania kontenerów innych niż domyślne i nowych

ContainerOpener opakowuje TagManager.openContainer() i udostępnia 2 metody pomocnicze do otwierania kontenerów: ContainerOpener.openContainer(..., Notifier notifier) i ContainerOpener.openContainer(..., Long timeoutInMillis).

Każda z tych metod przyjmuje wyliczenie, które żąda kontenera innego niż domyślny lub nowego.

W przypadku większości aplikacji zalecamy używanie OpenType.PREFER_NON_DEFAULT, które próbuje zwrócić pierwszy dostępny kontener inny niż domyślny w określonym czasie, z dysku lub sieci, nawet jeśli kontener jest starszy niż 12 godzin. Jeśli zwróci nieaktualny zapisany kontener, wyśle też asynchroniczne żądanie sieciowe o nowy kontener. Jeśli używasz OpenType.PREFER_NON_DEFAULT, zostanie zwrócony domyślny kontener, jeśli nie będzie dostępny żaden inny kontener lub jeśli upłynie limit czasu.

OpenType.PREFER_FRESH próbuje zwrócić nowy kontener z dysku lub sieci w określonym czasie. Zwraca zapisany kontener, jeśli połączenie sieciowe jest niedostępne lub upłynie limit czasu.

Nie zalecamy używania OpenType.PREFER_FRESH w miejscach, w których dłuższy czas żądania może zauważalnie wpłynąć na wygodę użytkownika, np. w przypadku flag interfejsu lub ciągów wyświetlanych. W dowolnym momencie możesz też użyć Container.refresh() , aby wymusić żądanie kontenera sieciowego.

Obie te metody pomocnicze nie blokują. ContainerOpener.openContainer(..., Long timeoutInMillis) zwraca obiekt ContainerOpener.ContainerFuture, którego metoda get zwraca Container zaraz po jego wczytaniu (ale do tego czasu blokuje). Metoda ContainerOpener.openContainer(..., Notifier notifier) przyjmuje pojedyncze wywołanie zwrotne, które jest wywoływane, gdy kontener jest dostępny. Można go użyć, aby zapobiec blokowaniu wątku głównego. Obie metody mają domyślny limit czasu wynoszący 2000 milisekund.

Ocena makr w czasie działania aplikacji za pomocą reguł

Kontenery mogą oceniać wartości w czasie działania aplikacji za pomocą reguł. Reguły mogą być oparte na kryteriach takich jak język urządzenia, platforma lub dowolna inna wartość makra. Na przykład reguły mogą służyć do wybierania zlokalizowanego ciągu wyświetlanego na podstawie języka urządzenia w czasie działania aplikacji. Można to skonfigurować za pomocą tej reguły:

Reguła służy do wybierania ciągów wyświetlanych na podstawie języka urządzenia w czasie działania: język równy es. Ta reguła używa predefiniowanego makra języka i dwuznakowego kodu języka ISO 639-1.
Rysunek 1.Dodawanie reguły, która włącza makro do zbierania wartości tylko w przypadku urządzeń skonfigurowanych do używania języka hiszpańskiego.

Następnie możesz utworzyć makra do zbierania wartości dla każdego języka i dodać do każdego makra tę regułę, wstawiając odpowiedni kod języka. Gdy ten kontener zostanie opublikowany, aplikacja będzie mogła wyświetlać zlokalizowane ciągi wyświetlane w zależności od języka urządzenia użytkownika w czasie działania aplikacji.

Jeśli domyślny kontener wymaga reguł, musisz użyć jako domyślnego kontenera binarnego pliku kontenera.

Więcej informacji o konfigurowaniu reguł znajdziesz w Centrum pomocy.

Binarne domyślne pliki kontenera

Domyślne kontenery, które wymagają reguł, powinny używać jako domyślnego kontenera binarnego pliku kontenera zamiast pliku JSON. Kontenery binarne obsługują określanie wartości makr w czasie działania aplikacji za pomocą reguł Menedżera tagów Google, natomiast pliki JSON nie.

Binarne pliki kontenera można pobrać z interfejsu Menedżera tagów Google i należy je dodać do folderu projektu /assets/tagmanager/i powinny być zgodne z tym wzorcem: /assets/tagmanager/GTM-XXXX, gdzie nazwa pliku reprezentuje identyfikator kontenera.

Jeśli obecny jest zarówno plik JSON, jak i binarny plik kontenera, pakiet SDK użyje binarnego pliku kontenera jako domyślnego kontenera.

Używanie makr wywołania funkcji

Makra wywołania funkcji to makra, które są ustawione na wartość zwracaną przez określoną funkcję w aplikacji. Makra wywołania funkcji mogą służyć do uwzględniania wartości w czasie działania aplikacji w regułach Menedżera tagów Google, np. do określania w czasie działania aplikacji ceny, która ma być wyświetlana użytkownikowi, na podstawie skonfigurowanego języka i waluty urządzenia.

Aby skonfigurować makro wywołania funkcji:

  1. Zdefiniuj makro wywołania funkcji w interfejsie Menedżera tagów Google. Argumenty można opcjonalnie skonfigurować jako pary klucz-wartość.
  2. Zarejestruj w aplikacji FunctionCallMacroHandler za pomocą Container.registerFunctionCallMacroHandler() i nazwy funkcji skonfigurowanej w interfejsie Menedżera tagów Google, zastępując jej getValue() metodę:
    /**
     * 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;
      }
    });

Używanie tagów wywołania funkcji

Tagi wywołania funkcji umożliwiają wykonywanie zarejestrowanych wcześniej funkcji, gdy zdarzenie zostanie przekazane do warstwy danych, a reguły tagu zwrócą wartość true.

Aby skonfigurować tag wywołania funkcji:

  1. Zdefiniuj tag wywołania funkcji w interfejsie Menedżera tagów Google. Argumenty można opcjonalnie skonfigurować jako pary klucz-wartość.
  2. Zarejestruj w aplikacji obsługę tagu wywołania funkcji za pomocą 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.
        }
      }
    });

Ustawianie niestandardowego okresu odświeżania

Pakiet SDK Menedżera tagów Google spróbuje pobrać nowy kontener, jeśli wiek bieżącego kontenera przekroczy 12 godzin. Aby ustawić niestandardowy okres odświeżania kontenera, użyj Timer, jak w tym przykładzie:

timer.scheduleTask(new TimerTask() {
  @Override
  public void run() {
    mContainer.refresh();
  }
}, delay, <new_period_in milliseconds>);

Debugowanie za pomocą rejestratora

Pakiet SDK Menedżera tagów Google domyślnie zapisuje błędy i ostrzeżenia w logach. Włączenie bardziej szczegółowego logowania może być przydatne do debugowania. Można to zrobić, implementując własny Logger za pomocą TagManager.setLogger, jak w tym przykładzie:

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.

});

Możesz też ustawić LogLevel istniejącego rejestratora za pomocą TagManager.getLogger().setLogLevel(LogLevel) , jak w tym przykładzie:

// Change the LogLevel to INFO to enable logging at INFO and higher levels.
TagManager tagManager = TagManager.getInstance(this);
tagManager.getLogger().setLogLevel(LogLevel.INFO);