26

In correspondence with Cordova news version 5.0.0 is ready. I tried to upgrade all my Android projects like it was usually.

To update Cordova framework itself:

npm update -g cordova

To update library in Android project:

cordova platform update android

After building new version using "--release" option:

cordova build android --release

I got only unsigned version. Strange...
So how is it possible to reuse existing keystore (previously generated by keytool and used by Cordova 4.0.0) to get signed APK?

Maxim
  • 13,029
  • 6
  • 30
  • 45

6 Answers6

50

It looks like Cordova 5.0.0 uses Gradle build automation system instead of Ant. So original settings for keystore defined in the file "/platforms/android/ant.properties" will not be used during building. So we will get unsigned APK as a result.

To solve this issue we need to tell Gradle to use existing keystore as well. Investigation of build.gradle gives us useful information that we need to provide signingConfigs.

But it is bad idea to do that in this file because it is labelled as auto-generated and it should be free of any editing.

So finally I have found the way to solve it. Object "signingConfigs" will be constructed from file with filename stored in cdvReleaseSigningPropertiesFile. In correspondence with documentation the default value of this variable is "release-signing.properties". So we need just to create new file with such name in the same folder as "build.gradle" file and put inside the following content:

storeFile=..\\..\\some-keystore.keystore
storeType=jks
keyAlias=some-key
// if you don't want to enter the password at every build, you can store it with this
keyPassword=your-key-password
storePassword=your-store-password

Path in example is specified for keystore saved in the project root directory. It has Windows style... In case of Linux you will need to use single slashes (not double backslashes like in above example).

In addition you can set your own path for signing settings file. To read more about that check the edge version of cordova documentation.

Maxim
  • 13,029
  • 6
  • 30
  • 45
  • Nice, but I think this has a problem, because you have to mantein a file in a platform speciffic folder. Maybe there's a way to create a hook that put that file in android folder? I'm trying with not success (My first time with hooks). Any clue? – Sebastián Rojas May 28 '15 at 21:44
  • Gradle files are required to build Android version. So it looks very straightforward to have all configuration files there. But you can create some file like build-release-android.cmd (build-release-android.sh) and put all commands there: 1. command for copying of config file 2. "cordova build android --release" command. – Maxim May 28 '15 at 22:49
  • @SebastiánRojasR What you are talking about is not specific for this question / answer. I fix this by creating a crossplatform directory on the same level as the plugin directory and config.xml in the project. I add files for android that need to be copied from there to the android build project result. Check out this article from Holly Schinsky on how to copy files from a non-platform specific location (see the part on copying images and edit that script): http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/ – EeKay Jun 11 '15 at 09:31
  • 3
    to clarify we need the put the configuration in `platform/android/release-signing.properties` – Cristian Jun 13 '15 at 22:55
45

According to official documentation (v5.1.1+) I've just added a build.json

{
     "android": {
         "release": {
             "keystore": "android.keystore",
             "storePassword": "storepassword",
             "alias": "mykey",
             "password" : "password",
             "keystoreType": ""
         }
     }
 }

and my existing android.keystore file in the root cordova folder.

cordova build android --release will do the trick, no hooks needed, the singned apk-file can then be found in ./platform/android/build/outputs/apk as android-release.apk .

  • 2
    Which folder did you put this build.json? – bertmaclin Jul 28 '15 at 07:31
  • @albertleao to the root of the project, from my trials, it's also simple to just put the .keystore to the root too, as Ronny suggests – Kaan Soral Aug 06 '15 at 14:59
  • Is there a way to put the build.json and keystore files into another folder? – Android Noob Aug 25 '15 at 18:30
  • 2
    This worked, but it seems that the path to the keystore is always considered to be relative to the build file, i.e. you can't put "D:\\SomeFolder\\mystore.keystore", you have to get to it using relative path ("..\..\SomeFolder\mystore.keystore", or similar) – veljkoz Aug 27 '15 at 14:38
  • 2
    This works perfectly, thanks for sharing! Do you know if there is a way to automatically change the name of the generated .apk file? – novas1r1 Sep 18 '15 at 08:46
  • Make sure you have the latest node.js/npm. This requires an "isAbsolute" call which I got burned on. – camster Nov 09 '15 at 01:37
  • Note to taco users. You can just add the build.json file in the root of your project. Same directory as taco.json and it will sign your android app. – muglio Dec 19 '15 at 06:20
  • Working with cordova 6.0.0 – Mikel Mar 17 '16 at 15:30
  • What is the difference between the 'storePassword' and the 'password'? I created my keystore using `keytool`, entered all the data and the password...and now have myApp.keystore compiled. I am assuming that password used is the `storePassword`. If so, then where does `password` come from? – rolinger Aug 03 '16 at 16:08
  • @veljkoz - I tried your relative path as: `"keystore": "\users\rpo\dev\appkeys\thisApp1.keystore",` and I got an error: `Error: Unexpected token s` - its not liking the path. And that path is a direct system root path to the .keystore. – rolinger Aug 03 '16 at 16:16
  • @rolinger When using the keytool correct, you have to enter the keystore password first, then some data like name and at the end the key password. If you hit there just return, it should be the same. – Ronny Elflein r11lein Aug 05 '16 at 10:40
  • Still working on cordova 6.5.0 and android platform version 6.2.2 – Andrew Paes Jun 28 '17 at 23:25
