4

I've a multi flavor project which is built by a CI and published to HockeyApp. Each flavor has an applicationId and an apiToken, which is stored in the flavor itself (to keep all important variables in one place):

    def token = null

    productFlavors {

    prod {
        applicationId "de.example.appname"

        buildConfigField 'String', 'FLAVOR_ID', '"0"'
        buildConfigField 'String', 'HOCKEY_APP_ID', '"1234567890"'

        token = "1q2w3e4r5t6z7u8i9o0p"
    }

    demo {
        applicationId "de.example.appname.demo"

        buildConfigField 'String', 'FLAVOR_ID', '"1"'
        buildConfigField 'String', 'HOCKEY_APP_ID', '"987654321"'

        token = "p0o9i8u7z6t5r4e3w2q1"
    }
}

On the same level like "productFlavors" there are the hockeyApp-settings:

    hockeyapp {
       apiToken = token
       releaseType = 0
       notify = 0
       status = 1
       notesType = 1
       notes = "Uploaded with gradle"
    }

For debugging the code I build & upload the .apk-file via terminal:

./gradlew uploadProdReleaseToHockeyApp [...]

Unfortunately the variable token of the prod-flavor is always overridden by the demo-value. So after each uploading process I get errors like

Error response from HockeyApp: App could not be created.

because gradle tries to upload the prod-flavor with the demo-token.

Here some additional basic data:

compileSdkVersion 24
buildToolsVersion "24.0.1"
compile 'net.hockeyapp.android:HockeySDK:4.0.0'
classpath 'com.android.tools.build:gradle:2.1.3'
classpath 'de.felixschulze.gradle:gradle-hockeyapp-plugin:3.5'

Based on my requirements, is there a solution to define flavor-variables and access them in the shown way?

Ekta Padaliya
  • 5,743
  • 3
  • 39
  • 51
JU5T1C3
  • 678
  • 1
  • 9
  • 26
  • This seems identical to [this unanswered question](http://stackoverflow.com/questions/35956182/is-there-a-way-to-change-gradle-variable-value-based-on-selected-productflavor?rq=1). See also [this thread](http://stackoverflow.com/questions/17197636/is-it-possible-to-declare-a-variable-in-gradle-usable-in-java), which may provide a solution. – Ted Hopp Oct 07 '16 at 07:48
  • Hey found any solution yet?i am looking for the same. – iMDroid Nov 03 '17 at 03:58
  • @iMDroid take a look at my correct marked answer ;-) – JU5T1C3 Nov 03 '17 at 13:19
  • @JU5T1C3 Great. thanks alot. – iMDroid Nov 06 '17 at 09:45

2 Answers2

2

In this special case I found following answer:

Add the hockeyapp-task with your modifications needed

hockeyapp {
    apiToken = "not_required"
    releaseType = 0
    notify = 0
    status = 2
    teams = 1234
    notesType = 1
}

In the next step add flavor-based gradle tasks to modify you hockeyapp's apiToken:

task setDevReleaseApiToken << {
    hockeyapp.apiToken = "1234567890abcdefghijklmnopqrstuvwxyz"
}

task setProdReleaseApiToken << {
    hockeyapp.apiToken = "1234567890abcdefghijklmnopqrstuvwxyz"
}

These tasks are called in gradle's whenTaskAdded-task, you can simply "override" it like this:

tasks.whenTaskAdded { task ->
    if (task.name == 'uploadDevReleaseToHockeyApp') {
        task.dependsOn 'setDevReleaseApiToken'
    } else if (task.name == 'uploadProdReleaseToHockeyApp') {
        task.dependsOn 'setProdReleaseApiToken'
    }
}

Everytime the task uploadDevReleaseToHockeyApp is called (manually or by CI..) the task setDevReleaseApiToken is called and the related apiToken is assigned.

Extend this schema for all other flavors if needed!

JU5T1C3
  • 678
  • 1
  • 9
  • 26
1

Though the OP might not be looking for an answer anymore, someone other might stumble upon this thread (like I did when I was dealing with this problem) so I'd like to share a solution.

I was dealing with variables having effect on gradle procedure itself (not on the source code) so I couldn't use resValue or buildConfigField.

This problem can be solved by using the settings.gradle file. This file executes before build.gradle, so you can prepare all your variables using this condition:

include ':project...'
rootProject.name = 'name...' 

def VARIANT1 = "YourFlavorName";
        if((gradle.startParameter.taskNames.contains(":assemble"+VARIANT1+"Debug"))||
    (gradle.startParameter.taskNames.contains(":assemble"+VARIANT1+"Release"))
        ||
    (gradle.startParameter.taskNames.contains(":generate"+VARIANT1+"DebugSources"))||(gradle.startParameter.taskNames.contains(":generate"+VARIANT1+"ReleaseSources"))) {
          gradle.ext.variable = value
          gradle.ext.var...
            }

It is a bit of a work-around but what this does is it checks the build commands given by your Android Studio and searches for the flavor name inside. Conditions with ":generate" are just for Building, ":assebmle" is for Running the application on a device.

Any variable you create in your settings file like this can be accessed from your build.gradle file.

myVariable = gradle.ext.variable

This should do it.