Android v3 (舊版) - 總覽

本開發人員指南說明如何在行動應用程式中導入 Google 代碼管理工具。

簡介

開發人員可透過 Google 代碼管理工具介面,在行動應用程式中變更設定值,不必重建應用程式,也不必將應用程式二進位檔重新提交至應用程式市集。

這項功能有助於管理應用程式中日後可能需要變更的任何設定值或旗標,包括:

  • 各種 UI 設定和顯示字串
  • 應用程式中放送的廣告大小、位置或類型
  • 遊戲設定

設定值也可以在執行階段使用規則進行評估,以啟用動態設定,例如:

  • 根據螢幕大小判斷廣告橫幅大小
  • 使用語言和位置資訊設定 UI 元素

Google 代碼管理工具也能在應用程式中動態導入追蹤代碼和像素。開發人員可以將重要事件推送至資料層,稍後再決定應觸發哪些追蹤代碼或像素。代碼管理工具支援下列代碼:

  • Google 行動應用程式分析
  • 自訂函式呼叫代碼

事前準備

使用本入門指南前,請先準備好下列項目:

如果您是 Google 代碼管理工具新手,建議先 進一步瞭解容器、巨集和規則 (說明中心),再繼續閱讀本指南。

開始使用

本節將引導開發人員完成典型的代碼管理工具工作流程:

  1. 將 Google 代碼管理工具 SDK 新增至專案
  2. 設定預設容器值
  3. 開啟容器
  4. 從容器取得設定值
  5. 將事件推送至資料層
  6. 預覽及發布容器

1. 在專案中加入 Google 代碼管理工具 SDK

使用 Google 代碼管理工具 SDK 前,請先解壓縮 SDK 套件,然後將程式庫新增至專案的建構路徑,並在 AndroidManifest.xml 檔案中新增權限。

首先,請將 Google 代碼管理工具程式庫新增至專案的 /libs 資料夾。

接著,請更新 AndroidManifest.xml 檔案,使用下列權限:

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

2. 在專案中新增預設容器檔案

應用程式首次執行時,Google 代碼管理工具會使用預設容器。在應用程式透過網路擷取新的容器之前,系統會使用預設容器。

如要下載預設容器二進位檔並新增至應用程式,請按照下列步驟操作:

  1. 登入 Google 代碼管理工具網頁介面。
  2. 選取要下載的容器版本
  3. 點選「下載」按鈕,即可擷取容器二進位檔。
  4. 將二進位檔案新增至下列路徑:<project-root>/assets/tagmanager/

預設檔案名稱應為容器 ID (例如 GTM-1234)。下載二進位檔案後,請務必從檔案名稱中移除版本後置字串,確保遵循正確的命名慣例。

建議使用二進位檔案,但如果容器不含規則或代碼,也可以改用 JSON 檔案。檔案必須位於 Android 專案的新 /assets/tagmanager 資料夾中,且應遵循下列命名慣例:<Container_ID>.json。舉例來說,如果容器 ID 為 GTM-1234,您應將預設容器值新增至 /assets/tagmanager/GTM-1234.json

3. 開啟容器

應用程式必須先開啟容器,才能從容器中擷取值。開啟容器時,系統會從磁碟載入容器 (如有),或從網路要求容器 (如有需要)。

在 Android 上開啟容器最簡單的方式是使用 ContainerOpener.openContainer(..., Notifier notifier),如下列範例所示:

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

在本範例中,ContainerOpener.openContainer(..., Notifier notifier) 用於從本機儲存空間要求已儲存的容器。在 containerAvailable 回呼中處理 mContainer 的指派作業,可確保主執行緒不會遭到封鎖。如果儲存的容器已超過 12 小時,呼叫也會排定要求,透過網路非同步擷取新的容器。

這個範例實作項目代表使用 ContainerOpener 便利類別,開啟及擷取容器值的最簡單方式。如需更多進階導入選項,請參閱「進階設定」。

4. 從容器取得設定值

開啟容器後,即可使用 get<type>Value() 方法擷取設定值:

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

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

如果要求使用的鍵不存在,系統會傳回適合所要求類型的預設值:

// 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. 將值推送到資料層

DataLayer 是一張地圖,可讓容器中的代碼管理工具巨集和代碼,取得應用程式的執行階段資訊,例如觸控事件或畫面檢視。

