Android 3. (starsza wersja) – omówienie

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

Wstęp

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

Jest to przydatne do zarządzania wszelkimi wartościami konfiguracyjnymi lub flagami w aplikacji, które w przyszłości konieczne może być zmiana, takimi jak:

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

Wartości konfiguracji mogą być też oceniane w czasie działania za pomocą reguł, które włączają konfiguracje dynamiczne, takie jak:

  • Używanie rozmiaru ekranu do określania rozmiaru banera reklamowego
  • Używanie języka i lokalizacji do konfigurowania elementów interfejsu

Menedżer tagów Google umożliwia też dynamiczną implementację tagów i pikseli śledzenia w aplikacjach. Deweloperzy mogą przekazywać ważne zdarzenia do warstwy danych i później zdecydować, które tagi śledzenia lub piksele mają być uruchamiane. Menedżer tagów obsługuje obecnie następujące tagi:

  • Analytics dla aplikacji mobilnych Google
  • Tag wywołania funkcji niestandardowej

Zanim zaczniesz

Zanim zaczniesz korzystać z tego przewodnika, będziesz potrzebować:

Jeśli dopiero zaczynasz korzystać z Menedżera tagów Google, zalecamy, aby przed przejściem do kolejnego przewodnika dowiedzieć się więcej o kontenerach, makrach i regułach.

Pierwsze kroki

W tej sekcji programiści mogą wykonać typowy proces działania Menedżera tagów:

  1. Dodawanie do projektu pakietu SDK Menedżera tagów Google
  2. Ustawianie domyślnych wartości kontenerów
  3. Otwórz kontener
  4. Pobieranie wartości konfiguracyjnych z kontenera
  5. Przekazywanie zdarzeń do warstwy danych
  6. Wyświetlanie podglądu i publikowanie kontenera

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

Przed rozpoczęciem korzystania z pakietu SDK Menedżera tagów Google musisz rozpakować pakiet SDK, dodać bibliotekę do ścieżki kompilacji projektu i nadać uprawnienia do pliku AndroidManifest.xml.

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

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

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

2. Dodawanie domyślnego pliku kontenera do projektu

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

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

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

Domyślną nazwą pliku powinien być identyfikator kontenera (np. GTM-1234). Po pobraniu pliku binarnego pamiętaj o usunięciu z nazwy pliku sufiksu wersji, aby zachować prawidłową konwencję nazewnictwa.

Zalecamy użycie pliku binarnego, ale jeśli Twój kontener nie zawiera reguł ani tagów, możesz użyć prostego pliku JSON. Plik musi się znajdować w nowym folderze /assets/tagmanager projektu na Androida i muszą być zgodne z tą konwencją nazewnictwa: <Container_ID>.json. Jeśli np. identyfikator kontenera to GTM-1234, należy dodać domyślne wartości kontenera do funkcji /assets/tagmanager/GTM-1234.json.

3. Otwieranie kontenera

Przed pobraniem wartości z kontenera aplikacja musi go otworzyć. Otwarcie kontenera spowoduje wczytanie go z dysku (jeśli będzie dostępny) lub użycie go do sieci (w razie potrzeby).

Najprostszym sposobem na otwarcie 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 żądań dotyczących zapisanego kontenera z pamięci lokalnej. Przypiszemy mContainer w wywołaniu zwrotnym containerAvailable, aby mieć pewność, że wątek główny nie jest blokowany. Jeśli zapisany kontener jest starszy niż 12 godzin, wywołanie zaplanuje też asynchroniczne żądanie asynchronicznego pobierania nowego kontenera przez sieć.

Ta przykładowa implementacja to najprostszy sposób otwierania i pobierania wartości z kontenera za pomocą klasy wygodnej ContainerOpener. Informacje o bardziej zaawansowanych opcjach implementacji znajdziesz w artykule Konfiguracja zaawansowana.

4. Pobieranie wartości konfiguracyjnych z kontenera

Po otwarciu kontenera wartości konfiguracyjne 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 wysłane przy użyciu nieistniejącego klucza będą zwracać wartość domyślną odpowiednią do żą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

Warstwy danych to mapa, dzięki której informacje o aplikacji w czasie działania, np. zdarzenia kliknięcia czy wyświetlenia ekranu, mogą być dostępne dla makr i tagów Menedżera tagów w kontenerze.

