Stephen McCormick
Stephen McCormick

Reputation: 1796

Android White Labeling using Android Studio Flavors

I have recently moved from Eclipse to Android Studio, and after some effort have the application up and running. Now I face the second obstacle - generating white label versions of the application. I have read everything I can find on the Flavor mechanism in Android Studio and I believe it will work but there are few questions I still have.

But first let me explain the current white labeling mechanism that we use employing Ant (due to an upgrading of the support library I don't think I can use it anymore since it does require the presence of Jar files in lib folder?). This Ant script reads a build.xml file where we have specified the location of the new values (strings.xml and colors.xml) and resource folders (images and such) specific to the white label. It basically copies the new files (only a few are different) and then runs the build, renaming the APK and giving it a new App Id. So in one fell swoop I can build upwards of 100 white labels with a press of a button. Included in this build is a copy mechanism which creates a copy of the new APK with a version associated with it, so if the basic flavor is MYAPP.apk and we are on version 44, it copies that and makes a 44-MYAPP.apk which we keep around in case we need to roll back for those customers pulling directly from our S3 and not from GooglePlay - yeah, that is a requirement for some of them.

I think I can mimic most of this with flavors, with the following questions:

  1. I want all the builds to have the same version name and version code. If I leave the flavor config values empty, will they pick up the versions from the AndroidManifest.xml file?

  2. Is it possible to have each APK have it's own application name when generated, such AppHeyYou.apk and WhereIsThat.apk for another flavor? The examples I have seen seem to tack on a suffix to the end of APK name, I need a completely new APK name (and without the "Release" tacked on).

  3. Can I have it build the flavor, then copy it and rename it (such as MyApp.apk and copy to 44-MyApp.apk) using the version from the AndroidManifest.xml or the default config? Since there are close to a 100, changing this in each flavor config would be not be practical with each release.

  4. Is there a way to force the generation of ALL the white labels with a single push of the button. Again, doing this for each would be impractical.

Thanks for any help!

UPDATE

Just to be helpful I thought I would show the full gradle script of what I ended up with. Here is what it does:

  1. Defines the flavors
  2. When building them, gives them the name of the flavor, but with the version code tacked on in front (so Red flavor with version code 44 becomes "44-Red.apk").

In the end my build.gradle for the application looks like this:

buildscript {
    repositories {
        maven { url 'https://maven.fabric.io/public' }
    }

    dependencies {
        classpath 'io.fabric.tools:gradle:1.+'
    }
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

repositories {
    maven { url 'https://maven.fabric.io/public' }
}


android {
    compileSdkVersion 25
    buildToolsVersion '25.0.2'
    defaultConfig {
        applicationId "com.mycompany.ourapp"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 62
        versionName "1.0.62"
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7
        }
        signingConfig signingConfigs.config
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
    productFlavors {
        Red {
            setProperty("archivesBaseName", "red")
        }
        Blue {
            setProperty("archivesBaseName", "blue")
        }
    }


    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def path = "C:/AndroidBuilds/MyCompany.Build/" + "/"
            def SEP = "-"
            def flavor = variant.productFlavors[0].name
            def version = variant.versionCode
            def newApkName = path + version + SEP + flavor
            def newApkNameNoVersion = path + flavor
            output.outputFile = new File(newApkName + ".apk")

    }
}

dependencies {
    }
}

When I have got the white labeling working and the auto run for all of those I will tack that on this too.

Upvotes: 0

Views: 793

Answers (1)

Ben P.
Ben P.

Reputation: 54204

I apologize for not knowing the precise gradle terms of art, but...

I want all the builds to have the same version name and version code. If I leave the flavor config values empty, will they pick up the versions from the AndroidManifest.xml file?

If you don't specify versionCode or versionName in the productFlavors block, whatever you defined in the defaultConfig block will be applied.

Is it possible to have each APK have it's own application name when generated, such AppHeyYou.apk and WhereIsThat.apk for another flavor? The examples I have seen seem to tack on a suffix to the end of APK name, I need a completely new APK name (and without the "Release" tacked on).

Check out the applicationVariants property. It will let you write something like

applicationVariants.all { variant ->
    variant.outputs.each { output ->
        def newName = [build your filename here]
        output.outputFile = new File(output.outputFile.parent, newName);
    }
}

Can I have it build the flavor, then copy it and rename it (such as MyApp.apk and copy to 44-MyApp.apk) using the version from the AndroidManifest.xml or the default config? Since there are close to a 100, changing this in each flavor config would be not be practical with each release.

In the above applicationVariants.all block, you can access defaultConfig.versionCode and .versionName to create copies with filenames that include versioning info.

Is there a way to force the generation of ALL the white labels with a single push of the button. Again, doing this for each would be impractical.

I believe you can just run the command gradlew assemble. Running gradlew tasks outputs this (and a lot of other tasks):

Build tasks
-----------
assemble - Assembles all variants of all applications and secondary packages.

Upvotes: 1

Related Questions