I am trying to setup signing process so that keystore password and key password are not stored in the project\'s build.gradle
file.
Cur
Alternatively, if you want to apply Scott Barta's answer in a way more similar to the auto generated gradle code, you can create a keystore.properties
file in your project root folder:
storePassword=my.keystore
keyPassword=key_password
keyAlias=my_key_alias
storeFile=store_file
and modify your gradle code to:
// Load keystore
def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
...
android{
...
signingConfigs {
release {
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
...
}
You can store this properties file in the root of your module, in which case just omit rootProject
, and you can also modify this code to have several sets of properties for different keystores and key aliases.
Inspired from https://stackoverflow.com/a/33218300/1673761 with some improvements
android
folder for React Native):app.keystore
keystore.properties
.gitignore
keystore.properties
addSTORE_FILE=app.keystore
KEY_ALIAS=app_alias
STORE_PASSWORD=your_password
KEY_PASSWORD=your_password
app/build.gradle
add// Load keystore
def keystoreProperties = new Properties()
try {
def keystorePropertiesFile = rootProject.file("keystore.properties");
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
} catch(IOException e) {
// We don't have release keys, ignoring
}
...
android {
...
signingConfigs {
release {
if (keystoreProperties['STORE_FILE']) {
storeFile rootProject.file(keystoreProperties['STORE_FILE'])
storePassword keystoreProperties['STORE_PASSWORD']
keyAlias keystoreProperties['KEY_ALIAS']
keyPassword keystoreProperties['KEY_PASSWORD']
}
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}
PS: Edits to improve the groovy logic are welcome
The accepted answer use a file to controls which keystore to use to sign the APK that resides in the same root folder of project. When we using vcs like Git, could be a bad thing when we forget to add the properties file to ignore list. Because we will disclose our password to the world. The problems still persist.
Instead making properties file in the same directory within our project, we should make it outside. We make it outside by using gradle.properties file.
Here the steps:
1.Edit or create gradle.properties on your root project and add the following code, remember to edit the path with your own:
AndroidProject.signing=/your/path/androidproject.properties
2.Create androidproject.properties in /your/path/ and add the following code to it, don't forget to change /your/path/to/android.keystore to your keystore path:
STORE_FILE=/your/path/to/android.keystore
STORE_PASSWORD=yourstorepassword
KEY_ALIAS=yourkeyalias
KEY_PASSWORD=yourkeypassword
3.In your app module build.gradle (not your project root build.gradle) add the following code if not exist or adjust to it:
signingConfigs {
release
}
buildTypes {
debug {
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
}
4.Add the following code below the code in step 3:
if (project.hasProperty("AndroidProject.signing")
&& new File(project.property("AndroidProject.signing").toString()).exists()) {
def Properties props = new Properties()
def propFile = new File(project.property("AndroidProject.signing").toString())
if(propFile.canRead()) {
props.load(new FileInputStream(propFile))
if (props!=null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&
props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
} else {
println 'androidproject.properties found but some entries are missing'
android.buildTypes.release.signingConfig = null
}
} else {
println 'androidproject.properties file not found'
android.buildTypes.release.signingConfig = null
}
}
This code will search for AndroidProject.signing property in gradle.properties from step 1. If the property found, it will translate property value as file path which pointing to androidproject.properties that we create in step 2. Then all the property value from it will be used as signing configuration for our build.gradle.
Now we don't need to worry again of risk of exposing our keystore password.
Read more at Signing Android apk without putting keystore info in build.gradle
The nice thing about Groovy is that you can freely mix Java code, and it's pretty easy to read in a key/value file using java.util.Properties
. Perhaps there's an even easier way using idiomatic Groovy, but Java is still pretty simple.
Create a keystore.properties
file (in this example, in the root directory of your project next to settings.gradle
, though you can put it wherever you like:
storePassword=...
keyPassword=...
keyAlias=...
storeFile=...
Add this to your build.gradle
:
allprojects {
afterEvaluate { project ->
def propsFile = rootProject.file('keystore.properties')
def configName = 'release'
if (propsFile.exists() && android.signingConfigs.hasProperty(configName)) {
def props = new Properties()
props.load(new FileInputStream(propsFile))
android.signingConfigs[configName].storeFile = file(props['storeFile'])
android.signingConfigs[configName].storePassword = props['storePassword']
android.signingConfigs[configName].keyAlias = props['keyAlias']
android.signingConfigs[configName].keyPassword = props['keyPassword']
}
}
}
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 and not in 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
The easiest way is to create a ~/.gradle/gradle.properties
file.
ANDROID_STORE_PASSWORD=hunter2
ANDROID_KEY_PASSWORD=hunter2
Then your build.gradle
file can look like this:
android {
signingConfigs {
release {
storeFile file('yourfile.keystore')
storePassword ANDROID_STORE_PASSWORD
keyAlias 'youralias'
keyPassword ANDROID_KEY_PASSWORD
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
}
}