I have a Gradle Android project that has 4 product flavors (each has it's own unique package name). The build.gradle
file is prity much straightforward:
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.6.+' } } apply plugin: 'android' repositories { mavenCentral() } dependencies { // All dependencies here // ... } android { // Usual stuff goes here productFlavors { flav1 { packageName 'com.company.flav1' versionName calcVersion() } flav2 { packageName 'com.company.flav2' versionName calcVersion() } flav3 { packageName 'com.company.flav3' versionName calcVersion() } flav4 { packageName 'com.company.flav4' versionName calcVersion() } } // Other configurations // ... }
Everything goes fine, and the required resources are merged, e.t.c. Now I am trying to implement a Push Notification feature using GCM. And according to the documentation, I must declare a permission for my app, like this:
<permission android:name="com.company.flav.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.company.flav.permission.C2D_MESSAGE" />
But I'm using a single manifest file, for all 4 applications (they differ only in application resources and some settings, that are put in the assets folder).
So my question is: How can I override these permissions for every product flavor?
I've used:
<permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
in the Android manifest - this appears to be resolved correctly.
You can use some sort of inheritance AndroidManifest.
The following rules are used when dealing with all the sourcesets used to build a single APK: - All source code (src/*/java) are used together as multiple folders generating a single output. - *Manifests are all merged together into a single manifest. This allows Product Flavors to have different components and/or permissions, similarly to Build Types.* - All resources (Android res and assets) are used using overlay priority where the Build Type overrides the Product Flavor, which overrides the main sourceSet. - Each Build Variant generates its own R class (or other generated source code) from the resources. Nothing is shared between variants.
code:
productFlavors { flav1 { packageName 'com.company.flav1' versionName calcVersion() } flav2 { packageName 'com.company.flav2' versionName calcVersion() } flav3 { packageName 'com.company.flav3' versionName calcVersion() } flav4 { packageName 'com.company.flav4' versionName calcVersion() } } sourceSets { main { manifest.srcFile 'AndroidManifest.xml' java.srcDirs = ['src'] resources.srcDirs = ['src'] aild.srcDirs = ['src'] renderscript.srcDirs = ['src'] res.srcDirs = ['res'] assets.srcDirs = ['assets'] } flav1 { manifest.srcFile 'flavor1/AndroidManifest.xml' } flav2 { manifest.srcFile 'flavor2/AndroidManifest.xml' } ... }
Where flavor1
and flavor2
are folders in root project folder.
In flavor1/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sample.someapp" android:versionCode="1" android:versionName="1.0"> <permission android:name="com.company.flav1.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.company.flav1.permission.C2D_MESSAGE" /> </manifest>
In flavor2/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.sample.someapp" android:versionCode="1" android:versionName="1.0"> <permission android:name="com.company.flav2.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.company.flav2.permission.C2D_MESSAGE" /> </manifest>
And in root AndroidManifest
everything else.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With