F.O.X Android SDK バージョン3系から4系に乗り換える

こんにちは。F.O.X開発の中の人、ガーヒラです。これからすこしボヤきます。
F.O.X Android SDK バージョン３系は、その昔先人たちにより秘伝のタレが継ぎ足して伝統が守られてきました。その中にはApacheHttpClientが含まれ、メインスレッドでの実行制約もあります。バージョン４をリリースし１年が経ち導入実績も増えており、３系から4系への移行についての質問も増えているので, バージョン４にマイグレーションする際に困らなくても良いように手順を紹介します。

## 何が変わったのか？

以下の３点を心掛けました。

* **記述するステップ数を減らす**<br><br>出来るだけコピペで済むように。且つ、計測系SDKの導入になんか時間を使ってられないエンジニアが楽になるように。<br>
<br>
* **各成果地点での計測で引数にContextが不要にする**<br><br>最初のアクティベーション処理を実行すれば、内部でApplicationContextを保持するので、以後、各所で実装するAPIの引数にContextが不要となります。
故に、アプリ内イベントを計測する実装では、Activityのしがらみから開放され純粋にイベント計測に必要な値だけを引数に指定すればよくなりました。  
<br>
* **クラス名とメソッド名から何をするものかがわかるようにするｗ**<br><br>当たり前で非常に恥ずかしいですが、前バージョンまではそれが出来ていませんでした。<br>（バージョン４からは秘伝のタレを捨てました。）


## 1. SDKの入れ替え

アプリのbuild.gradleのdependenciesを以下のように変更します。まずは書き換えてしまいましょう！古いバージョンを混在させてしまうと正しい計測値が得られない可能性が出てきます。まずは以下のdependenciesの古い記述を削除しGradleSyncとビルドを実行。ビルドエラーが発生した箇所を直して行きます。


**[削除]**

```
compile 'co.jp.cyberz.fox:sdk-android:3.X.X'
```

**[追加]**

```
compile 'co.cyberz.fox:track-core:4.4.0'
```

※ 本記事掲載時期の最新バージョンは4.4.0です。
※ jarファイルで導入している場合は、libsディレクトリのFOX_Android_SDK_3.X.X.jarを削除し、上記の[追加]を設定します。

## 2. 基本設定の変更

AndroidManifest.xmlに設定していた内容を更新します。
これまでAndroidManifest.xmlに記述していた以下のmeta-dataの設定箇所が不要となり、Application継承クラスのonCreate内での設定となります。

**[削除]**

```xml
<meta-data
    android:name="APPADFORCE_APP_ID"
    android:value="1234" />
<meta-data
    android:name="APPADFORCE_SERVER_URL"
    android:value="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" />
<meta-data
    android:name="APPADFORCE_CRYPTO_SALT"
    android:value="YYYYYYYYYYYYYYYYYYYYYYYYYY" />
<meta-data
    android:name="ANALYTICS_APP_KEY"
    android:value="ZZZZZZZZZZZZZZZZZZZZZZZZZZ" />
```

**[必須パラメータの設定箇所]**

|必須パラメータ|〜3.7.1|4.0.0〜|
|:---:|:---:|:---:|
|APPADFORCE_APP_ID|AndroidManifest.xml|Application継承クラス内|
|APPADFORCE_SERVER_URL|AndroidManifest.xml|不要|
|APPADFORCE_CRYPTO_SALT|AndroidManifest.xml|Application継承クラス内|
|ANALYTICS_APP_KEY|AndroidManifest.xml|Application継承クラス内|


## 3. 計測APIの置き換え

広告効果計測APIのマイグレーションを行います。主要な実装の置き換えを紹介します。

### 3.1 アクティベーション

前項のAndroidManifest.xmlに記述していたmeta-dataの内容をApplication継承クラスのonCreate内で実装します。

