Google Fitへ栄養データ(PFC)を登録する

## 前書き
仕事で開発しているAndroidアプリにて、栄養データをGoogle Fitへ登録する処理を実装したときの足跡です。
2018年11月現在も、Google Fitアプリで確認できる栄養データはPFCデータのみっぽいので、その３つ＋カロリーを書き込むことにします。

##### PFC = プロテイン(Protein) 脂肪(Fat) 炭水化物(Carbs)

## Client作成
Google APIに接続するクライアントを作成する際に、**History API**の利用と**FITNESS_NUTRITION_READ_WRITE**をScopeに加えることで、栄養価データの読み書きができるようになります。

```java
// クライアント作成
mClient = new GoogleApiClient.Builder(getApplicationContext())
        .addApi(Fitness.HISTORY_API)
        .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ_WRITE))
        .addConnectionCallbacks(
                new GoogleApiClient.ConnectionCallbacks() {
                    @Override
                    public void onConnected(Bundle bundle) {
                        Timber.d("Connect OK");
                        startFitnessCooper();
                    }

                    @Override
                    public void onConnectionSuspended(int i) {
                        // If your connection to the sensor gets lost at some point,
                        // you'll be able to determine the reason and react to it here.
                        if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
                            Timber.i("Connection lost.  Cause: Network Lost");
                        } else if (i
                                == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
                            Timber.i("Connection lost.  Reason: Service Disconnected");
                        }
                        cleanFitnessClient();
                    }
                }
        )
        .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
            @Override
            public void onConnectionFailed(ConnectionResult result) {
                Timber.i("Google Play services connection failed. Cause: " + result.toString());
                cleanFitnessClient();
            }
        })
        .build();

// 接続
mClient.connect();
```

## PFC書き込み
予めPFCデータを用意しておき、非同期で書き込みする。
ここではNutritionEntityに栄養データが格納されていると仮定。
なお、登録データには何かしらの名前をつけてあげる必要があるため、とりあえず年月日(ymd)を使います。

```java
private class InsertAndVerifyDataTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... params) {
        // 栄養価をGoogleへ書き込む
        updateFitnessDataNutrition(mYmd, mRecordNutritionValueEntity);
        return null;
    }
}

private void updateFitnessDataNutrition(String ymd, NutritionEntity entity) {
    DataSource dataSource = new DataSource.Builder()
            .setAppPackageName(getPackageName())
            .setDataType(DataType.TYPE_NUTRITION)
            .setName(ymd)
            .setType(DataSource.TYPE_RAW)
            .build();

    DataPoint dataPoint = DataPoint.create(dataSource);
    dataPoint.setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
    dataPoint.getValue(Field.FIELD_FOOD_ITEM).setString("Asken Diet"); // アプリ名などを記載しておくとgoogle fitアプリでデータ元みたいに表示される

    float calorie = entity.values.calorie.val;
    float protein = entity.values.protein.val;
    float fat = entity.values.fat.val;
    float carbs = entity.values.carbohydrate.val;

    // 摂取カロリー (kcal)
    dataPoint.getValue(Field.FIELD_NUTRIENTS).setKeyValue(Field.NUTRIENT_CALORIES, calorie);
    // タンパク質（g）
    dataPoint.getValue(Field.FIELD_NUTRIENTS).setKeyValue(Field.NUTRIENT_PROTEIN, protein);
    // 脂肪（g）
    dataPoint.getValue(Field.FIELD_NUTRIENTS).setKeyValue(Field.NUTRIENT_TOTAL_FAT, fat);
    // 炭水化物（g）
    dataPoint.getValue(Field.FIELD_NUTRIENTS).setKeyValue(Field.NUTRIENT_TOTAL_CARBS, carbs);
    
    DataSet dataSet = DataSet.create(dataSource);
    dataSet.add(dataPoint);

    DataUpdateRequest request = new DataUpdateRequest.Builder()
            .setDataSet(dataSet)
            .setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
            .build();

    Status updateStatus = Fitness.HistoryApi.updateData(mClient, request).await(1, TimeUnit.MINUTES);
    if (!updateStatus.isSuccess()) {
        Timber.i("There was a problem inserting the dataset nutrition");
    }
}

```
なお、手元で開発してみたかぎりでは、**必ずカロリーも書き込みてあげないとGoogle Fitアプリがクラッシュします。**

##Google Fitアプリで登録データ確認
正常に栄養データ登録が完了すると、Google FitアプリでPFCデータが確認できます。
<img src="https://qiita-image-store.s3.amazonaws.com/0/103992/9baf3ea3-06ee-bc46-c8e3-1f20e6fdbb10.png" width="300px" />