build.gradleのbuildTypesとproductFlavors内でmanifestPlaceholdersと変数展開について軽くまとめてみる。
今のところ使った場面は以下の4つです。
- GCMのPermission
- GCMのIntentFilter
- AndroidManifestでSearchRecentSuggestionsProviderの定義
- android:schemeのホスト名
build.gradleを以下のように設定している場合についてそれぞれ説明します。
build.gradle
android {
...
  buildTypes {
    release {
      manifestPlaceholders = [hostName: "epy0n0ff.com"]
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    develop {
      debuggable true
      signingConfig signingConfigs.debug
      manifestPlaceholders = [hostName: "dev.epy0n0ff.com"]
      applicationIdSuffix '.develop'
    }
    local {
      debuggable true
      signingConfig signingConfigs.debug
      manifestPlaceholders = [hostName: "local.epy0n0ff.com"]
      applicationIdSuffix '.local'
    }
    debug {
      debuggable true
      signingConfig signingConfigs.debug
      manifestPlaceholders = [hostName: "dev.epy0n0ff.com"]
      applicationIdSuffix '.debug'
    }
  }
...
}
GCMのPermission
GCMのPermission要素にはapplicationIdを含みます。
buildTypes毎にAndroidManiefst.xmlを用意してもいいのですが、事故を減らすために
main/AndroidManifest.xmlを以下の用に変更します。
AndroidManifest.xml(適用前)
<permission android:name="com.epy0n0ff.develop.permission.C2D_MESSAGE"
      android:protectionLevel="signature"/>
  <uses-permission android:name="com.epy0n0ff.develop.permission.C2D_MESSAGE"/>
</code></pre>
AndroidManifest.xml(適用後)
<pre><code>
<permission android:name="${applicationId}.permission.C2D_MESSAGE"
      android:protectionLevel="signature"/>
  <uses-permission android:name="com.epy0n0ff.develop.permission.C2D_MESSAGE"/>
GCMのIntentFilter
GCMの設定には前項以外にもIntentFilterにapplicationIdが使用されています。
ここもapplicationIdの変数を使うように変更します。
AndroidManifest.xml(適用前)
    <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.develop"/>
      </intent-filter>
    </receiver>
AndroidManifest.xml(適用後)
    <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="${applicationId}"/>
      </intent-filter>
    </receiver>
AndroidManifestでSearchRecentSuggestionsProviderの定義
見落としがちというか気づきにくいのがSearchRecentSuggestionsProviderの定義です。
Logcatで見ていると以下のようなエラーが出るので修正します。
/com.epy0n0ff.develop E/ActivityThread﹕ Failed to find provider info for com.epy0n0ff.content.provider.search
AndroidManifest.xml(適用前)
<provider
        android:name=".content.provider.RecentSearchSuggestionProvider"
        android:authorities="com.epy0n0ff.content.provider.search"
        android:exported="false"
        />
AndroidManifest.xml(適用後)
<provider
        android:name=".content.provider.RecentSearchSuggestionProvider"
        android:authorities="${applicationId}.content.provider.search"
        android:exported="false"
        />
android:schemeのホスト名
ここでやっとmanifestPlaceholdersの登場です。
manifestPlaceholdersはkey-valueのmapなので${key}と書くとそこにvalueが展開されます。
AndroidManifest.xml(適用前)
   <activity
        android:name=".view.activity.UrlInterpreterActivity"
        android:launchMode="singleTask"
        android:noHistory="true">
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data
            android:host="develop.epy0n0ff.com"
            android:pathPattern="/sp/.*"
            android:scheme="http"/>
    </activity>
AndroidManifest.xml(適用後)
    <activity
        android:name=".view.activity.UrlInterpreterActivity"
        android:launchMode="singleTask"
        android:noHistory="true">
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data
            android:host="${hostName}"
            android:pathPattern="/sp/.*"
            android:scheme="http"/>
    </activity>
参考