Kotlin でも MediaPipe の MultiHandTracking を動かしたい

Kotlin で MediaPipe の MultiHandTracking を利用しているサンプルが無さそうだったので作ってみました。
プログラムは [GitHub](https://github.com/machidyo/MediaPipeHandTracking) に上げてあるので、よかったら参考にしてください。

こんな感じで動きます。
![mutli_hand_tracking_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/65813178-202d-5b69-802b-d7ef0f78b593.gif)
# 作ったと言いながら
元々は[こちら](https://github.com/google/mediapipe/blob/master/LICENSE)の Java のコードを Kotlin に移植したものになります。Kotlin をある程度知っている人なら特に苦労することなく移植できると思います。（自分は素人に毛が生えたようなものなので小一時間ほどは浪費しました・・・） 

# 移植する上での注意
## Java のバージョン指定の追加
そのまま移植すると、こんな感じのエラー（java.lang.NoSuchMethodError: No static method）が出ます。

``` kotlin
    java.lang.NoSuchMethodError: No static method metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite; in class Ljava/lang/invoke/LambdaMetafactory; or its super classes (declaration of 'java.lang.invoke.LambdaMetafactory' appears in /apex/com.android.runtime/javalib/core-oj.jar)
        at com.google.mediapipe.components.CameraXPreviewHelper.startCamera(CameraXPreviewHelper.java:52)
        at com.example.mediapipehandtracking.MainActivity.startCamera(MainActivity.kt:165)
        at com.example.mediapipehandtracking.MainActivity.onResume(MainActivity.kt:102)
        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1465)
        at android.app.Activity.performResume(Activity.java:8203)
        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4757)
        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4810)
        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:52)
        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:190)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:105)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2373)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:213)
        at android.app.ActivityThread.main(ActivityThread.java:8147)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
```

aar を取り込んで入れてるのでそのせいだと思われますが、Java のバージョンを指定することでエラーを回避できます。

``` kotlin
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
```

## gradle.build, AndroidManifest.xml
この辺はしっかり必要なものを設定していないと、ビルドは通るものの、実行時にエラーになったりします。
自分は protobuf のモジュールを違うものを使っていて、ログに問題が出ていると出力されていたものの、
Error ではなく Infoだったので、気付くのに時間掛かりました。

### gradle.build の修正
```
implementation 'com.google.protobuf:protobuf-java:3.11.4'
```

は

```
implementation 'com.google.protobuf:protobuf-lite:3.0.1'
```
にする必要があります。

# コードはこちら
* [MediaPipeHandTracking](https://github.com/machidyo/MediaPipeHandTracking)

# 参考
* [MediaPipe の android_archive_library](https://github.com/google/mediapipe/blob/master/mediapipe/docs/android_archive_library.md) を取り込む手順