AndroidのmanifestPlaceholdersの使いどころ


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"/>

AndroidManifest.xml(適用後)

  <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>

参考

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です