8

I´m trying to sign my app with the gradle build file. When I use the plain signingConfigs it works (signingConfigs.release)! But If I´m trying to read the properties from the properties-file it won´t work. (signingConfigs.config)

Properties props = new Properties();
props.load(new FileInputStream(file(rootProject.file("signing.properties"))))

android {
        signingConfigs {
            config {
                storeFile file(props["storeFile"])
                storePassword props["storePassword"]
                keyAlias props["keyAlias"]
                keyPassword props["KeyPassword"]
            }
            release {
                storeFile file("..\\xyz.jks")
                storePassword "****"
                keyAlias "****"
                keyPassword "****"
            }
        } 
    .
    .
    .
        buildTypes {
            release {
                runProguard false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
                signingConfig signingConfigs.release
            }
            debug {
                applicationIdSuffix '.debug'
                versionNameSuffix '-SNAPSHOT'
            }
        }

Properties file:

storeFile=xyz.jks
storePassword=xyz
keyAlias=xyz
keyPassword=xyz

When I run the project, android studios show a dialog which says:

xyz.apk is not signed. Please configure the signing information for the selected flavor using the Project Structure dialog.

The property file is read correctly because I can log some properties from the file throw the console.

Some of my system details:

Android Studio 0.8.6 Windows 8.1 x64 gradle 1.12

Hope anyone can help me. If you want to know more details, then ask me.

Adam
  • 302
  • 1
  • 3
  • 8

4 Answers4

18

This is what I do and it works for me:

signingConfigs {
    release {
        def Properties localProps = new Properties()
        localProps.load(new FileInputStream(file('../local.properties')))
        def Properties keyProps = new Properties()
        assert localProps['keystore.props.file'];
        keyProps.load(new FileInputStream(file(localProps['keystore.props.file'])))
        storeFile file(keyProps["store"])
        keyAlias keyProps["alias"]
        storePassword keyProps["storePass"]
        keyPassword keyProps["pass"]
    }
}

My local.properties file contains a path to a "keystore.properties" file. That contains my info about the keystore:

store=***
alias=***
pass=***
storePass=***

Perhaps the loading of two Propreties file is redundant, but it does work for me.

ariets
  • 4,218
  • 4
  • 28
  • 34
  • Thanks for the answers. your solution works, but can someone explain me why? – Adam Aug 14 '14 at 14:28
  • Yeah. First, you're loading in the local.properties file. This then loads in your a that contains your keystore (keystore.props.file). Doing it this way allows you to define a separate path (not within your project) to where you keystore properties are so you can upload to a git repo without worry. – ariets Mar 24 '15 at 20:30
  • I am getting a `Cannot resolve symbol 'Properties'` Is that expected? Also the assertion: `assert localProps['keystore.props.file'];` fails! – reubenjohn Aug 08 '15 at 10:52
  • Never mind, the issue was that my `local.properties` file was missing the `keystore.props.file=../keystore.properties` line. And fixing that and updating my Android Studio gradle plugin to the latest version fixed the resolution of `Properties` – reubenjohn Aug 08 '15 at 11:08
  • I am still confused over that redundant use of 'Properties'...!! :( – eRaisedToX Aug 21 '17 at 16:20
3

Here is a complete step-by-step that I took to use a properties file to move both of my keys out of the gradle.build file into a file that will not be included in any builds or repository commits.

1) Create a gradle.properties (if you don't already have one).

The location for this file depends on your OS:

   /home/<username>/.gradle/ (Linux)
   /Users/<username>/.gradle/ (Mac)
   C:\Users\<username>\.gradle (Windows)

2) Add an entry pointing to yourprojectname.properties file. (example for Windows)

yourprojectname.properties=c:\\Users\\<username>\\signing\\yourprojectname.properties

3) Create yourprojectname.properties file in the location you specified in Step 2 with the following information:

keystore=C:\\path\\to\\keystore\\yourapps.keystore
keystore.password=your_secret_password

4) Modify your gradle.build file to point to yourprojectname.properties file to use the variables.

if(project.hasProperty("yourprojectname.properties")
        && new File(project.property("yourprojectname.properties")).exists()) {

    Properties props = new Properties()
    props.load(new FileInputStream(file(project.property("yourprojectname.properties"))))

    android {
        signingConfigs {
            release {
                keyAlias 'release'
                keyPassword props['keystore.password']
                storeFile file(props['keystore'])
                storePassword props['keystore.password']
            }
            debug {
                keyAlias 'debug'
                keyPassword props['keystore.password']
                storeFile file(props['keystore'])
                storePassword props['keystore.password']
            }
        }
        compileSdkVersion 19
        buildToolsVersion "20.0.0"
        defaultConfig {
            applicationId "your.project.app"
            minSdkVersion 16
            targetSdkVersion 17
        }
        buildTypes {
            release {
            }
        }
    }

}

dependencies {
    ...
}

5) Enjoy! Now all of your keys will be outside of the root of the directory and yet you still have the joys of automation for each build.

If you get an error in your gradle.build file about the "props" variable it's because you are not executing the "android {}" block inside the very first if condition where the props variable gets assigned so just move the entire android{ ... } section into the condition in which the props variable is assigned then try again.

I pieced these steps together from the information found here and here.

Max Worg
  • 2,932
  • 2
  • 20
  • 35
  • I guess you need to rephrase your answer, your steps are not clear (not to me atleast ). may be look from a reader's end ! – eRaisedToX Aug 21 '17 at 16:16
  • What if I have 2 kinds of release, each with a different key-alias ? How can I set it properly? I've asked about this here: https://stackoverflow.com/q/75434891/878126 , but sadly I think what was offered to me doesn't work. – android developer Mar 15 '23 at 09:10
1

I found the mistake!!! The problem was case-sensitive! I write

keyPassword props["KeyPassword"]

but the file contains only

keyPassword

Why does gradle don´t tell me?

Adam
  • 302
  • 1
  • 3
  • 8
1

An alternative to juggling variables is to include/apply a gradle file containing the signing configs.

So in your build.gradle

android {
// the part to include
    if (project.hasProperty("yourproject.signing") && new File(project.property("yourproject.signing")).exists()) {
        println 'apply yourproject signing property';
        apply from: project.property("yourproject.signing");
    } else {
        println 'no yourproject signing property';
    }
// the rest of the usual stuff
    compileSdkVersion etc.

In your .gradle directory (depends on your OS where it is) add a gradle.properties file, or if it exists, add the following line

yourproject.signing=*the full path to your magic file*signing.gradle

In the file pointed to by the above entry you include the signing configs as you would in the build.gradle file

android {
    signingConfigs {
        release {
            keyAlias '*your release key alias*'
            keyPassword '*your key password*'
            storeFile file('*the full path to your keystore file*.jks')
            storePassword '*your keystore password*'
        }
    }
}

Yes, the extra android wrapping has to be there. The advantage being that the above is a regular gradle file, so you can do all the magic you want in there.

Add more signingConfigs as needed, use the usual way, e.g.

signingConfig signingConfigs.release
mir
  • 371
  • 2
  • 5