舉例來說,只要將螢幕檢視畫面相關資訊推送至 DataLayer 對應,您就能在代碼管理工具網頁介面中設定代碼,以便在這些螢幕檢視畫面觸發轉換像素和追蹤呼叫,不必在應用程式中硬式編碼。

使用 push()DataLayer.mapOf() 輔助方法,將事件推送至 DataLayer:

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

在網頁介面中,您現在可以建立代碼 (例如 Google Analytics 代碼),並建立以下規則,在每次畫面瀏覽時觸發代碼: 等於「openScreen」。如要將畫面名稱傳遞至其中一個代碼,請建立參照資料層中「screenName」鍵的資料層巨集。您也可以建立代碼 (例如 Google Ads 轉換像素),只針對特定畫面檢視觸發,方法是建立規則,其中 等於「openScreen」&& 等於「ConfirmationScreen」。

6. 預覽及發布容器

巨集值一律會對應至目前發布的版本。 發布容器最新版本前,您可以先預覽容器草稿。

如要預覽容器,請在 Google 代碼管理工具網頁介面中產生預覽網址,方法是選取要預覽的容器版本,然後選取 Preview。請儲存這個預覽網址,後續步驟會用到。

預覽網址位於代碼管理工具網頁介面的預覽視窗中
圖 1: 從代碼管理工具網頁介面取得預覽網址。

接著,在應用程式的 AndroidManifest.xml 檔案中新增下列 Activity:

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

在模擬器或實體裝置上開啟連結,即可在應用程式中預覽草稿容器。

準備好讓應用程式使用草稿設定值時,請 發布容器

進階設定

行動裝置專用的 Google 代碼管理工具提供多種進階設定選項,可讓您使用規則根據執行階段條件選取值、手動重新整理容器,以及取得開啟容器的其他選項。下列各節將說明幾種最常見的進階設定。

開啟容器的進階選項

Google 代碼管理工具 SDK 提供多種開啟容器的方法,可讓您進一步控管載入程序:

TagManager.openContainer()

TagManager.openContainer() 是開啟容器的最低階 API,也是最彈性的 API。如果沒有已儲存的容器,或儲存的容器不是最新版本 (超過 12 小時),這個函式會立即傳回預設容器,並從磁碟或網路非同步載入容器。

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

在載入過程中,TagManager.openContainer() 會發出數個生命週期回呼,讓您的程式碼瞭解載入要求何時開始、是否成功 (以及失敗或成功的原因),以及容器最終是從磁碟還是網路載入。

除非應用程式可接受使用預設值,否則您需要使用這些回呼,瞭解已儲存或網路容器何時載入。請注意,如果這是首次執行應用程式,且沒有網路連線,您將無法載入已儲存或網路容器。

TagManager.openContainer() 會將下列 enum 值做為引數傳遞至這些回呼:

RefreshType

說明
Container.Callback.SAVED 重新整理要求會載入本機儲存的容器。
Container.Callback.NETWORK 重新整理要求會透過網路載入容器。

RefreshFailure

說明
Container.Callback.NO_SAVED_CONTAINER 沒有可用的已儲存容器。
Container.Callback.IO_ERROR I/O 錯誤導致容器無法重新整理。
Container.Callback.NO_NETWORK 沒有可用的網路連線。
Container.Callback.NETWORK_ERROR 發生網路錯誤。
Container.Callback.SERVER_ERROR 伺服器發生錯誤。
Container.Callback.UNKNOWN_ERROR 發生無法分類的錯誤。

開啟非預設和全新容器的方法

ContainerOpener 會包裝 TagManager.openContainer(),並提供兩種開啟容器的便利方法:ContainerOpener.openContainer(..., Notifier notifier)ContainerOpener.openContainer(..., Long timeoutInMillis)

這些方法都會採用列舉,要求非預設或新的容器。

OpenType.PREFER_NON_DEFAULT 適用於大多數應用程式,並嘗試在指定逾時期間內,從磁碟或網路傳回第一個可用的非預設容器,即使該容器已超過 12 小時也沒問題。如果傳回過時的已儲存容器,也會發出非同步網路要求,以取得新容器。使用 OpenType.PREFER_NON_DEFAULT 時,如果沒有其他容器可用,或超過逾時時間,系統會傳回預設容器。