Na przykład umieszczając informacje o wyświetleniach ekranu na mapę warstw DataLayer, możesz skonfigurować w interfejsie internetowym Menedżera tagów tagi, które będą uruchamiać piksele konwersji i śledzić wywołania w odpowiedzi na te wyświetlenia ekranu bez konieczności kodowania na stałe w aplikacji.

Zdarzenia są przekazywane do warstwy danych za pomocą właściwości 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 internetowym możesz teraz tworzyć tagi (np. tagi Google Analytics), które będą się uruchamiać dla każdego wyświetlenia ekranu. W tym celu utwórz następującą regułę: równa się „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 konwersji Google Ads), który będzie uruchamiany tylko w przypadku określonych wyświetleń ekranu. W tym celu utwórz regułę, w której równa się „openScreen” && równa się „ConfirmationScreen”.

6. Wyświetlanie podglądu i publikowanie kontenera

Wartości makr zawsze będą odpowiadać obecnie opublikowanej wersji. Przed opublikowaniem najnowszej wersji kontenera możesz wyświetlić jego podgląd.

Aby wyświetlić podgląd kontenera, wygeneruj adres URL podglądu w interfejsie internetowym Menedżera tagów Google. Aby to zrobić, wybierz wersję kontenera, której podgląd chcesz wyświetlić, a potem kliknij Preview. Zachowuj się nad tym adresem URL podglądu, ponieważ będziesz go potrzebować na kolejnych etapach.

Adresy URL podglądu są dostępne w oknie podglądu interfejsu internetowego Menedżera tagów
Rys. 1: Uzyskiwanie adresu URL podglądu w interfejsie internetowym Menedżera tagów.

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

<!-- 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 wszystko będzie gotowe do udostępnienia w aplikacji wartości roboczych wersji roboczych, opublikuj kontener.

Konfiguracja zaawansowana

Menedżer tagów Google do aplikacji mobilnych ma wiele zaawansowanych opcji konfiguracji, które pozwalają wybierać wartości w zależności od warunków środowiska wykonawczego za pomocą reguł, ręcznie odświeżać kontener i uzyskiwać dodatkowe opcje otwierania kontenerów. W sekcjach poniżej opisujemy kilka najczęstszych konfiguracji zaawansowanych.

Zaawansowane opcje otwierania kontenerów

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

TagManager.openContainer()

TagManager.openContainer() to najniższy poziom i najbardziej elastyczny interfejs API do otwierania kontenera. Zwracany jest natychmiast z domyślnym kontenerem. Również asynchronicznie wczytuje kontener z dysku lub sieci, jeśli nie istnieje żaden zapisany kontener lub jeśli zapisany kontener nie jest aktualny (ma ponad 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.
  }

W trakcie procesu wczytywania TagManager.openContainer() wysyła kilka wywołań zwrotnych cyklu życia, aby Twój kod mógł dowiedzieć się, kiedy zaczyna się żądanie wczytywania, czy i dlaczego kończy się ono niepowodzeniem oraz czy zakończyło się ono sukcesem, a także czy kontener został ostatecznie załadowany z dysku czy sieci.

O ile nie jest to dozwolone w Twojej aplikacji, musisz używać tych wywołań zwrotnych do sprawdzania, kiedy zapisany lub kontener sieci został wczytany. Jeśli aplikacja jest uruchamiana po raz pierwszy i nie ma połączenia sieciowego, nie będzie można wczytać zapisanego kontenera lub kontenera sieciowego.

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

RefreshType

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

RefreshFailure

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

Metody otwierania nowych i niedomyślnych kontenerów

ContainerOpener pakuje element TagManager.openContainer() i zapewnia 2 wygodne metody otwierania kontenerów: ContainerOpener.openContainer(..., Notifier notifier) i ContainerOpener.openContainer(..., Long timeoutInMillis).

Każda z tych metod wymaga wyliczenia żądającego kontenera nowego lub innego niż domyślny.

Parametr OpenType.PREFER_NON_DEFAULT jest zalecany w przypadku większości aplikacji i próbuje zwrócić z dysku lub sieci pierwszy dostępny kontener inny niż domyślny w danym okresie czasu oczekiwania, nawet jeśli ma on więcej niż 12 godzin. Jeśli zwróci nieaktualny zapisany kontener, wyśle też asynchroniczne żądanie sieciowe na nowy. Gdy używasz OpenType.PREFER_NON_DEFAULT, zwracany jest domyślny kontener, jeśli nie będzie dostępny żaden inny kontener lub jeśli zostanie przekroczony limit czasu oczekiwania.