```java
public class YourApplication extends Application {

  private int FOX_APP_ID      = 1234;
  private String FOX_APP_KEY  = "XXXXXXXXXXXXXXXXXXX";
  private String FOX_APP_SALT = "YYYYYYYYYYYYYYYYYYY";

  @Override
  public void onCreate() {
    super.onCreate();

    FoxConfig config = new FoxConfig(this, FOX_APP_ID, FOX_APP_KEY, FOX_APP_SALT);
    config.addDebugOption(BuildConfig.DEBUG)
          .activate();
  }

}
```

> ※ FOX_APP_ID, FOX_APP_KEY, FOX_APP_SALTは国別にアプリのバイナリを分けるケースやAndroidTV版と分けるケースなどを考慮し、Flavor別に管理し、BuildConfigから呼び出すのも効果的です。

### 3.2 インストール計測

ベーシックなケース。
AdManagerクラスでの実装は削除し、Foxクラスで実装するよう変更します。

[3.X.X]

```java
@Override
public void onCreate() {
  super.onCreate();

  AdManager ad = new AdManager(this);
  ad.sendConversion("default");
}
```

[4.X.X]

引数にはContextも不要となりコピペで良くなりました。

```java
@Override
public void onCreate() {
  super.onCreate();

  Fox.trackInstall();
}
```

---

細かなオプションを指定しているケース。この実装は、初回起動時の成果送信に以下を実行する例となります。

* Buid(アプリ内ユーザーID)を指定する
* 成果送信後に `https://www.hogehoge.com`へリダイレクトさせる
* 成果送信完了のコールバックを受け取る(onComplete)


[3.X.X]

```java
@Override
public void onCreate() {
  super.onCreate();

  AdManager ad = new AdManager(this);
  ad.setTrackingStateListener(new TrackingStateListener() {

    @Override
    public void onComplete() {
      Toast.makeText(this, "tracking complete", Toast.LENGTH_LONG).show();
    }
  });
  ad.sendConversion("https://www.hogehoge.com", "BUID_001");
}
```

[4.X.X]

バージョン4に置き換えると以下の実装となり、実装ステップ数はさほど変わらないですがチェーンで実装できるようにしてあります。

```java
@Override
public void onCreate() {
  super.onCreate();

  FoxTrackOption option = new FoxTrackOption();
  option.addRedirectUrl("https://www.hogehoge.com")
        .addBuid("BUID_001")
        .setTrackingStateListener(new TrackingStateListener() {

          @Override
          public void onComplete() {
            Toast.makeText(this, "tracking complete", Toast.LENGTH_LONG).show();
          }
        });
  Fox.trackInstall(option);
}
```

### 3.3 セッション計測

[3.X.X]

単なるセッション計測なのに長いクラス名と長いメソッド名に加え引数を設定します。

```java
@Override
public void onResume() {

  AnalyticsManager.sendStartSession(this);

}
```

[4.X.X]

次のように置き換えます。何のライブラリが何を行う処理なのか分かるものとなりました。

```java
@Override
public void onResume() {

  Fox.trackSession();

}
```

### 課金イベント計測

[3.X.X]

LTV成果計測とアクセス解析の２つの計測があるせいで実装量が多く、混乱も招きました。
9.99ドルの課金を計測するだけにこのザマです。。

```java
// LTV計測による課金計測
AdManager ad = new AdManager(getContext());
LtvManager ltv = new LtvManager( ad );
ltv.addParam(LtvManager.URL_PARAM_PRICE, "9.99");
ltv.addParam(LtvManager.URL_PARAM_CURRENCY, "USD");
ltv.sendLtvConversion( 成果地点ID );

// アクセス解析による課金計測
AnalyticsManager.sendEvent(Context, "イベント名", action, null, null, orderId, sku, itemName, 9.99, 1, "USD");
```


[4.X.X]

勇気を出し、秘伝のタレは捨てることを誓った結果、多少はシンプルに書けるようにはなりました。
ただ、3系で実装していた`イベント名`と`成果地点ID`はそのまま入れてください。集計の関係上、整合が取れなくなってしまいます。