OpenType.PREFER_FRESH 會嘗試在指定逾時期間內,從磁碟或網路傳回新的容器。如果網路連線無法使用和/或超過逾時時間,系統會傳回已儲存的容器。

不建議在要求時間較長可能會明顯影響使用者體驗的地方使用 OpenType.PREFER_FRESH,例如 UI 標記或顯示字串。您也可以隨時使用 Container.refresh() 強制發出網路容器要求。

這兩種便利方法都不會造成阻斷。 ContainerOpener.openContainer(..., Long timeoutInMillis) 會傳回 ContainerOpener.ContainerFuture 物件,該物件的 get 方法會在載入後立即傳回 Container (但會封鎖到載入完成為止)。ContainerOpener.openContainer(..., Notifier notifier) 方法會採用單一回呼,在容器可用時呼叫,可用於避免封鎖主執行緒。這兩種方法的預設逾時時間都是 2000 毫秒。

使用規則在執行階段評估巨集

容器可在執行階段使用規則評估值。規則可根據裝置語言、平台或任何其他巨集值等條件設定。舉例來說,規則可用於在執行階段根據裝置語言選取本地化顯示字串。您可以使用下列規則設定這項功能:

系統會根據執行階段的裝置語言選取顯示字串,例如語言等於「es」。這項規則會使用預先定義的語言巨集和雙字元 ISO 639-1 語言代碼。
圖 1:新增規則,僅針對設定使用西班牙文的裝置啟用值收集巨集。

接著,您可以為每種語言建立值集合巨集,並在每個巨集中加入這項規則,插入適當的語言代碼。發布這個容器後,應用程式就能在執行階段根據使用者裝置的語言,顯示本地化顯示字串。

請注意,如果預設容器需要規則,您必須使用二進位容器檔案做為預設容器。

進一步瞭解如何設定規則 (說明中心)。

二進位預設容器檔案

需要規則的預設容器應使用二進位容器檔案,而非 JSON 檔案做為預設容器。二進位容器支援使用 Google 代碼管理工具規則,在執行階段判斷巨集值,但 JSON 檔案不支援。

您可以從 Google 代碼管理工具網頁介面下載二進位容器檔案,並將檔案新增至專案的 /assets/tagmanager/ 資料夾,遵循以下模式:/assets/tagmanager/GTM-XXXX,其中檔案名稱代表容器 ID。

如果同時存在 JSON 檔案和二進位容器檔案,SDK 會將二進位容器檔案做為預設容器。

使用函式呼叫巨集

函式呼叫巨集會設為應用程式中指定函式的傳回值。函式呼叫巨集可用於在 Google 代碼管理工具規則中加入執行階段值,例如根據裝置設定的語言和幣別,在執行階段決定要向使用者顯示的價格。

如要設定函式呼叫巨集,請按照下列步驟操作:

  1. 在 Google 代碼管理工具網頁介面中定義函式呼叫巨集。 引數可視需要設定為鍵/值組合。
  2. 使用 Container.registerFunctionCallMacroHandler() 和您在 Google 代碼管理工具網頁介面中設定的函式名稱,在應用程式中註冊 FunctionCallMacroHandler,並覆寫其 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;
      }
    });

使用函式呼叫代碼

每當事件推送至資料層,且代碼規則評估結果為 true 時,函式呼叫代碼就會執行預先註冊的函式。

如要設定函式呼叫代碼,請按照下列步驟操作:

  1. 在 Google 代碼管理工具網頁介面中定義函式呼叫代碼。 引數可視需要設定為鍵/值組合。
  2. 在應用程式中使用 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.
        }
      }
    });

設定自訂重新整理週期

如果目前的容器已超過 12 小時,Google 代碼管理工具 SDK 會嘗試擷取新的容器。如要設定自訂容器重新整理週期,請使用 Timer,如下列範例所示:

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

使用記錄器偵錯

根據預設,Google 代碼管理工具 SDK 會將錯誤和警告訊息列印至記錄檔。啟用更詳細的記錄功能有助於偵錯,您可以實作自己的 Logger,並使用 TagManager.setLogger 啟用這項功能,如下例所示:

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.

});

或者,您也可以使用 TagManager.getLogger().setLogLevel(LogLevel) 設定現有記錄器的 LogLevel,如以下範例所示:

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