We were unable to load Disqus. If you are a moderator please see our troubleshooting guide.

Davy Jones • 9 years ago

And how do you use this configs to generate apk ? If i do "Build-> Generate Signed apk" from menu, i guess it will ask to enter keystore file and password manually. Does this valid for ./gradlew assembleRelease command ??

Rafael Ortiz Nunes • 1 year ago

Thank you.

AD_LB • 2 years ago

This works fine, but what if I have 2 apps set inside the gradle file, each with a different package name and each needs to use a different key-alias?
I asked it here and I thought it works fine, but it actually produced me APK files that use debug variant instead of release variant:
https://stackoverflow.com/a...

Umar Isa Abdulkadir • 8 years ago

Hi please can you help me on how to fix this error? the build.gradle is below

Gradle sync failed: You should define KEYSTORE_PASSWORD, KEYSTORE_ALIAS and KEY_PASSWORD in gradle.properties.groovy.lang.MissingPropertyException: Could not get unknown property 'KEYSTORE_PASSWORD' for SigningConfig_Decorated{name=release, storeFile=C:\Users\user\Downloads\umar\shopping\app\openshopKeystore.jks, storePassword=null, keyAlias=null, keyPassword=null, storeType=C:\Users\user\Downloads\umar\shopping\app\openshopKeystore.jks, v1SigningEnabled=true, v2SigningEnabled=true} of type com.android.build.gradle.internal.dsl.SigningConfig.

Thanks for this post! One thing I don't understand - why do we need:



if(project.hasProperty("MyProject.signing")
&& new File(project.property("MyProject.signing") + ".gradle").exists()) {

In my opinion it is better to remove the condition and let the gradle raise error when there is no property or file.

PeteFrmNY • 7 years ago

this is a late response but for anything who comes across this later...

it's a good idea if your project is git synced for 2 scenarios:

1. someone gains unauthorized access to the git project. You don't want them being able to mess with your app in the play store
2. only certain people on the team are allowed to generate the final signed apks for the play store.

KB • 9 years ago

Hi Tim, thanks for the tutorial. I have a question about fetching file via https, would it be possible? Sorry, if this question comes as a silly question. I have been on android studio for a little while now but just start to learn all of this last night, so I am really new to all these concepts.

Tim Roes • 9 years ago

Hi KB, do you mean fetching config files (with e.g. passwords and such) from the internet? You can extract and apply parts of the build file via apply from: 'foo'. "foo" doesn't have to be a local path, you could also apply files via HTTP as follows:


apply from: 'https://example.com/repository/base.gradle

But this comes fro the cost of your build not working anymore without a network connection. There is a Gradle caching plugin out there, that allows using HTTP and have a working cache.

In general: The build.gradle file is "just" a Groovy script executed. So you can use any Groovy magic you want to do in it what you want. And since Groovy is a near superset of Java (and you are not familiar with Groovy enough) you can use whatever Java you want in it :-)

KB • 9 years ago

Thanks Tim, I think I get it. Just for my curiosity, why do the creators of groovy make it very flexible? I feel if a mistake makes to the program, it will be hard to debug. Also Is there any tool do you use to debug groovy (gradle in this case)? Really appreciate for your help and advice.

Tim Roes • 9 years ago

I think you mean the creators of Gradle made it very flexible (since Groovy is just a programming language, and as flexible as a programming language usually is). For Gradle: it's always the trade-off in any build system between configuration vs. coding.

Maven for example is pure configuration, but that has the drawback of you require a plugin (in worst case write it yourself) for any simple task, that is not part of the core configuration. In Gradle if it's just small you can just write the stuff as Groovy code inside your build script, and if you need it more often or it gets larger just exclude it in a plugin when needed. E.g. we began reading out the version number of our software from Git tags, and just wrote the 5-10 lines of code needed for this into the build.gradle. Once we used it in several project, we just extracted it into a plugin: gradle-git-version and now it's a one liner to include it in any new project. So it's always the balance between flexibility vs. static configuration. Both have their advantages and disadvantages.

Since Groovy just runs in the JVM, you can actually use the regular debugging options there. If you use the Gradle wrapper script - and you should do so - you will find DEFAULT_JVM_OPTS="" in one of the first lines, where you can add the Java debugging options and attach any debugger. You should e.g. be able to use IntelliJ IDEA debugger, to attach to this (and it also prints you out the parameters you need to add there). I've never actually tried to debug a Groovy script, so this is more a "should work" than "does work".

KB • 9 years ago

Thanks Tim for your explanation.

DhrupalPPatel • 9 years ago

Hello Tim,
I am reading apk version code from properties file and increment it on every build. But I want to to inc it only on time of signing. Can yo please help me in that? Following is my code:


android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
def versionPropsFile = file('version.properties')

if (versionPropsFile.canRead()) {
def Properties versionProps = new Properties()

versionProps.load(new FileInputStream(versionPropsFile))

def code = versionProps['build.version'].toInteger() + 1

versionProps['build.version']=code.toString()
versionProps.store(versionPropsFile.newWriter(), null)

defaultConfig {
applicationId "com.test"
multiDexEnabled true
versionCode code
versionName versionProps['product.version']
minSdkVersion 18
targetSdkVersion 23
}
}
else {
throw new GradleException("Could not read version.properties!")
}
......
}
Tim Roes • 9 years ago

