Flutter Androidの開発環境 切替設定

AndroidのアプリケーションIDとアプリケーション名を
開発環境と本番環境に応じて切り替える設定方法を紹介します。

## .vscodeの設定
プロジェクト直下に`.vscode`フォルダを作り、その中に`launch.json`ファイルを作成する

```launch.json
{
  "configurations": [
    {
      "name": "開発環境デバッグビルド",
      "request": "launch",
      "type": "dart",
      "args": [
        "--dart-define=FLAVOR=dev"
      ]
    },
    {
      "name": "本番環境デバッグビルド",
      "request": "launch",
      "type": "dart",
      "args": [
        "--dart-define=FLAVOR=prod"
      ]
    },
    {
      "name": "開発環境リリースビルド",
      "request": "launch",
      "type": "dart",
      "flutterMode": "release",
      "args": [
        "--dart-define=FLAVOR=dev"
      ]
    },
    {
      "name": "本番環境リリースビルド",
      "request": "launch",
      "type": "dart",
      "flutterMode": "release",
      "args": [
        "--dart-define=FLAVOR=prod"
      ]
    },
  ]
}
```
もっと細かく設定もできるので詳しくは下記参照

https://go.microsoft.com/fwlink/?linkid=830387

## Androidの設定
`android/app/build.gradle`を開いて追記していきます。
※ android/build.gradleと間違えないように注意！

### Dartの環境変数を使用できるようにする おまじない
```build.gradle
// Gradleビルドスクリプト内でDartの環境変数を使用できるようにするための初期設定
def dartEnvironmentVariables = [:];
if (project.hasProperty('dart-defines')) {
    // カンマ区切りかつBase64でエンコードされているdart-definesの値をデコードして変数に格納する。
    dartEnvironmentVariables = dartEnvironmentVariables + project.property('dart-defines')
        .split(',')
        .collectEntries { entry ->
            def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
            [(pair.first()): pair.last()]
        }
}
```
`dart-defines`はlaunch.jsonファイルの`"args": []`内で設定した変数名です。
これの値を`dartEnvironmentVariables`に格納してます。
こうすることで`dartEnvironmentVariables.FLAVOR`がビルドした環境に応じて`dev` or `prod`を出力するようになります。

### アプリケーションIDを切り替える
```build.gradle
android {
    defaultConfig {
        applicationId "com.sample.sample_app"
        minSdkVersion 28
        targetSdkVersion 33
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName

        // prod 以外の場合はアプリケーションIDにフレーバー名を追加
        if (dartEnvironmentVariables.FLAVOR != 'prod') {
            applicationIdSuffix ".${dartEnvironmentVariables.FLAVOR}"
        }
    }
}
```
本番環境以外の場合はアプリケーションIDの末尾にFlavorの値をつけるようにしてます。
つまり今回の例だと
本番環境のときは `com.sample.sample_app`
開発環境のときは `com.sample.sample_app.dev`
となります。
このように分けることで本番環境と開発環境を別々のアプリとしてビルドできるようになります。

### アプリケーション名を切り替える
```build.gradle
android {
    defaultConfig {
        applicationId "com.sample.sample_app"
        minSdkVersion 28
        targetSdkVersion 33
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        if (dartEnvironmentVariables.FLAVOR != 'prod') {
            applicationIdSuffix ".${dartEnvironmentVariables.FLAVOR}"
        }

        // アプリケーション名の設定
        resValue "string", "app_name", "自身のアプリ名" +
            (dartEnvironmentVariables.FLAVOR == 'prod' ? '' : ".${dartEnvironmentVariables.FLAVOR}")
    }
}
```
resValueは、リソース値を定義するためのGradle関数です。
第1引数はリソースの種類
第2引数はリソースの名前
第3引数はリソースの値
を示しています。

今回の例では`app_name`をAndroidアプリケーションの`stringリソース`として
本番環境のときは `自身のアプリ名`、開発環境のときは `自身のアプリ名.dev`となるように値を定義しています。
こうすることでAndroidアプリケーション内のコードやXMLリソースファイルから直接参照することができるようになります。


### アプリケーション名を設定する
`android/app/src/main/AndroidManifest.xml`を開く

```AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:label="@string/app_name"
```
先程build.gradleで定義したリソース値はxmlファイル内では`@string/app_name`で呼び出すことができます。
`android:label`に指定することでビルド環境に応じてアプリ名が切り替わるようになります！


## 参考URL
https://qiita.com/tetsufe/items/29cc779592171dcfb7aa