Gradle and GCM project integration

又到了難纏的狀況, 跟之前 Google Maps 的狀況很類似, 不過這次需要支援的檔案為 AndroidManifest.xml

GCM 需要在 AndroidManifest.xml 中設定權限, 而這個權限又得跟著 package name 跑, 所以不同的 flavour & buildType 就會有不同的設定值. 但問題是 gradle 並不支援 flavourBuildType (比如 amazonFreeDebug) 的目錄設定, 所以即使它可以幫你整合檔案裡的設定值, 但要怎麼擺放 AndroidManifest.xml 卻是個大問題.

這邊一樣提供 hack 的方法, 首先指定 flavour 所要使用的 AndroidManifest.xml 路徑

project.ext.flavor1 = [
    debugManifest: 'src/flavor1Debug/AndroidManifest.xml',
    releaseManifest: 'src/flavor1Release/AndroidManifest.xml'
]

project.ext.flavor2 = [
    debugManifest: 'src/flavor2Debug/AndroidManifest.xml',
    releaseManifest: 'src/flavor2Release/AndroidManifest.xml'
]

接著在 variant.processManifest 時想辦法讓 gradle 吃到這些檔案, 由於這個 case 的 debug & release 都是不同的 package name, 我們可以利用 flavour 本身並不具有資源設定值的特色, 把新的 AndroidManifest.xml 偷偷地塞進 flavour 的目錄裡, 名正言順的讓 gradle 編譯該 flavour. 最後記得刪除這個偷塞的檔案:

android.applicationVariants.all { variant ->
    variant.processManifest.doFirst {
        if (project.ext.has(variant.<a href="http://productFlavors.name">productFlavors.name</a>)) {
            if (project.ext[variant.<a href="http://productFlavors.name">productFlavors.name</a>].debugManifest != null &amp;&amp;
                project.ext[variant.productFlavors.name].releaseManifest != null) {
                def manifestDirectory = android.sourceSets[variant.productFlavors.name].manifest.srcFile.parentFile
                if (variant.buildType.name.equals("debug")) {
                    copy {
                        from project.ext[variant.productFlavors.name].debugManifest
                        into manifestDirectory
                    }
                } else if (variant.buildType.name.equals("release")) {
                    copy {
                        from project.ext[variant.productFlavors.name].releaseManifest
                        into manifestDirectory
                    }
                }
            }
        }
    }

    variant.processManifest.doLast {
        if (project.ext.has(variant.productFlavors.name)) {
            project.delete android.sourceSets[variant.productFlavors.name].manifest.srcFile
        }
    }
}

至於 AndroidManifest.xml, 只要留 GCM 相關設定即可, 其他 Activity 啥鬼的都不用放進去, 由 gradle 在編譯過程中自行與 main 整合.



    package="com.android.example.free.debug"
    android:versionCode="1"
    android:versionName="1.0" >


        android:name="com.android.example.free.debug.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />






收工, 跟平常一樣 assemble 即可, happy hacking ! 相關的 code 可以參考這 : https://github.com/shakalaca/learning_gradle_android/blob/bef7af864f1d89483df3c611d76a199815f65660/07_tricks/app/build.gradle



comments powered by Disqus