Hi, you would need to do the read out all the time. Just move the increasing of the version number to a separate block, that will only be executed when signing. (How to execute code only when a specific task is executed, you can see here: https://www.timroes.de/2014.... So in pseudo code it might look like that:

def readVersion = {
// what you already did to read it out
return version
}

android {
defaultConfig {
versionCode readVersion()
}
}

// To check whether a specific task will be executed, we need to wait for the taskGraph to be ready
gradle.taskGraph.whenReady { taskGraph ->
if(taskGraph.hasTask(':app:assembleRelease')) {
// If the assembleRelease task is executed (or use some task else you require)
// Do here the increasing of the version number and write it back to file
project.android.defaultConfig.versionCode newVersionCode
}
}

DhrupalPPatel • 9 years ago

When I generate sign apk it never comes in if(taskGraph.hasTask(':app:assembleRelease'))

Tim Roes • 9 years ago

Is your task really called like that? Perhaps your submodule isn't named app ? You can use `./gradlew tasks` to list all tasks.

DhrupalPPatel • 9 years ago
Kevin Chris • 9 years ago

In Windows I'm using Android Studio, for me MyProject.properties is in "C:\Users\Username\.gradle\myproject.properties". How do I give this? If I give with single/double quotes it gives me error unable to find properties for MyProject. As you have mentioned instead of / if I try to use \\ it gives me error Unexpected Symbol. How to resolve this?

Luis E Alvarado • 9 years ago

Hey there, hope you see this, or at least anyone else in this situation.

For Windows, you still use Windows paths - but you actually want to prepend the folder paths with '/'.
So, for the path given above, it should read:
"C:/\Users/\Username/\.gradle/\myproject.properties"

Okan • 10 years ago

Hi Tim,

As far as I understood, you keep the important data, like password or keystores, in your own machine. But what if your are working in Circle Integration environment, building the project in a Virtual Machine in a server ? You will need to keep your data there in the Virtual Machine as well.

And if you are using a third party continuous integration server, what would be the most secure way to keep your important files safe.

Thanks.

Tim Roes • 10 years ago

Hei,

yeah the solution only shows how to work with this kind of stuff on a local developer machine.
For usage of keys on CI servers I haven't found the perfect solution yet for me.

You could just upload and store the key on the jenkins machine (or vm) and reference it there.
If you mean with third party CI server, a server owned by someone else, I doubt that there is a really secure way, since
you need to upload the key at some time to the server.
I am common to use own jenkins instances. If these are provisioned by any common tool (puppet and such) you can use this
to also place the keys on them. But you will still need to store them somewhere where the provision tools can reach them.

As mentioned, nothing of these solutions made me really happy, and unfortunately I haven't build up any ideas about 3rd part
build servers, that could be of any help in that situation.

Please feel free to share any solutions you will find or work on with the world.

Cheers
Tim

Wayne Piekarski • 11 years ago

It is possible to take any existing Android Studio gradle project and build/sign it from the command line without editing any files. This makes it very nice for storing your project in version control while keeping your keys and passwords separate from your build.gradle file:


./gradlew assembleRelease -Pandroid.injected.signing.store.file=$KEYFILE -Pandroid.injected.signing.store.password=$STORE_PASSWORD -Pandroid.injected.signing.key.alias=$KEY_ALIAS -Pandroid.injected.signing.key.password=$KEY_PASSWORD

Timothy Kist • 11 years ago

Worked a treat. Took a while to get it to work, though. The problem I was having was thinking that the project name had to be the same as the .properties file and getting all the naming of properties and files right so it's referencing everything correctly. Figured it out now. I went for option 3 in the end after trying to make option 1 work.

Can you specify that the DSL line needs to go inside the android {...} part of the gradle file, not at the end?

Also, if you're on Windows, use double backslashes \\ instead of a forward slash '/' for the path.

Tim Roes • 11 years ago

I am not sure what you mean by DSL line :-) But if you meant the missing android { } around the signingConfig block, I added that and added a sentence about the windows pathes in the top.

Sim • 12 years ago

Hey,
I'm getting this exception on build in myproject.gradle:

" Invalid variable name. Must start with a letter but was: “MyProject
. At [4:36] @ line 4, column 36.
storeFile file(project.property(“MyProject.signing”) + “.keystore”)

Pretty confused. Any ideas?
Thanks!

Igor Ganapolsky • 12 years ago

What about proguard. Do you use that in your gradle configs?

Tim Roes • 12 years ago

I haven't tested ProGuard yet with Gradle, but ProGuard itself has a explanation in their docs on how to integrate it with Gradle: http://proguard.sourceforge...

Igor Ganapolsky • 12 years ago

What about the keyAlias and keyPassword values? How should those be set in myproject.properties?

Tim Roes • 12 years ago

I guess you are talking about the 3rd option, where you store plain text files in a properties file? In that case you can just write:

keyAlias=myKeyAlias
keyPassword=password

in your myproject.properties file, and load them via the Properties object (as shown in the last code snippet).

Grantland Chew • 12 years ago

You don't want to include the quotes in the gradle.properties file as it will use them in the path, which will cause the file to be not found. At least that's what happened to me with OS X.

Tim Roes • 12 years ago

Thanks. I changed it.