Android Gradlereplace清单中的值的包名称

我正在使用Gradle的产品风味,我为每一个设置不同的包名称。

productFlavors { appone { packageName "com.dg.app1" } apptwo { packageName "com.dg.app2" } appthree { packageName "com.dg.app3" } appfour { packageName "com.dg.app4" } } 

我需要能够replace每个相应的应用程序清单内的包名称。

我的清单是这样的:

 <receiver android:name="com.parse.GcmBroadcastReceiver" 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.dg.example" /> </intent-filter> </receiver> 

所以我需要replace每个应用程序风格的包名称的com.dg.example。 做这个的最好方式是什么?

Gradle插件v0.12及更高版本:

使用${applicationId}而不是${packageName}

Gradle插件v0.11及更高版本:

从v0.11开始,您不再需要指定不使用旧的清单合并器。

Gradle Plugin v0.10及更高版本:

假设您使用0.10或更高版本,现在已经正式支持:

 buildscript { repositories { mavenCentral() } dependencies { // Make sure this is at least 0.10.+ classpath 'com.android.tools.build:gradle:0.10.+' } } 

从v0.10开始,您还必须手动启用新的清单合并 ,不过,当新合并成为默认值时,我希望这个要求能够以一两个版本消失:

 android { useOldManifestMerger false } 

然后,只需在AndroidManifest.xml中的任何位置使用${packageName} ,通常您将对软件包名称进行硬编码。 例如:

 <category android:name="my.package.name"/> 

会成为

<category android:name="${packageName}"/>


Gradle Plugin v0.9及以下版本:

所以,引用这篇文章 ,似乎这还没有正式通过Gradle支持。 一个简单的解决方法如下:

  1. 用自定义标记replace包名(例如<category android:name="my.package.name"/>变成<category android:name="_PACKAGENAME_"/>
  2. 将以下内容添加到您的build.gradle ,在android范围内:

 applicationVariants.all { variant -> // After processing the manifest, replace all instances of your tag // with the variant's actual package name. variant.processManifest << { def manifestOutFile = variant.processManifest.manifestOutputFile def newFileContents = manifestOutFile.getText('UTF-8').replace("_PACKAGENAME_", variant.packageName) manifestOutFile.write(newFileContents, 'UTF-8') } } 

为了做这样的事情,我在我的gradle文件中使用了buildTypes,但是我很确定这也适用于flavor。 对我来说,我试图在活动中设置标签字段。

我有我的每个buildTypes一个stringXML文件。 然后我有一个每个buildType包含正确的string文件的sourceSet。 然后在清单中,我不使用硬编码的string,而是“@ string / my_var”,它将根据sourceSets的定义来提取正确的string。

这谷歌+post和相关的要点可能会有所帮助。

还有一件事是把一个AndroidManifest.xml文件放到src / flavor中,它只包含与每个flavor相关的位。 然后将这些位从主清单文件中取出。 在构build时,Manifest文件将被合并到一个文件中。 您可以在构build/清单中看到所有合并清单的结果。

我有同样的问题,并在Gradle中实现了占位符replace方法。 它确实如你所期望的那样,同时也关心了packageNameSuffix属性,所以你可以在同一个设备上进行debugrelease以及任何其他定制的构build。

 applicationVariants.all { variant -> def flavor = variant.productFlavors.get(0) def buildType = variant.buildType variant.processManifest.doLast { println '################# Adding Package Names to Manifest #######################' replaceInManifest(variant, 'PACKAGE_NAME', [flavor.packageName, buildType.packageNameSuffix].findAll().join()) // ignores null } } def replaceInManifest(variant, fromString, toString) { def flavor = variant.productFlavors.get(0) def buildtype = variant.buildType def manifestFile = "$buildDir/manifests/${flavor.name}/${buildtype.name}/AndroidManifest.xml" def updatedContent = new File(manifestFile).getText('UTF-8').replaceAll(fromString, toString) new File(manifestFile).write(updatedContent, 'UTF-8') } 

如果你想看看它是否会在以后发展的话,我也会把它写出来。

我发现这是比多种资源和XMLparsing方法更优雅的方法。

选项Gradle:

使用成绩属性 API。 有些事情是这样的

 manifest.attributes(["attr1":"value1", "attr2":"value2"]) 

选项1

如何将您的项目转换为Android – 库项目,并为每个公司制作额外的项目。 你可以根据需要编辑Manifest文件。

选项2

写一个batch file。