Android向けにビルドしたUnityアプリをadbコマンドで起動する

# 用途

JenkinsなどのCIでUnityプロジェクトのビルドを行った後、そのアプリをAndroid端末に自動でインストールして自動で起動できれば、テストの自動化など様々な取り組みを行うことができます。

# adbコマンドでUnityアプリを起動する方法

以下のコマンドで起動できます。
```adb shell am start -n <パッケージ名>/<アクティビティ名>```

例：
```shell:
adb shell am start -n com.HogeCompany.HogeProduct/com.unity3d.player.UnityPlayerActivity
```

Unityプロジェクトを新しく作った時のデフォルトのメインアクティビティ名は ```com.unity3d.player.UnityPlayerActivity``` です。メインアクティビティを変更している場合は、コマンドで指定するアクティビティ名を変更してください。

# adbコマンドでUnityアプリを起動する時に引数を渡す方法

インテント引数を指定することで簡単にUnityアプリにデータを渡すことができます。
各型ごとにオプションがあります。
[Android Debug Bridge（adb） - インテント引数の指定](https://developer.android.com/studio/command-line/adb?hl=ja#IntentSpec)

```adb shell am``` ですべての利用できるオプションを確認できます。
上に記載しているリンクのドキュメントにないstring型データの配列用の ```--esa``` オプションもあります。

```shell:
--esn <EXTRA_KEY>
    null エクストラを追加します。

-e | --es <EXTRA_KEY> <EXTRA_STRING_VALUE>
    string 型データを Key-Value ペアとして追加します。

--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE>
    bool 型データを Key-Value ペアとして追加します。

--ei <EXTRA_KEY> <EXTRA_INT_VALUE>
    int 型データを Key-Value ペアとして追加します。

--el <EXTRA_KEY> <EXTRA_LONG_VALUE>
    long 型データを Key-Value ペアとして追加します。

--ef <EXTRA_KEY> <EXTRA_FLOAT_VALUE>
    float 型データを Key-Value ペアとして追加します。

--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]
    int 型データの配列を追加します。

--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]
    long 型データの配列を追加します。

--efa <EXTRA_KEY> <EXTRA_FLOAT_VALUE>[,<EXTRA_FLOAT_VALUE...]
    float 型データの配列を追加します。

--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]
    string 型データの配列を追加します。
```

# adbコマンドで指定された引数をC#で受け取る方法

javaコードを書かなくても簡単なC#コードで指定された引数を取得することができます。

引数を受け取るために、C#コードでAndroidJavaObjectクラスを利用して、IntentのExtraを取得します。
Intentクラスのメソッドは下に記載しているリンクのドキュメントを参照します。
[Intentクラス - パブリックメソッド](https://developer.android.com/reference/android/content/Intent#public-methods_1)

例：
```C#:
AndroidJavaClass UnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
AndroidJavaObject currentActivity = UnityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject intent = currentActivity.Call<AndroidJavaObject>("getIntent");

// 各型の取得サンプル

bool hasNullExtra = intent.Call<bool>("hasExtra", "testNull");
Debug.Log(hasNullExtra ? "has testNull extra" : "no testNull extra");

string stringValue = intent.Call<string>("getStringExtra", "testString", "default string");
Debug.Log("testString: " + stringValue);

bool boolValue = intent.Call<bool>("getBooleanExtra", "testBool", false);
Debug.Log("testBool: " + boolValue.ToString());

int intValue = intent.Call<int>("getIntExtra", "testInt", 0);
Debug.Log("testInt: " + intValue.ToString());

long longValue = intent.Call<long>("getLongExtra", "testLong", 99999999999);
Debug.Log("testLong: " + longValue.ToString());

float floatValue = intent.Call<float>("getFloatExtra", "testFloat", 0.0f);
Debug.Log("testFloat: " + floatValue.ToString());

int[] intArray = intent.Call<int[]>("getIntArrayExtra", "testIntArray") ?? new int[0];
Debug.Log("--- testIntArray ---");
foreach (var val in intArray)
{
    Debug.Log(val);
}

long[] longArray = intent.Call<long[]>("getLongArrayExtra", "testLongArray") ?? new long[0];
Debug.Log("--- testLongArray ---");
foreach (var val in longArray)
{
    Debug.Log(val);
}

float[] floatArray = intent.Call<float[]>("getFloatArrayExtra", "testFloatArray") ?? new float[0];
Debug.Log("--- testFloatArray ---");
foreach (var val in floatArray)
{
    Debug.Log(val);
}

string[] stringArray = intent.Call<string[]>("getStringArrayExtra", "testStringArray") ?? new string[0];
Debug.Log("--- testStringArray ---");
foreach (var val in stringArray)
{
    Debug.Log(val);
}
```

サンプルとして、以下のコマンドを実行します。
```shell:
adb shell am start -n com.HogeCompany.HogeProduct/com.unity3d.player.UnityPlayerActivity ^
--esn "testNull" ^
--es "testString" pineapple ^
--ez "testBool" true ^
--ei "testInt" 77 ^
--el "testLong" 12345678912 ^
--ef "testFloat" 5.67F ^
--eia "testIntArray" 1,2,3,4 ^
--ela "testLongArray" 22222222222,33333333333 ^
--efa "testFloatArray" 1.1F,2.2F,3.3F ^
--esa "testStringArray" apple,orange,melon
```

コマンドの実行結果：
```shell:
has testNull extra
testString: pineapple
testBool: True
testInt: 77
testLong: 12345678912
testFloat: 5.67
--- testIntArray ---
1
2
3
4
--- testLongArray ---
22222222222
33333333333
--- testFloatArray ---
1.1
2.2
3.3
--- testStringArray ---
apple
orange
melon
```