Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Gradle replace Package name for a value in manifest

Tags:

android

gradle

I am using Gradle with Product flavors where I set a different package name for each one.

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

I need to be able to replace the package name inside the manifest for each corresponding app.

My manifest has this:

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

So I need to replace com.dg.example for each app flavor's package name. What is the best way to do this?

like image 571
DArkO Avatar asked Jan 14 '14 08:01

DArkO


People also ask

Where is the merged manifest?

Even before you build your app, you can see a preview of what your merged manifest looks by opening your AndroidManifest. xml file in Android Studio, and then clicking the Merged Manifest tab at the bottom of the editor.

Where is the manifest file in Android Studio?

The file is located at WorkspaceName>/temp/<AppName>/build/luaandroid/dist. The manifest file provides essential information about your app to the Android operating system, and Google Play store. The Android manifest file helps to declare the permissions that an app must have to access data from other apps.

What is the use of manifest and Gradle files in Android application?

Every app project must have an AndroidManifest. xml file (with precisely that name) at the root of the project source set. The manifest file describes essential information about your app to the Android build tools, the Android operating system, and Google Play.


2 Answers

Gradle Plugin v0.12 and higher:

Use ${applicationId} instead of ${packageName}.

Gradle Plugin v0.11 and higher:

As of v0.11, you no longer need to specify not to use the old manifest merger.

Gradle Plugin v0.10 and higher:

Assuming you're using version 0.10 or higher, this is now officially supported:

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

As of v0.10, you'll also have to manually enable the new manifest merger, although I'd expect that requirement to go away in a version or two whenever the new merger becomes the default:

android {     useOldManifestMerger false } 

Then, just use ${packageName} anywhere in AndroidManifest.xml that you would normally hardcode the package name. For example:

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

would become

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


Gradle Plugin v0.9 and below:

So, referencing this post, it appears this is not yet officially supported through Gradle. A simple workaround is the following:

  1. Replace the package name with a custom tag (e.g. <category android:name="my.package.name"/> becomes <category android:name="_PACKAGENAME_"/>
  2. Add the following to your build.gradle, under the android scope:

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')     } } 
like image 155
Kevin Coppock Avatar answered Sep 25 '22 09:09

Kevin Coppock


To do something like this, I use buildTypes in my gradle file but I am pretty sure this will work with flavours as well. For me I am trying to set the label field in the activities.

I have a strings xml file for each of my buildTypes. Then I have a sourceSet for each buildType which includes the correct strings file. Then in the manifest I do not use a hard coded string but rather "@string/my_var" which will pull the correct string depending on how the sourceSets are defined.

This google+ post and related gist may help.

Something else to do is to put a AndroidManifest.xml file into the src/flavour which only contains the bits which are relevant to each flavour. Then take those bits out of the main manifest file. At build time the Manifest files will be merged into one file. You can see the result all of the merged manifests in build/manifests.

like image 27
maiatoday Avatar answered Sep 25 '22 09:09

maiatoday