I'm struggling to find a way for build several apk at once with gradle.
I'd like to have a custom gradle task which considers only variants with enviroment = "production" and all the brands but nonPublishedBrand and buildtype = "release" (see code below).
For each of those variants i need to:
generate the signed apk
upload prodguard mappings to bugsnag with the relative task uploadBugsnag${variant.name}-releaseMapping
rename apk into <brand>-<version>.apk and move it to a common folder $buildDir/myApks
I only found a way to make assemble tasks also run my custom tasks but that's not ideal because i don't want to upload mappings every time a production release variant is built, but only when it's meant i.e. launching a specific gradle task.
Is it possible to achieve that with gradle? Can you please point me in the right direction?
See my build.gradle android section for reference:
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 15
targetSdkVersion 27
versionCode 1000000
versionName "1.0.0.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
storeFile file("keystore/keystore")
storePassword '*******'
keyAlias '*******'
keyPassword '*******'
}
}
buildTypes {
debug {
applicationIdSuffix ".debug"
versionNameSuffix ".debug"
manifestPlaceholders = [buildTypePrefix: "D_"]
}
release {
debuggable false
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
manifestPlaceholders = [buildTypePrefix: ""]
}
}
flavorDimensions "environment", "brand"
productFlavors {
//ENVIRONMENTS
staging {
dimension "environment"
applicationIdSuffix ".staging"
versionNameSuffix ".staging"
buildConfigField("String", "BASE_URL", "\"http://baseurl-staging.com\"")
manifestPlaceholders = [environmentPrefix: "S_"]
}
production {
dimension "environment"
buildConfigField("String", "BASE_URL"l, "\"http://baseurl-prod.com\"")
manifestPlaceholders = [environmentPrefix: ""]
}
//BRANDS
nonPublishedBrand {
dimension "brand"
applicationId "${packageBaseName}.nonpublishedbrand"
manifestPlaceholders = [appName: "Non published brand"]
ext {
facebook_app_id = [
staging: "0000000",
prod : "11111111"
]
}
}
brand1 {
dimension "brand"
applicationId "${packageBaseName}.brand1"
manifestPlaceholders = [appName: "Brand 1"]
ext {
facebook_app_id = [
staging: "22222222",
prod : "33333333"
]
}
}
brand2 {
dimension "brand"
applicationId "${packageBaseName}.brand2"
manifestPlaceholders = [appName: "Brand 2"]
ext {
facebook_app_id = [
staging: "44444444",
prod : "555555555"
]
}
}
}
productFlavors {
applicationVariants.all { variant ->
def isDebug = false
if (variant.buildType.name == "debug") {
isDebug = true
}
def isStaging = false
def flavors = variant.productFlavors
def environment = flavors[0]
if (environment.name == "staging") {
isStaging = true
}
def facebookAppId = ""
if (isStaging){
facebookAppId = flavors[1].facebook_app_id.staging
}else{
facebookAppId = flavors[1].facebook_app_id.prod
}
variant.buildConfigField "String", "FACEBOOK_APP_ID", "\"${facebookAppId}\""
}
}
dataBinding {
enabled = true
}
bugsnag {
autoUpload false
}
}
circle.ci is an efficient way to generate builds with each commit. Documentation : https://circleci.com/docs/2.0/
Your circle.yml file would have something like this :
override:
- ./gradlew clean :mobile:assemblePre -PdisablePreDex -Pandroid.threadPoolSize=1 -Dorg.gradle.parallel=false -Dorg.gradle.jvmargs="-Xms2048m -Xmx4608m"
- cp -r ~ build/outputs/apk/build/pre/*.apk $CIRCLE_ARTIFACTS
- ./gradlew clean :mobile:assembleRelease -PdisablePreDex -Pandroid.threadPoolSize=1 -Dorg.gradle.parallel=false -Dorg.gradle.jvmargs="-Xms2048m -Xmx4608m"
- cp -r ~build/outputs/apk/build/release/*.apk $CIRCLE_ARTIFACTS
assemblePre and assembleRelease are tasks executed in above case. You can try to write custom tasks here.
Related
As I have tried these 2 ways (using a single at a time) to rename the APK
Option - One
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
Option - Two
(for this also tried to change the - variant.outputs.all to variant.outputs.each)
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
When I use option One,
Issue - it generates all splits but it overrides the flavor config with the
last flavor written in Gradle.
Also, try to put option One only once in defaultConfig but as productFlavours written after that it returns the null value in versionCode and versionName.
productFlavors {
aFlavor {
applicationId "com.a"
versionCode 5
versionName "1.0.5"
signingConfig signingConfigs.signingA
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
}
bFlavor {
applicationId "com.b"
versionCode 5
versionName "1.0.5"
signingConfig signingConfigs.signingB
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
}
cFlavor {
applicationId "com.c"
versionCode 3
versionName "1.0.3"
signingConfig signingConfigs.signingC
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
}
}
When I use option Two,
Issue - it generates the correct name but generates a single APK file.
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'x86', 'x86_64'
universalApk false
}
}
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
Issue for bundle - not able to rename the bundle using option Two.
As per This answer, you can go with Option - Two with minor changes as mention below only works for APK, not the Bundle / AAB files
splits {
abi {
enable true
reset()
include 'arm64-v8a', 'x86', 'x86_64'
universalApk false
}
}
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
// New one or Updated one
output.outputFileName = "${variant.getFlavorName()}-${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}-${output.getFilter(com.android.build.OutputFile.ABI)}.apk"
// Old one
// output.outputFileName = "${variant.buildType.name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
Also, remove the line from each Flavor's block
// To Change the APK and Bundle Name
archivesBaseName = "${name}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}"
By this, you get the output file name like this
For aFlvour
Release
aFlavor-release-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk
aFlavor-release-v5_1.0.5-16Jan2020_21-26-x86_64.apk
aFlavor-release-v5_1.0.5-16Jan2020_21-26-x86.apk
Debug
aFlavor-debug-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk
aFlavor-debug-v5_1.0.5-16Jan2020_21-26-x86_64.apk
aFlavor-debug-v5_1.0.5-16Jan2020_21-26-x86.apk
For bFlavor
Similar name as above just change the prefix aFlavor with bFlavor like
bFlavor-release-v5_1.0.5-16Jan2020_21-26-arm64-v8a.apk
For cFlavor
Similar name as above just change the prefix aFlavor with cFlavor
and, versionCode and versionName as respected
cFlavor-release-v3_1.0.3-16Jan2020_21-26-arm64-v8a.apk
Because you are using universalApk false, Gradle generates different output apk for each ABI. So you have to add ABI name to your output filename. The output.getFilter(com.android.build.OutputFile.ABI) expression returns current ABI name.
Please look at the following example:
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
output.outputFileName = "${variant.buildType.name}-${output.getFilter(com.android.build.OutputFile.ABI)}-v${versionCode}_${versionName}-${new Date().format('ddMMMyyyy_HH-mm')}.apk"
}
}
Remove app_name from string.xml file
apply plugin: 'com.android.application'
android {
signingConfigs {
release {
keyAlias 'your key alias'
keyPassword 'your password'
storeFile file('path of your keystore')
storePassword 'your password'
}
}
compileSdkVersion 28
flavorDimensions "default"
project.archivesBaseName = "ProjectName";
defaultConfig {
applicationId "Your package name"
minSdkVersion 16
targetSdkVersion 28
multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
signingConfig signingConfigs.release
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
applicationVariants.all { variant ->
variant.outputs.all { //output ->
outputFileName = "YourAppName-${variant.baseName}-${variant.versionName}.apk"
}
}
}
debug {
}
}
productFlavors {
dev {
versionCode 778899 // your versioncode
versionName "v.1.1.BUILD_NUM" // your version name
applicationIdPrefix ".dev" // your application package name like as com.a
resValue "string", "app_name", "Your App Name"
}
live {
versionCode 778899 // your versioncode
versionName "v.1.1.BUILD_NUM" // your version name
applicationIdPrefix ".dev" // your application package name like as com.a
resValue "string", "app_name", "Your App Name"
}
}
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
}
dependencies {
// Here your application gradle
}
These solutions do not work for aab (bundle). Only APK.
You have to set different flavors if you want to have different output apks.
I have an android studio project, and I'm trying to port gradle from the stable version 2.0.0 to the experimental version 0.7.0-beta1:
This is the working code inside my android tag module my 2.0.0 gradle code:
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.test.myapp"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.0"
ndk {
moduleName "myNativeLib"
}
}
sourceSets.main {
jniLibs.srcDir 'src/main/libs' //set .so files location to libs
jni.srcDirs = [] //disable automatic ndk-build call
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task runSwig(type: Exec, description: 'Run swig config') {
workingDir 'src/main'
commandLine 'cmd', '/c', 'swig.bat'
}
Properties props = new Properties()
props.load(new FileInputStream(file(project.property("KeyStore.properties"))))
signingConfigs {
storeSignature {
storeFile = file(props['KEYSTORE'])
storePassword = props['KEYSTORE_PASSWD']
keyAlias = props['KEYSTORE_MYAPP']
keyPassword = props['KEYSTORE_MYAPP_PASSWD']
}
}
buildTypes {
def SERVER_URL = "SERVER_URL"
debug {
debuggable true
jniDebuggable true
buildConfigField "String", SERVER_URL, "\"http://testusound.eastus.cloudapp.azure.com/androidbackend/checkjson\""
versionNameSuffix getMasterName() + "." + getDate()
}
release {
signingConfig signingConfigs.storeSignature
debuggable false
jniDebuggable false
minifyEnabled false
buildConfigField "String", SERVER_URL, "\"http://www.usound.co/androidbackend/checkjson\""
versionNameSuffix getMasterName()
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
Now here is my attempt to rewrite my code for the expermiental pluggin 0.7.0-beta1:
model {
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig.with {
applicationId "com.test.myapp"
minSdkVersion.apiLevel 15
targetSdkVersion.apiLevel 23
versionCode 1
versionName "1.0"
}
ndk {
moduleName "myNativeLib"
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
}
task runSwig(type: Exec, description: 'Run swig config') {
workingDir 'src/main'
commandLine 'cmd', '/c', 'swig.bat'
}
buildConfigFields.with {
create() {
type "String"
name "SERVER_URL"
value "\"http://www.myserver.com/backend/checkjson\""
}
}
buildConfigFields.with {
create() {
type "String"
name "TEST_SERVER_URL"
value "\"http://www.mytestserver.com/backend/checkjson\""
}
}
sources {
main {
jni {
source {
srcDir "src"
}
}
jni.srcDirs = [] //disable automatic ndk-build call
}
}
buildTypes {
debug {
debuggable true
jniDebuggable true
buildConfigField $("android.buildConfigFields.TEST_SERVER_URL")
versionNameSuffix getMasterName() + "." + getDate()
}
release {
signingConfig = $("android.signingConfigs.mySignature")
debuggable false
jniDebuggable false
minifyEnabled false
buildConfigField $("android.buildConfigFields.SERVER_URL")
versionNameSuffix getMasterName()
proguardFiles.add(file('proguard-rules.pro'))
}
}
Properties props = new Properties()
props.load(new FileInputStream(file(project.property("KeyStore.properties"))))
}
android.signingConfigs {
create("mySignature")
storeFile = file(props['KEYSTORE'])
storePassword = props['KEYSTORE_PASSWD']
keyAlias = props['KEYSTORE_MYAPP']
keyPassword = props['KEYSTORE_MYAPP_PASSWD']
}
}
I'm getting this error error with the signingConfigs:
Error:Attempt to read a write only view of model of type 'java.lang.Object' given to rule 'android.signingConfigs { ... } # app\build.gradle line 165, column 5'
in my code would be this line:
android.signingConfigs {
for my signing configs I'm using a file called keystore.properties located under my main folder (I would like to keep it this way in a separate file so I don't upload my keystore signature data to git, so I haven't put the signing config keys like in the current experimental gradle projects).
What am I missing here? How should I write the signing configs to use properties loaded from a file?
As I'm just getting into experimental gradle feel free to give me some examples or info you believe might be useful.
The stuff after create should be in a set of {}'s
android.signingConfigs {
create("mySignature") { // <-- needed
storeFile = file(props['KEYSTORE'])
storePassword = props['KEYSTORE_PASSWD']
keyAlias = props['KEYSTORE_MYAPP']
keyPassword = props['KEYSTORE_MYAPP_PASSWD']
} // <-- needed
}
Imagine this setup:
android {
buildTypes {
debug {
applicationIdSuffix ".debug"
}
}
productFlavors {
foo {
applicationId defaultConfig.applicationId + '.foo'
}
}
}
How can I set up a dynamic string value such as
resValue "string", "package_name", applicationId
so that it includes the applicationIdSuffix for debug builds?
If I add this to defaultConfig, its my defaultConfig's applicationId that is set. If I add this to the flavor configuration, it is missing the applicationIdSuffix (this is null at this level).
Any hints?
The cool part about applicationIdSuffix is that you can use it in flavors as well as in build types. Check this out:
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "dev.bmax.suffixtext"
minSdkVersion 14
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
applicationIdSuffix '.debug'
}
}
productFlavors {
prod {
applicationIdSuffix '.prod'
}
mock {
applicationIdSuffix '.mock'
}
}
}
Now, when I build my 'prodDebug' variant the final application ID is 'dev.bmax.suffixtext.prod.debug', which is what you want if I understand your question correctly.
EDIT
You can access the variant's name in a Gradle task like this:
applicationVariants.all { variant ->
// Use 'variant.name'
}
Gradle Android Plugin version 0.14.3 added support of the variant specific BuildConfigField/resValue:
applicationVariants.all { variant ->
variant.resValue "string", "name", "value"
}
I've got an Android app that has 2 flavors: internal and production, and there are 2 build types as well: debug and release.
I'm trying to assign signing configs based on the flavor, which according to the documentation is doable. I've looked and found other answers to this, but none of them seem to work. Everything compiles, but the app is being signed with the debug keystore local to my machine.
Here is my gradle file:
android {
compileSdkVersion 22
buildToolsVersion "22.0.1"
defaultConfig {
minSdkVersion 14
targetSdkVersion 22
versionCode 1
versionName "1.0.0"
}
signingConfigs {
internal {
storeFile file("../internal.keystore")
storePassword "password"
keyAlias "user"
keyPassword "password"
}
production {
storeFile file("../production.keystore")
storePassword "password"
keyAlias "user"
keyPassword "password"
}
}
productFlavors {
internal {
signingConfig signingConfigs.internal
applicationId 'com.test.test.internal'
}
production {
signingConfig signingConfigs.production
applicationId 'com.test.test'
}
}
buildTypes {
debug {
applicationIdSuffix ".d"
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
variantFilter { variant ->
if (variant.buildType.name.equals('debug')
&& variant.getFlavors().get(0).name.equals('production')) {
variant.setIgnore(true);
}
}
}
Note: I'm also compiling with classpath 'com.android.tools.build:gradle:1.1.3'
It seems that by default, Android has a signingConfig set on the debug build type (the android debug keystore), and when the signingConfig is set for the build type, the signingConfig is ignored for the flavor.
The solution is to set the signingConfig to null on the debug build type. Then the signingConfig given for the flavor will be used instead:
buildTypes {
debug {
// Set to null to override default debug keystore and defer to the product flavor.
signingConfig null
applicationIdSuffix ".d"
}
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
I am tyring to migrate my projects to gradle. One of my projects has multiple product flavors and each one of them has to be signed with a different signingConfig in its release version. So this is what I tried so far:
buildscript {
...
}
apply plugin: 'android'
android {
compileSdkVersion 17
buildToolsVersion '17'
signingConfigs {
flavor1 {
storeFile file("keystore")
storePassword "secret"
keyAlias "aliasForFlavor1"
keyPassword "secretFlavor1"
}
flavor2 {
storeFile file("keystore")
storePassword "secret"
keyAlias "aliasForFlavor2"
keyPassword "secretFlavor2"
}
}
productFlavors {
flavor1 {
signingConfig signingConfigs.flavor1
}
flavor1 {
signingConfig signingConfigs.flavor2
}
}
}
dependencies {
...
}
When I run gradle build I get a groovy.lang.MissingFieldException and the following error message:
No such field: signingConfigs for class: com.android.build.gradle.internal.dsl.GroupableProductFlavorFactory
So I assume the productFlavors.* part of the Gradle script is not the right place to put code signing configurations.
You can declare signing config for each flavor in buildType. Here is my gradle file for release signing flavors with different keystores.
android {
signingConfigs {
configFirst {
keyAlias 'alias'
keyPassword 'password'
storeFile file('first.keystore')
storePassword 'password'
}
configSecond {
keyAlias 'alias'
keyPassword 'password'
storeFile file('second.keystore')
storePassword 'password'
}
}
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 14
targetSdkVersion 23
}
productFlavors{
flavor1 {
applicationId "com.test.firstapp"
}
flavor2 {
applicationId "com.test.secondapp"
}
}
buildTypes {
release {
productFlavors.flavor1.signingConfig signingConfigs.configFirst
productFlavors.flavor2.signingConfig signingConfigs.configSecond
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'),
'proguard-rules.pro'
}
}
}
buildTypes block should be placed after productFlavors block, I mean order is important.
Per the user guide, signingConfigs for flavors are supported.
The problem here has to do with the scope of the signingConfigs object. I just assigned it to a variable inside the productFlavors block, but outside the flavor1 flavor block to fix the issue:
productFlavors {
def flavor1SigningVariable = signingConfigs.flavor1
flavor1 {
...
signingConfig flavor1SigningVariable
...
}
The gradle plugin for android only supports signing per build type, not per flavor. The reason for this is that any given variant (build type + flavors) can only be signed by one key, but can be a combination of several flavor groups. For example your flavor groups could be cpu (x86/arm) and version (free/paid), that's four different variants right there.
The solution you're looking for is to create separate build types for your different release versions. For example, your build types might be debug, release, release-beta, like this:
...
android {
...
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
signingConfig signingConfigs.release
}
release-beta {
initWith release
signingConfig signingConfigs.release-beta
}
}
}
The initWith above just tells gradle that release-beta should be a copy of the release build type, only signed with a different key.
Maybe another interesting solution with dynamic flavor signing configs and other advantages
Im fine with defining app id and app name of flavors in gradle (it is clear and just 2 lines for each flavor) but I do not want to define separate signing configs (gradle file would be too long when adding flavors)
I also do not want to have sensitive signing information placed in gradle because of commiting it
Bonus advantage is that debug build has another app id and app name.
.gitignore
...
/keystore.properties
.keystore.properties
storeFile=../mystore.jks
storePassword=...
keyAliasFlavor1=...
keyPasswordFlavor1=...
keyAliasFlavor2=...
keyPasswordFlavor2=...
app/build.gradle
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(rootProject.file('keystore.properties')))
android {
...
buildTypes {
debug {
...
manifestPlaceholders = [appNameSuffix: " Dev"]
applicationIdSuffix ".dev"
}
release {
...
manifestPlaceholders = [appNameSuffix: ""]
productFlavors.all { flavor ->
flavor.signingConfig = android.signingConfigs.create("${flavor.name}")
flavor.signingConfig.storeFile = rootProject.file(keystoreProperties["storeFile"])
flavor.signingConfig.storePassword = keystoreProperties["storePassword"]
flavor.signingConfig.keyAlias = keystoreProperties["keyAlias${flavor.name}"]
flavor.signingConfig.keyPassword = keystoreProperties["keyPassword${flavor.name}"]
}
}
}
productFlavors {
Flavor1 {
applicationId "..."
manifestPlaceholders = [appNameBase: "MyApp 1"]
}
Flavor2 {
applicationId "..."
manifestPlaceholders = [appNameBase: "MyApp 2"]
}
// ... and many other flavors without taking care about signing configs
// (just add two lines into keystore.properties for each new flavor)
}
}
app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
...
<application android:label="${appNameBase}${appNameSuffix}" ...>
...
</application>
</manifest>
This is the Kotlin DSL equivalent of ashakirov's answer:
// See https://stackoverflow.com/q/60474010
fun getLocalProperty(key: String) = gradleLocalProperties(rootDir).getProperty(key)
fun String?.toFile() = file(this!!)
// Could also use System.getenv("VARIABLE_NAME") to get each variable individually
val environment: Map<String, String> = System.getenv()
android {
signingConfigs {
create("MyFirstConfig") {
keyAlias = getLocalProperty("signing.keyAlias") ?: environment["SIGNING_KEY_ALIAS"]
storeFile = (getLocalProperty("signing.storeFile") ?: environment["SIGNING_STORE_FILE"]).toFile()
keyPassword = getLocalProperty("signing.keyPassword") ?: environment["SIGNING_KEY_PASSWORD"]
storePassword = getLocalProperty("signing.storePassword") ?: environment["SIGNING_STORE_PASSWORD"]
enableV1Signing = true
enableV2Signing = true
}
create("MySecondConfig") {
keyAlias = getLocalProperty("signing.keyAlias2") ?: environment["SIGNING_KEY_ALIAS2"]
storeFile = (getLocalProperty("signing.storeFile2") ?: environment["SIGNING_STORE_FILE2"]).toFile()
keyPassword = getLocalProperty("signing.keyPassword2") ?: environment["SIGNING_KEY_PASSWORD2"]
storePassword = getLocalProperty("signing.storePassword2") ?: environment["SIGNING_STORE_PASSWORD2"]
enableV1Signing = true
enableV2Signing = true
}
}
productFlavors {
create("flavor1") {
// ...
}
create("flavor2") {
// ...
}
}
buildTypes {
getByName("release") { // OR simply release { in newer versions of Android Gradle Plugin (AGP)
productFlavors["flavor1"].signingConfig = signingConfigs["MyFirstConfig"]
productFlavors["flavor2"].signingConfig = signingConfigs["MySecondConfig"]
// OR alternative notation
// productFlavors {
// getByName("flavor1") {
// signingConfig = signingConfigs["MyFirstConfig"]
// }
// getByName("flavor2") {
// signingConfig = signingConfigs["MySecondConfig"]
// }
// }
}
}
}
Split signing configs between Gms and Hms builds
Just for future ref if anyone has to split their signing configs between Gms and Hms builds.
This adds on the the answer listed here:
Maybe another interesting solution with dynamic flavor signing configs and other advantages
build.gradle
Option 1
gradle.startParameter.getTaskNames().each()
def keystorePropertiesFile = rootProject.file("keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
signingConfigs {
release {
storeFile file(keystoreProperties["RELEASE_STORE_FILE"])
storePassword keystoreProperties["RELEASE_STORE_PASSWORD"]
keyAlias keystoreProperties["RELEASE_KEY_ALIAS"]
keyPassword keystoreProperties["RELEASE_KEY_PASSWORD"]
}
releaseHms {
storeFile file(keystoreProperties["RELEASE_HMS_STORE_FILE"])
storePassword keystoreProperties["RELEASE_STORE_PASSWORD"]
keyAlias keystoreProperties["RELEASE_KEY_ALIAS"]
keyPassword keystoreProperties["RELEASE_KEY_PASSWORD"]
}
debug {
// use default debug key to sign
}
}
buildTypes {
release {
...
gradle.startParameter.getTaskNames().each { task ->
if (task.toLowerCase().contains("gms")) {
signingConfig signingConfigs.release
}
if (task.toLowerCase().contains("hms") {
signingConfig signingConfigs.releaseHms
}
}
}
debug {
...
gradle.startParameter.getTaskNames().each { task ->
if (task.toLowerCase().contains("gms")) {
signingConfig signingConfigs.debug
}
if (task.toLowerCase().contains("hms") {
signingConfig signingConfigs.releaseHms
}
}
flavorDimensions "serviceplatform"
productFlavors {
hms {
dimension "serviceplatform"
applicationIdSuffix ".huawei"
versionNameSuffix "-huawei"
}
gms {
dimension "serviceplatform"
applicationIdSuffix ".android"
}
}
sourceSets {
main {
res.srcDirs = [
"src/main/res",
"src/main/res/layout/toolbar",
"src/main/res/layout/fragment",
"src/main/res/layout/activity"
]
}
gms {
java.srcDir("src/gms/java")
}
hms {
java.srcDir("src/hms/java")
}
}
Option 2
productFlavors.gms.signingConfig
Ensure your flavorDimensions is before buildTypes
flavorDimensions "serviceplatform"
productFlavors {
hms {
...
}
gms {
...
}
}
buildTypes {
release {
...
productFlavors.gms.signingConfig signingConfigs.release
productFlavors.hms.signingConfig signingConfigs.releaseHms
}
debug {
...
productFlavors.gms.signingConfig signingConfigs.debug
productFlavors.hms.signingConfig signingConfigs.releaseHms
}
}