Google Tag Manager for Android でABテストをする - その２ アプリでABを出し分ける

# はじめに
この記事は、[Google Tag Manager for Android でABテストをする - その１ テストの公開](http://qiita.com/ara_tack/items/7e8d36c8131d14106fab)の続きです。

以下の方法を説明したいと思います。

1. Google Tag Manager (GTM) を用いたモバイルのABテストを開始する
2. Google Tag Manager for Android でアプリにABの出し分けを実装する

この記事では、2の説明をしたいと思います。

また、この記事のサンプルアプリを
https://github.com/takuaraki/AB-Sample-for-Android
に載せてあります。

# Google Tag Manager for Android でABの出し分け
## 前提条件
以下のパターンの Google アナリティクスウェブテストが入った Google Tag Manager のコンテナを公開していること。

| パターン名 | 値               |
|----------|------------------|
| パターンA | {'pattern': 'A'} |
| パターンB | {'pattern': 'B'} |

この方法は、[前の記事](http://qiita.com/ara_tack/items/7e8d36c8131d14106fab)を参考にしてください。

## 大まかな手順
1. コンテナのバイナリファイルをアプリに追加する
2. Google Tag Manager を導入する
3. Google Tag Manager を初期化する
4. パターンの値を取得してABを出し分ける

1のみブラウザでの作業があります。他は全て Android Studio での作業です。

## コンテナのバイナリファイルをアプリに追加する
コンテナ画面を開き、最終公開の「公開されたバージョンを表示」をクリックします。

![スクリーンショット 2016-03-13 21.18.51.png](https://qiita-image-store.s3.amazonaws.com/0/98669/126e9ee2-004d-bba4-a78c-67d1ed141684.png)

バージョンの詳細画面になるので、右上の「アクション」をクリックしてから、「ダウンロード」を選択します。

![スクリーンショット 2016-03-13 21.17.36.png](https://qiita-image-store.s3.amazonaws.com/0/98669/dd504820-138b-641b-66ca-a1119291c062.png)

すると、GTM-XXXXXX（コンテナ名と一致）という名前のバイナリファイルがダウンロードされます。このファイルを Android Studio のプロジェクトの `res/raw` フォルダ内に置きます。ここで注意するのがプロジェクトに置くときのファイル名で、小文字またはアンダースコア以外の文字が含まれている場合はビルド時にエラーになります。そこで、この記事では `gtm_default_container` というファイル名に変更しました。

## Google Tag Manager を導入する
### パーミッションの設定
以下のパーミッションを `AndroidManifest.xml` に追加してください。

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

### Gradle スクリプトの設定
アプリの `build.gradle` の `dependencies` に以下を追加してください。

``` groovy
compile 'com.google.android.gms:play-services-analytics:8.4.0'
```

[公式ドキュメント](https://developers.google.com/tag-manager/android/v4/#add)には、Google Play Services SDK を使うように書いていますが、Google Analytics のライブラリだけで十分です。

## Google Tag Manager を初期化する。
アプリの初期化処理を行う場所で、Google Tag Manager を初期化するのがよいと思います。ここでは、スプラッシュ画面のActivityで初期化を行います。

``` java
// change this value to your container id
private static final String CONTAINER_ID = "GTM-XXXXXX";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash);

    // initializing Google Tag Manager
    TagManager tagManager = TagManager.getInstance(this);
    PendingResult<ContainerHolder> pending = tagManager.loadContainerPreferNonDefault(CONTAINER_ID, R.raw.gtm_default_container);
    pending.setResultCallback(new ResultCallback<ContainerHolder>() {
        @Override
        public void onResult(ContainerHolder containerHolder) {
            ContainerHolderSingleton.setContainerHolder(containerHolder);
            if (!containerHolder.getStatus().isSuccess()) {
                Log.e(TAG, "failure loading container");
                displayErrorToUser(R.string.load_error);
                return;
            }
            startMainActivity();
        }
    }, 2, TimeUnit.SECONDS);
}
```

`CONTAINER_ID` は自分のコンテナのIDに、`gtm_default_container` は `res/raw` に置いたバイナリファイル名に適宜置き換えてください。

また、`ContainerHolderSingleton` は、 `ContainerHolder` を保持するシングルトンクラスです。このクラスの`getContainerHoler()`メソッドを利用すれば、同一の `ContainerHolder` インスタンスを参照することができます。

``` java
public class ContainerHolderSingleton {
    private static ContainerHolder containerHolder;

    private ContainerHolderSingleton() {
    }

    public static ContainerHolder getContainerHolder() {
        return containerHolder;
    }

    public static void setContainerHolder(ContainerHolder c) {
        containerHolder = c;
    }
}
```

## パターンの値を取得してABを出し分ける
初期化が終わったら、いよいよABの出し分けです。肝となるコードは、

``` java
containerHolder.getContainer().getString("key");
```

です。このコードを使えばキーに対応した `String` の値を取得することができます。また、`getBoolean(String key)` や `getLong(String key)` メソッドで `boolean` や `long` の値を取得することもできます。

今回は、メイン画面を以下のように作りました。

``` java
public class MainActivity extends AppCompatActivity {
    private static final String KEY_PATTERN = "pattern";

    private static final String PATTERN_A = "A";
    private static final String PATTERN_B = "B";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        TextView textView = (TextView) findViewById(R.id.textView);

        // A と B の出し分け
        ContainerHolder containerHolder = ContainerHolderSingleton.getContainerHolder();
        String pattern = containerHolder.getContainer().getString(KEY_PATTERN);
        switch (pattern) {
            case PATTERN_A:
                textView.setText("A");
                textView.setBackgroundColor(Color.MAGENTA);
                break;
            case PATTERN_B:
                textView.setText("B");
                textView.setBackgroundColor(Color.CYAN);
                break;
        }
    }
}
```

前提条件で載せたパターンの表を再掲すると、

| パターン名 | 値               |
|----------|------------------|
| パターンA | {'pattern': 'A'} |
| パターンB | {'pattern': 'B'} |

となっています。コンテナのウェブテストによって、パターンAかパターンBのうち、どちらかがユーザーごとに適用されます。パターンAが適用された場合は `textView` に「A」がセットされて背景がマゼンダになり、パターンBが適用された場合は `textView` に「B」がセットされて背景がシアンになります。今回はパターンの値をフラグのように使っただけでしたが、出すべきテキストや色の情報などをパターンに入れてそのまま出すということもできると思います。

# おわりに
以上で、Google Tag Manager を用いたABの出し分けができました。一応ここで区切りはつきましたが、この時点だとまだ効果的なウェブテストはできないと思います。Google Tag Manager でテストの目標や有効化トリガーを設定する方法なども、自分で試してみて余力があれば記事も書いてみたいです。この記事が、これからアプリでABテストをする方の足がかりになれば幸いです。

# 参考にした記事
- [Google Tag Manager for Android](http://qiita.com/sis-yoshiday/items/49c5f5e855a255c98fd6)