8

For cordova 5.1.1+, refer to Ronny Elflein r11lein answer https://stackoverflow.com/a/30980293/2163398

The current answer is good (by @maxim), but we want to keep platform-specific folder untouched, so we can maintain it out of version control. So I created this Hook to automatically copy the "release-signing.properties" file in android folder.

So, first, place your keystore in your project root. Then create the "release-signing.properties" in a the folder config, in the root of your cordova project. Contents (storeFile path in example is specified for keystore saved in the project root directory. It has Windows style... In case of Linux you will need to use single slashes):

storeFile=..\\..\\some-keystore.keystore
storeType=jks
keyAlias=some-key
// if you don't want to enter the password at every build, you can store it with this
keyPassword=your-key-password
storePassword=your-store-password

Then, add if not exists the "after_prepare" folder inside the "hooks" folder, and crete in it a file called "copy_assets.js".Contents:

#!/usr/bin/env node

// Files to be copied, with source and destination

var ncp = require('ncp').ncp,
    transfers = [
      {
        'source': './config/android/release-signing.properties',
        'destination': './platforms/android/release-signing.properties'
      }
    ];

ncp.limit = 16;

transfers.forEach(function(transfer) {
  ncp(transfer.source, transfer.destination, function (err) {
    if (err) {
      return console.error(err);
    }
    console.log('====== Assets moved from ' + transfer.source + ' to ' + transfer.destination + ' ======');
  });
});

If you don't hace ncp in your project, open a command promt in the project folder root and run the command (it's posible you need to create a a packages.json file in your project root):

npm install ncp

Then, you can run:

cordova build android --release
Community
  • 1
  • 1
Sebastián Rojas
  • 2,776
  • 1
  • 25
  • 34
4

To automate build release process you should create "build.json" on your project's folder and include the following content:

{
 "android": {
     "release": {
         "keystore": "android.keystore",
         "storePassword": "storepassword",
         "alias": "mykey",
         "password" : "password",
         "keystoreType": ""
     }
 }
}

The keytore is generated using

keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

If you already have a keystore file just run the command below to know the required content

keytool -list -keystore .keystore

Then you just have to run

cordova build android --release
Filipe Pinto
  • 311
  • 3
  • 17
  • What is the difference between the 'storePassword' and the 'password'? I created my keystore using `keytool`, entered all the data and the password...and now have myApp.keystore compiled. I am assuming that password used is the `storePassword`. If so, then where does `password` come from? – rolinger Aug 03 '16 at 16:07
2

Steps - 1) Generate keystore certificate

Syntax -  keytool -genkey -v -keystore C:\DIR\APPNAME.keystore -alias APPNAME -keyalg RSA -keysize 2048 -validity 10000
  • 2) Copy generated keystore file and paste in cd platforms\android
  • 3) Specify signing config for Gradle Create file property file - release-signing.properties (file name) Write bellow keys and values

    Syntax

            storeFile=..\\..\\some-keystore.keystore
            storeType=jks (pkcs12 for p12,jks for keystore)
            keyAlias=some-key
            // if you don't want to enter the password at every build, you can store it with this
            keyPassword=your-key-password
            storePassword=your-store-password
    

Example

        storeFile= abc.keystore
        storePassword=mypass
        storeType=jks
        keyAlias=abc
        keyPassword=mypass
  • 4) Build cordova project

cordova build android --release

  • 5) Run cordova project

cordova run android --release

  • 6) Relese APK created in following path -

platforms\android\build\outputs\apk

Ravi
  • 2,360
  • 1
  • 15
  • 11
1

In the latest gradle version it is also possible to create a file named "release-signing.properties" at the "\platforms\android\" folder. The contents should be:

storeFile=<your key>.keystore
storeType=jks
keyAlias=<your_alias>
keyPassword=<your_passwd>
storePassword=<your_passwd>

The file ".keystore" should be in the same folder.

Filipe Pinto
  • 311
  • 3
  • 17
  • Worth remembering - whilst keytool lets you work with passwords and aliases that are non-alphanumeric Cordova appears to have trouble with these. In my own case I spent a fair amount of time till I realized that Cordova did not like the exclamation marks in my passwords – DroidOS Feb 03 '17 at 08:10