Android StudioでProduct Flavorを使う

#経緯
Eclipseで作成していた某アプリをAndroid Studioに移行するにあたり今まで別々のプロジェクトとして管理していた通常版とデモ版を1つのプロジェクトで管理したくなったので、その時に色々と試した結果を備忘録がてらまとめてみます。

#基本情報
[Configuring Gradle Builds](http://developer.android.com/intl/ja/tools/building/configuring-gradle.html)

#環境
Android Studio 2.0 Preview 4

#作業手順

##Android Studioへのインポート
1. 通常版のプロジェクトを[File] > [New] > [Import project] でAndroid Studioにインポートします。[^1]

[^1]: デモ版のプロジェクトはインポートする必要はありません。

##build.gradle(Modle:app)の編集(その1)
Project Structuresから修正するのが王道(?)。

1. [File] > [Project Structure]を開く。
1. [Modules] > [app]を開く。
1. [Flavors]を開く。
1. 画面下部の+ボタンをクリックして、Flavorを追加する。
1. 「Name」に任意の名前をつける。
1. 「ApplicationId」を指定する。
1. OKボタンをクリックして保存する。

build.gradleを直接書き換えて、下記のように「productFlavors」を追加してもOK。~~と言うか、こっちの方が速い。~~


```
android {
  (略)
  productFlavors {
      regular {
          applicationId "com.foo.bar"
      }
      demo {
          applicationId "com.foo.bar.demo"
      }
  }
}
```

###[メモ]
+ 未指定の箇所は「defaultConfig」の設定値が使用されるので、とりあえずはNameとApplicationIdの指定だけでとりあえずOK。
+ 通常版とデモ版の2つのAPKを作りたい場合、それぞれのFlavorを登録する必要があります。"defaultConfig"が通常版として使えるのかと思って、デモ版用のFlavorしか作らなかったら、デバッグとか、APK作成とかの際にデモ版しか作れず、しばらく悩みました。

##デモ版用ソースコードの追加
1. srcフォルダを右クリックして、[New] > [Directory]をクリック。
1. 「directory name」に「demo」と入力し、OKボタンをクリック。
1. demoフォルダを右クリックして、[New] > [Folder] > [Java Folder]をクリック。
1. Finishボタンをクリック。
1. 必要に応じて、res等のフォルダも追加する。
1. demoフォルダの下にあるjavaフォルダを右クリックして[New] > [Package]をクリック。[^2]
1. デモ版に必要なコードを追加する(Eclipseのデモ版プロジェクトからコピーすればOK)。[^3]
1. プロジェクトのsrcフォルダを右クリックして、通常版用のフォルダ(regular)を追加。[^4]

変更後のプロジェクトの構造は下記のようになります。

```
<通常版のみ>                    <通常版+デモ版>
プロジェクト名                  プロジェクト名
  ┗━app                         ┗━app
     ┗━src                         ┗━src
        ┗━main                        ┣━demo
           ┣━java                     ┃  ┣━java
           ┗━res                      ┃  ┗━res
                                      ┣━main
                                      ┃  ┣━java
                                      ┃  ┗━res
                                      ┗━regular
```

[^2]: ここでPackageが選択できない場合は、Android Studioのウィンドウの左端の下の方にある「Build Variants」を開いて「app」を「demo***」(DebugでもReleaseでも)に変更してみます。それでもダメなら、パッケージと同じになるようにDirectoryで作っていけばOK。

[^3]: マージされるので、通常版と共通のコードは追加しなくて大丈夫。

[^4]: 本来はregularフォルダの下に通常版用のコード類を置くんだと思いますが、今回はmain配下に配置したので、javaフォルダなどは作りませんでした。regularフォルダには、後でAndroidManifest.xmlだけを配置します。

##Android Manifestの追加
**Android Manifestはマージされる。**
**Android Manifestはマージされる。**

大事なことなので2回言いました。最初これを理解していなかったせいで、通常版とデモ版2つのアイコンが出たりして、かなり悩みました。

結論から言うと、通常版とデモ版、それに共通部分の3つのManifestを作りました。

なお、やり方によっては2つでも行けます(後述)が，Manifestが見辛くなるのでお勧めできません。

###通常版とデモ版の差異

Android Manifestの追加・修正内容はアプリの内容により異なってくるかと思います。今回の場合、通常版とデモ版では下記のような差異がありますので、ここに記載する内容はこの差異に沿った内容です。

+ 起動時のActivityが異なる。
+ サービス等一部のコンポーネントが異なる。
+ 広告表示に必要なパーミッションが追加される。
+ ライセンス認証は行わないので、CHECK_LICENSEパーミッションは削除する。
+ アプリ名が異なる。

###共通Manifest
1. mainフォルダ内のAndroidManifest.xmlを開く。
1. 通常版とデモ版の両方に共通しないコンポーネント(activity、service、receiver、provider、uses-permission等)に関する記述を削除。

###通常版Manifest
1. regularフォルダを右クリックして、[New] > [Other] > [Android Manifest]を開く。
1. Finishボタンをクリック。
1. 作成されたregular/AndroidManifest.xmlを開く。
1. 通常版にのみ存在するコンポーネントに関する記述を追加。

今回は、``<uses-permission android:name="com.android.vending.CHECK_LICENSE"/>``を追加し、通常版起動時のActivityや、差異のあるコンポーネントを追加しました。

###デモ版Manifest
1. demoフォルダを右クリックして、[New] > [Other] > [Android Manifest]を開く。
1. Finishボタンをクリック。
1. 作成されたregular/AndroidManifest.xmlを開く。
1. 通常版にのみ存在するコンポーネントに関する記述を追加。
1. manifestタグ内に``xmlns:tools="http://schemas.android.com/tools"``を追加。
1. applicationタグ内の「android:label」をデモ版用のアプリ名に変更。
1. applicationタグ内に``tools:replace="android:label"``を追加。

今回は、広告表示に必要なパーミッションを追加し、デモ版起動時のActivityや、差異のあるコンポーネントを追加しました。

また、``android:label``を書き換えただけでは競合しているというエラーが出るので、``tools:replace="android:label"``を設定して競合を解消してやります。

###[メモ]
+ マージ後のManifestは「AndroidStudio_workspace/プロジェクト/app/build/intermediates/manifests/full」配下に出力されます。

###通常版のManifestを作らない方法
[Manifest Merging](http://developer.android.com/intl/ja/tools/building/manifest-merge.html)を斜め読みして最初に試した方法がコチラ。

mainフォルダ配下のAndroidManifest.xmlに通常版+共通コンポーネントの記述を全て書いて、demoフォルダ配下のAndroidManifest.xmlで不要なコンポーネントのタグに``tools:node='remove'``を追加して削除します(もちろんデモ版で必要なコンポーネントの記述も追加する)。

ただ、やってみると分かりますが、Manifestがとっても読みにくくなります。

##build.gradle(Module:app)の編集(その2)
ここまでの内容と、デモ版に必要な設定をbuild.gradleに反映します。多分一部は反映されているハズです。

###デモ版のソースコードの位置指定
上記の手順でやっている場合は、作業しなくても反映されているハズですが、念のため。

1. build.gradle(Module: app)を開く。
1. sourceSetsに以下の記述を追加する。[^5]

```
sourceSets {
    main {
      (略)
    }
    demo {
        java.srcDirs = ['src/demo/java']
        res.srcDirs  = ['src/demo/res']
    }
}
```

[^5]: 今回通常版のソースをregularに置かなかったので、mainにはjava.srcDirs、res.srcDisの記載はなくても大丈夫。

###広告表示用ライブラリの追加
デモ版だけで広告表示用のライブラリを使用するように設定します。

1. build.gradle(Module: app)を開く。
1. dependenciesに以下の記述を追加(libs/ads.jarは広告表示用のライブラリ)。

```
dependencies {
    (略)
    demoCompile files('libs/ads.jar')
}
```

###デモ版用Proguardの設定
広告ライブラリに対応するため、デモ版は通常版とは異なるProguard設定を使用しました。

1. build.gradle(Module: app)を開く。
1. productFlaveorsに以下の記述を追加。

```
productFlavors {
    regular {
    　　(略)
    }
    demo {
        (略)
        proguardFile('proguard-rules_demo.so')
    }
}
```

###バージョン名の変更
アプリ名と合わせて、バージョン名も変更しました。

1. build.gradle(Module: app)を開く。
1. productFlaveorsに以下の記述を追加。


```
productFlavors {
    regular {
        (略)
        versionName "1.0.0"
    }
    demo {
        (略)
        versionName "1.0.0(demo)"
    }
}
```

##実行と署名付きAPKの作成

###実行
デモ版と通常版の切り替えは「Build Variants」で行えます。

1. Android Studioのウィンドウの枠の左下部にある「Build Variants」をクリック(画像参照)。
1. 「app」で起動したいBuild variantを選択。
1. 実行ボタンをクリックして実行。

![スクリーンショット 2015-12-27 1.26.45.png](https://qiita-image-store.s3.amazonaws.com/0/107120/a180c009-734e-0f1a-8e12-a3ea6e1e39c4.png)

###署名付きAPKの作成
最後に作成したいFlavorを選択するだけで、他は何も変わりません。

署名を変えたい場合は、build.gradleで使用する署名を指定するらしいです(未確認)。
(参考)[Signing Your Applications](http://developer.android.com/intl/ja/tools/publishing/app-signing.html)

#更新履歴
2015/12/25 初版