下書きに残っていたのでちょっと古めな記事です。
productFlavorsが扱い易くなったよ
Android Studioが*.gradleファイルを読み込んでくれるようになってproductFlavorsを
build.gradleを直接編集することなく扱えるようになりました。
これを使えばpackageNameのsuffixにstagingやdevelopを付けて環境別のアプリを同一端末に入れることができる。
AndroidManifest.xmlは書き換えてくれない
ビルドシステムがgradleに切り替わってからAndroidManifestの依存度が少しずつ低くなってきています。
compileSdkVersionやminSdkVersionやtargetSdkVersionはgradleのほうが優先されます。
これで一度痛い目を見ました。
また、productFlavorsで書き換えられるのはAndroidManifestの上部にあるpackage="com.epy0n0ff"
あたりだけのようです。
ソースコードパッケージ名とアプリケーションパッケージ名は別扱いのため、アプリケーションパッケージ名を使うGCMのパーミッションもproductFlavorsを変えただけでは書き換わってくれません。
どうするよ
よーし、パパsedで書き換えちゃうぞー。
# GCM周りをパッケージ名に合わせて書き換え
# <permission>と<uses-permission>タグ
sed -i -e 's/com.epy0n0ff.permission.C2D_MESSAGE/com.epy0n0ff.develop.permission.C2D_MESSAGE/g' ./Hatrakitakunai/src/main/AndroidManifest.xml
# <intent-filter>内の<category>タグ
sed -i -e 's/android:name="com.epy0n0ff"/android:name="com.epy0n0ff.develop"/g' ./Hatarakitakunai/src/main/AndroidManifest.xml
# アプリ名も変更
sed -i -e 's/android:label="@string\/app_name"/android:label="Hatarakitakunai develop"/g' ./7gogo/src/main/AndroidManifest.xml
よし、これでいける!と思ったがそうはいかなかった。
GCMレシーバクラスをデフォルトのままにしているとGCMIntentService
クラスもアプリケーションパッケージ名に影響を受けてcom.epy0n0ff.develop.GCMIntentService
を呼び出してしまいます。
レシーバーをカスタム
対策方法としてはGCMReceiver
を継承したクラスを作りパッケージ名を含めたクラス名を渡してやる必要があります。
public class GCMReceiver extends GCMBroadcastReceiver {
@Override
protected String getGCMIntentServiceClassName( Context context ) {
return GCMIntentService.class.getCanonicalName();
}
}
また、AndroidManifestのほうはデフォルトのレシーバクラスなので追加したものに変更します。
<service android:name="com.epy0n0ff.GCMIntentService"/>
<receiver
android:name="com.epy0n0ff.GCMReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.epy0n0ff"/>
</intent-filter>
</receiver>
これで無事GCMへの登録ができ、環境別のアプリをビルドできるようになりました。