このデベロッパー ガイドでは、モバイルアプリに Google タグ マネージャーを実装する方法について説明します。
はじめに
Google タグ マネージャーを使用すると、デベロッパーは、アプリケーション バイナリを再ビルドしてアプリ マーケットプレイスに再送信しなくても、Google タグ マネージャーのインターフェースからモバイルアプリの設定値を変更できます。
これは、アプリ内で変更が必要になる構成値やフラグを管理するのに役立ちます。次に例を示します。
- さまざまな UI 設定と表示文字列
- アプリ内で配信される広告のサイズ、場所、タイプ
- ゲームの設定
構成値はルールを使用してランタイム時に評価され、次のような動的な構成が可能になります。
- 画面サイズを使用して広告のバナーサイズを決定する
- 言語と地域を使用して UI 要素を設定する
また、アプリにトラッキング タグとピクセルを動的に実装することも可能です。デベロッパーは重要なイベントをデータレイヤーにプッシュし、後でどのトラッキング タグやピクセルを配信するかを決めることができます。 現在、タグ マネージャーでは以下のタグがサポートされています。
- Google モバイルアプリ解析
- カスタムの関数呼び出しタグ
始める前に
このスタートガイドを使用する前に、以下をご用意ください。
- Google タグ マネージャー アカウント
- タグ マネージャーの新しい コンテナと値の収集マクロ
- Google タグ マネージャーを実装するための Android 向けモバイルアプリ
- Google アナリティクス サービス SDK: タグ マネージャー ライブラリが含まれています。
Google タグ マネージャーを初めてご利用になる場合は、このガイドに進む前に、 コンテナ、マクロ、ルールの詳細(ヘルプセンター)を確認することをおすすめします。
はじめに
このセクションでは、タグ マネージャーの一般的なワークフローについて説明します。
- プロジェクトに Google タグ マネージャー SDK を追加する
- コンテナのデフォルトの値を設定する
- コンテナを開く
- コンテナから設定値を取得する
- DataLayer にイベントを push する
- コンテナをプレビューして公開する
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 タグ マネージャーは、アプリケーションの初回実行時にデフォルトのコンテナを使用します。アプリがネットワーク経由で新しいコンテナを取得できるようになるまで、デフォルトのコンテナが使用されます。
デフォルトのコンテナ バイナリをダウンロードしてアプリケーションに追加する手順は次のとおりです。
- Google タグ マネージャーの管理画面にログインします。
- ダウンロードするコンテナのバージョンを選択します。
- [ダウンロード] ボタンをクリックしてコンテナ バイナリを取得します。
- 次のパスにバイナリ ファイルを追加します。
<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 に値を push する
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 }
ウェブ管理画面で、「 が "openScreen" と等しい」というルールを作成して、スクリーン ビューごとに配信されるタグ(Google アナリティクス タグなど)を作成できるようになりました。スクリーン名を上記のタグのいずれかに渡すには、データレイヤーの「screenName」キーを参照するデータレイヤー マクロを作成します。特定のスクリーン ビューに対してのみ配信されるタグ(例: Google 広告コンバージョン ピクセルなど)を作成することもできます。それには、 が「openScreen」と等しい && が「ConfirmationScreen」と等しいルールを作成します。
6. コンテナのプレビューと公開
マクロの値は、現在公開中のバージョンに常に対応しています。 最新バージョンのコンテナを公開する前に、ドラフト コンテナをプレビューできます。
コンテナをプレビューするには、Google タグ マネージャーの管理画面で、プレビューするコンテナのバージョンを選択し、[Preview
] を選択することにより、プレビュー URL を生成します。このプレビュー URL は後の手順で必要になるため、控えておきましょう。
次に、以下のアクティビティをアプリの AndroidManifest.xml
ファイルに追加します。
<!-- 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 です。デフォルトのコンテナとともにすぐに返されます。保存されたコンテナが存在しない場合、または保存されたコンテナが最新でない(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()
をラップし、コンテナを開くための 2 つの便利なメソッド(ContainerOpener.openContainer(..., Notifier notifier)
と ContainerOpener.openContainer(..., Long timeoutInMillis)
)を提供します。
これらのメソッドはそれぞれ、デフォルト以外のコンテナまたは新しいコンテナをリクエストする列挙型を取ります。
ほとんどのアプリケーションでは、OpenType.PREFER_NON_DEFAULT
を指定することをおすすめします。デフォルト以外のコンテナは、作成から 12 時間以上経過していても、ディスクまたはネットワークから特定のタイムアウト時間内に最初のものを返します。古い保存済みコンテナが返された場合は、新しいコンテナに対する非同期ネットワーク リクエストも行われます。OpenType.PREFER_NON_DEFAULT
を使用すると、他のコンテナが使用できない場合、またはタイムアウト時間を超えた場合に、デフォルトのコンテナが返されます。
OpenType.PREFER_FRESH
は、指定されたタイムアウト期間内にディスクまたはネットワークから新しいコンテナを返そうとします。ネットワーク接続が利用できない場合、またはタイムアウト期間を超えた場合、保存済みコンテナを返します。
UI フラグや表示文字列など、リクエスト時間が長いとユーザー エクスペリエンスに明らかな影響が出る可能性がある場所では、OpenType.PREFER_FRESH
を使用しないことをおすすめします。また、Container.refresh()
を使用して、いつでもネットワーク コンテナ リクエストを強制することもできます。
これらの便利なメソッドはどちらも非ブロックです。ContainerOpener.openContainer(..., Long timeoutInMillis)
は ContainerOpener.ContainerFuture
オブジェクトを返します。その get
メソッドは、読み込みが完了するとすぐに Container
を返します(それまではブロックされます)。ContainerOpener.openContainer(..., Notifier notifier)
メソッドは、コンテナが利用可能なときに呼び出される単一のコールバックを受け取ります。これにより、メインスレッドがブロックされるのを防ぐことができます。どちらの方法でも、デフォルトのタイムアウト時間は 2000
ミリ秒です。
ルールを使用したランタイムでのマクロの評価
コンテナはルールを使用して実行時に値を評価できます。ルールは、デバイスの言語、プラットフォーム、その他のマクロ値などの条件に基づいて作成できます。たとえば、ルールを使用することで、実行時のデバイスの言語に基づいてローカライズされた表示文字列を選択できます。これは、次のルールを使用して構成できます。
次に、言語ごとに値コレクション マクロを作成し、このルールを各マクロに追加して、適切な言語コードを挿入します。このコンテナが公開されると、実行時のユーザーのデバイスの言語に応じて、ローカライズされた表示文字列をアプリで表示できるようになります。
デフォルトのコンテナにルールが必要な場合は、デフォルトのコンテナとしてバイナリ コンテナ ファイルを使用する必要があります。
バイナリのデフォルト コンテナ ファイル
ルールが必要なデフォルト コンテナは、デフォルトのコンテナとして JSON ファイルではなく、バイナリ コンテナ ファイルを使用する必要があります。Google タグ マネージャーのルールでは、バイナリ コンテナには実行時にマクロ値を決定できますが、JSON ファイルはサポートされていません。
バイナリ コンテナ ファイルは、Google タグ マネージャーのウェブ インターフェースからダウンロードでき、プロジェクトの /assets/tagmanager/
フォルダに追加して、/assets/tagmanager/GTM-XXXX
というパターンで追加する必要があります。ここで、ファイル名はコンテナ ID を表します。
JSON ファイルとバイナリ コンテナ ファイルが存在する場合、SDK はバイナリ コンテナ ファイルをデフォルトのコンテナとして使用します。
関数呼び出しマクロの使用
関数呼び出しマクロは、アプリ内で指定した関数の戻り値に設定されるマクロです。関数呼び出しマクロを使用すると、ランタイム値を Google タグ マネージャーのルールに組み込めます。たとえば、デバイスに設定されている言語と通貨に基づいて、ユーザーに表示する価格を実行時に決定できます。
関数呼び出しマクロを構成するには:
- Google タグ マネージャーの管理画面で、関数呼び出しマクロを定義します。 引数は必要に応じて Key-Value ペアとして設定できます。
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
と評価されるたびに、事前登録された関数を実行できます。
関数呼び出しタグを構成するには:
- Google タグ マネージャーの管理画面で、関数呼び出しタグを定義します。 引数は必要に応じて Key-Value ペアとして設定できます。
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 はデフォルトでエラーと警告をログに出力します。
詳細ログを有効にするとデバッグに役立ちます。そのためには、次の例のように、TagManager.setLogger
を使用して独自の Logger
を実装します。
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)
を使用して既存の Logger の LogLevel を設定することもできます。
// Change the LogLevel to INFO to enable logging at INFO and higher levels. TagManager tagManager = TagManager.getInstance(this); tagManager.getLogger().setLogLevel(LogLevel.INFO);