OpenType.PREFER_FRESH próbuje zwrócić nowy kontener z dysku lub sieci w podanym okresie oczekiwania. Zwraca zapisany kontener, jeśli połączenie sieciowe jest niedostępne lub został przekroczony limit czasu.

Nie zalecamy używania OpenType.PREFER_FRESH w miejscach, gdzie dłuższy czas żądania może zauważalnie wpływać na wrażenia użytkownika, na przykład w przypadku flag interfejsu lub wyświetlanych ciągów. W każdej chwili możesz też użyć Container.refresh(), aby wymusić wysłanie żądania kontenera sieciowego.

Obie te metody nie blokują dostępu. ContainerOpener.openContainer(..., Long timeoutInMillis) zwraca obiekt ContainerOpener.ContainerFuture, którego metoda get zwraca Container natychmiast po wczytaniu (ale do tego czasu ta metoda jest blokowana). Metoda ContainerOpener.openContainer(..., Notifier notifier) przyjmuje jedno wywołanie zwrotne, które jest wywoływane, gdy kontener jest dostępny. Za pomocą tego można uniknąć zablokowania wątku głównego. Dla obu metod domyślny limit czasu oczekiwania wynosi 2000 milisekund.

Ocena makr w środowisku wykonawczym z użyciem reguł

Kontenery mogą oceniać wartości w czasie działania za pomocą reguł. Reguły mogą opierać się na takich kryteriach jak język urządzenia, platforma lub dowolna inna wartość makra. Za pomocą reguł można na przykład wybrać zlokalizowany wyświetlany ciąg znaków na podstawie języka urządzenia w czasie działania. Możesz to skonfigurować, korzystając z tej reguły:

Reguła służy do wybierania wyświetlanych ciągów na podstawie języka urządzenia w czasie działania: język równa się es. Ta reguła korzysta ze wstępnie zdefiniowanego makra języka i dwuznakowego kodu języka w formacie ISO 639-1.
Rysunek 1. Dodawanie reguły włączającej makro zbierania wartości tylko w przypadku urządzeń skonfigurowanych do używania języka hiszpańskiego

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

Pamiętaj, że jeśli domyślny kontener wymaga reguł, musisz użyć pliku binarnego jako kontenera domyślnego.

Więcej informacji o konfigurowaniu reguł (Centrum pomocy)

Domyślne binarne pliki kontenerów

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

Pliki binarne można pobrać z interfejsu internetowego Menedżera tagów Google. Należy je dodać do folderu /assets/tagmanager/ projektu zgodnie z tym wzorcem: /assets/tagmanager/GTM-XXXX, gdzie nazwa pliku reprezentuje identyfikator kontenera.

W przypadku plików JSON i binarnych kontenerów pakiet SDK użyje ich jako domyślnego kontenera.

Używanie makr wywołań funkcji

Makra wywołań funkcji to makra, które są ustawione na wartość zwracaną przez określoną funkcję w Twojej aplikacji. Makra wywołań funkcji mogą służyć do dołączania do reguł Menedżera tagów Google wartości środowiska wykonawczego, np. do określania w czasie działania 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 internetowym Menedżera tagów Google. Argumenty mogą być opcjonalnie skonfigurowane jako pary klucz-wartość.
  2. Zarejestruj FunctionCallMacroHandler w aplikacji za pomocą Container.registerFunctionCallMacroHandler() i nazwy funkcji skonfigurowanej w interfejsie internetowym Menedżera tagów Google, zastępując jej metodę getValue():
    /**
     * 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ą uruchamianie wcześniej zarejestrowanych funkcji za każdym razem, gdy zdarzenie jest przekazywane do warstwy danych, a reguły tagu zwracają wartość true.

Aby skonfigurować tag wywołania funkcji:

  1. Zdefiniuj tag wywołania funkcji w interfejsie internetowym Menedżera tagów Google. Argumenty mogą być opcjonalnie skonfigurowane jako pary klucz-wartość.
  2. Zarejestruj moduł obsługi tagu wywołania funkcji w aplikacji 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

Jeśli bieżący wiek kontenera przekroczy 12 godzin, pakiet SDK Menedżera tagów Google spróbuje pobrać nowy kontener. Aby ustawić niestandardowy okres odświeżania kontenera, użyj parametru 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 wyświetla błędy i ostrzeżenia w dziennikach. Włączenie bardziej szczegółowego logowania może pomóc w debugowaniu. Aby to zrobić, możesz zaimplementować własny Logger w metodzie 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ć poziom logu dla istniejącego dziennika, używając parametru 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);