```java
FoxEvent event = new FoxEvent("イベント名", 成果地点ID);
event.price = 9.99;
event.currency = "USD";
Fox.trackEvent(event);
```


### その他の変更前後

前項では記載しなかったAPIの対応表となります。

|種別| `〜 3.X.X` の実装 | `4.0.0 〜` の実装|
|:---:|:---|:---|
|[リエンゲージメント計測](../../README.md#tracking_reengagement)|AdManager ad = new AdManager( Context );<br>ad.sendReengagementConversion(Intent);|[Fox](../sdk_api/README.md#fox).trackDeeplinkLaunch(Intent);|
|[外部ブラウザでイベント計測](../track_events/README.md#track_by_browser)|AdManager ad = new AdManager(this);<br>LtvManager ltv = new LtvManager(ad);<br>ltv.ltvOpenBrowser("*http://yourhost.com/*");|[Fox](../sdk_api/README.md#fox).trackEventByBrowser("*http://yourhost.com/*");|
|[アプリ内WebViewでイベント計測](../track_events/README.md#track_by_webview)|AdManager ad = new AdManager(*Context*);<br>LtvManager ltv = new LtvManager(ad);<br>WebView mWebView = (WebView) findViewById(R.id.webview);<br>ltv.setLtvCookie(mWebView);<br>webView.loadUrl("*http://yourhost.com/*");|WebView webView = (WebView) findViewById(R.id.webview);<br>[Fox](../sdk_api/README.md#fox).trackEventByWebView(webView);<br>webView.loadUrl("*http://yourhost.com/*");|
|[イベント計測<br>(チュートリアル完了)](../../README.md#tracking_event_tutorial)|AnalyticsManager.sendEvent(Context, "*チュートリアル完了*", null, null, 1);|[FoxEvent](../sdk_api/README.md#foxevent) event = new [FoxEvent](../sdk_api/README.md#foxevent)("*チュートリアル完了*");<br>[Fox](../sdk_api/README.md#fox).trackEvent(event);|


## 4. その他

### 4.1 Proguardの設定

[3.X.X]

以下の記載は削除してください。

```
-keepattributes *Annotation*
-libraryjars libs/AppAdForce.jar
-keep interface jp.appAdForce.** { *; }
-keep class jp.appAdForce.** { *; }
-keep class jp.co.dimage.** { *; }
-keep class com.google.android.gms.ads.identifier.* { *; }
-dontwarn jp.appAdForce.android.**
-dontwarn jp.co.dimage.**
-dontwarn jp.co.cyberz.fox.**
-dontwarn com.adobe.fre.**
-dontwarn com.ansca.**
-dontwarn com.naef.jnlua.**
```

[4.X.X]

その代わり、以下を記載します。

```
-keepattributes *Annotation*
-keep class co.cyberz.** { *; }
-keep class com.google.android.gms.ads.identifier.* { *; }
-dontwarn co.cyberz.**
```

### 4.2 BroadcastReceiverの複数指定と共存

インストールリファラー計測を行うために以下のreceiver指定は必須となっていました。
しかし、他ツールのreceiverも指定すると記述量が増えてしまったり他の予期せぬ事象が発生したりと推奨できませんでした。

```xml
<receiver
    android:name="jp.appAdForce.android.InstallReceiver"
    android:exported="true">
    <intent-filter>
        <action android:name="com.android.vending.INSTALL_REFERRER" />
    </intent-filter>
</receiver>
```

バージョン4.0.0〜は上記のreceiverと、以下のmeta-dataタグを宣言しても貰えれば、valueに他ツールのReceiverクラス名をパッケージ付きで指定してもらえればContextとIntentを転送します。
複数設定する場合には、|(パイプ)区切りで記述します。

```xml
<meta-data
        android:name="APPADFORCE_FORWARD_RECEIVER"
        android:value="com.hoge.InstallReceiver|jp.co.hohoge.InstallReceiver|com.example.InstallReceiver" />
```


全体的に実装のお手間を微弱ですが減らしました。(つもり)
どうぞよろしくお願い致します。