Ionic toturial for building a release.apk


#1

Hey, so i just had to go through the struggle of building this so i made a step by step tutorial from things i found from other posts

  1. Add android platform with the CLI :

    ionic platform add android

2)Now navigate to platforms/android with the CLI :

cd platforms/android
  1. Generate a key.store file with the CLI and answer all the questions:

    keytool -genkey -v -keystore YourApp.keystore -alias YourApp -keyalg RSA -keysize 2048 -validity 10000

To avoid having to build, sign, then zipalign we can accomplish all three in one step by doing the following.

  1. In the platforms/android directory create a file called ant.properties if it doesn’t already exist. Add the following to the file to contain your key.store:

    key.store=YourApp.keystore
    key.alias=YourApp

  2. Create a secure.properties file to contain your passwords.

    key.store.password=
    key.alias.password=

  3. Add the following lines inside the tag to your custom_rules.xml file to tell the build system about your secure.properties file.

  4. Now go back to the root of your Ionic project with the CLI and build a release version:

    cd …
    cd …
    ionic build android --release

That’s it, no signing, zip align or password prompt just one clean build which should generate a CordovaApp-release.apk
lots of this came from @nicraboy his blog : https://blog.nraboy.com/2014/09/signing-apache-cordova-android-app-release/


Ionic 2 App is reported as Malware PUA - Virustotal
Package applications via CLI
"ionic build android" create an UNALIGNED.AKP file
"There is a problem parsing the package"
#2

Thanks for the referral


#3

your tuts are rulez dude!! =)


#4

I have tried as you says… but raises build error


#5

What is the error? Please paste your full logs.


#6

Here is the error:

E:\PROJECTS\mob-sp>ionic build android --release
Running command: “C:\Program Files\nodejs\node.exe” E:\PROJECTS\mob-sp\hooks\after_prepare\010_add_platform_class.js E:\PROJECTS\mob-sp
add to body class: platform-android
Running command: “C:\Program Files\nodejs\node.exe” E:\PROJECTS\mob-sp\hooks\after_prepare\020_remove_sass_from_platforms.js E:\PROJECTS\mob-sp
Running command: E:\PROJECTS\mob-sp\platforms\android\cordova\build.bat --release
Buildfile: E:\PROJECTS\mob-sp\platforms\android\build.xml

-set-mode-check:

-set-release-mode:

-release-obfuscation-check:
[echo] proguard.config is ${proguard.config}

-pre-build:

-check-env:
[checkenv] Android SDK Tools Revision 24.0.2
[checkenv] Installed at C:\Program Files\Android\android-sdk

-setup:
[echo] Project Name: Studypress
[gettype] Project Type: Application

-build-setup:
[getbuildtools] Using latest Build Tools: 21.1.1
[echo] Resolving Build Target for Studypress…
[gettarget] Project Target: Android 4.4.2
[gettarget] API level: 19
[echo] ----------
[echo] Creating output directories if needed…
[echo] ----------
[echo] Resolving Dependencies for Studypress…
[dependency] Library dependencies:
[dependency]
[dependency] ------------------
[dependency] Ordered libraries:
[dependency]
[dependency] ------------------
[echo] ----------
[echo] Building Libraries with ‘release’…

nodeps:

-set-mode-check:

-set-release-mode:

-release-obfuscation-check:
[echo] proguard.config is ${proguard.config}

-pre-build:

-check-env:
[checkenv] Android SDK Tools Revision 24.0.2
[checkenv] Installed at C:\Program Files\Android\android-sdk

-setup:
[echo] Project Name: Studypress
[gettype] Project Type: Android Library

-build-setup:
[getbuildtools] Using latest Build Tools: 21.1.1
[echo] Resolving Build Target for Studypress…
[gettarget] Project Target: Android 4.4.2
[gettarget] API level: 19
[echo] ----------
[echo] Creating output directories if needed…
[echo] ----------
[echo] Resolving Dependencies for Studypress…
[dependency] Library dependencies:
[dependency] No Libraries
[dependency]
[dependency] ------------------

-code-gen:
[mergemanifest] Found Deleted Target File
[mergemanifest] Merging AndroidManifest files into one.
[mergemanifest] Manifest merger disabled. Using project manifest only.
[echo] Handling aidl files…
[aidl] No AIDL files to compile.
[echo] ----------
[echo] Handling RenderScript files…
[echo] ----------
[echo] Handling Resources…
[aapt] Found new input file
[aapt] Generating resource IDs…
[echo] ----------
[echo] Handling BuildConfig class…
[buildconfig] No need to generate new BuildConfig.

-pre-compile:

-compile:
[echo] Creating library output jar file…

-post-compile:

-obfuscate:

-dex:
[echo] Library project: do not convert bytecode…

-crunch:
[crunch] Crunching PNG Files in source dir: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\res
[crunch] To destination dir: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\res
[crunch] Crunched 0 PNG files to update cache

-package-resources:
[echo] Library project: do not package resources…

-package:
[echo] Library project: do not package apk…

-post-package:

-release-prompt-for-password:

-release-nosign:
[echo]
[propertyfile] Updating property file: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\build.prop
[propertyfile] Updating property file: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\build.prop
[propertyfile] Updating property file: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\build.prop
[propertyfile] Updating property file: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\build.prop

-release-sign:

-post-build:

release:

-code-gen:
[mergemanifest] Found Deleted Target File
[mergemanifest] Merging AndroidManifest files into one.
[mergemanifest] Manifest merger disabled. Using project manifest only.
[echo] Handling aidl files…
[aidl] No AIDL files to compile.
[echo] ----------
[echo] Handling RenderScript files…
[echo] ----------
[echo] Handling Resources…
[aapt] Found Deleted Target File
[aapt] Generating resource IDs…
[echo] ----------
[echo] Handling BuildConfig class…
[buildconfig] No need to generate new BuildConfig.

-pre-compile:
[echo] Set jars path to: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\classes.jar

-compile:
[javac] Compiling 2 source files to E:\PROJECTS\mob-sp\platforms\android\ant-build\classes
[javac] warning: [options] source value 1.5 is obsolete and will be removed in a future release
[javac] warning: [options] target value 1.5 is obsolete and will be removed in a future release
[javac] warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
[javac] 3 warnings

-post-compile:

-obfuscate:

-dex:
[dex] input: E:\PROJECTS\mob-sp\platforms\android\ant-build\classes
[dex] input: E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\classes.jar
[dex] Using Pre-Dexed classes-eb297a97df999646c8f3f61bd1627d9e.jar <- E:\PROJECTS\mob-sp\platforms\android\CordovaLib\ant-build\classes.jar
[dex] Found Deleted Target File
[dex] Converting compiled files and external libraries into E:\PROJECTS\mob-sp\platforms\android\ant-build\classes.dex…
[dx] Merged dex A (18 defs/9.6KiB) with dex B (209 defs/316.7KiB). Result is 227 defs/396.5KiB. Took 0.3s

-crunch:
[crunch] Crunching PNG Files in source dir: E:\PROJECTS\mob-sp\platforms\android\res
[crunch] To destination dir: E:\PROJECTS\mob-sp\platforms\android\ant-build\res
[crunch] Crunched 0 PNG files to update cache

-package-resources:
[aapt] Found Deleted Target File
[aapt] Creating full resource package…
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern ‘.’)
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern '.
’)
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern ‘.’)
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern '.
’)
[aapt] (skipping file ‘.gitignore’ due to ANDROID_AAPT_IGNORE pattern ‘.’)
[aapt] (skipping file ‘.travis.yml’ due to ANDROID_AAPT_IGNORE pattern '.
’)
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern ‘.’)
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern '.
’)
[aapt] (skipping file ‘.bower.json’ due to ANDROID_AAPT_IGNORE pattern ‘.*’)

-package:
[apkbuilder] Found Deleted Target File
[apkbuilder] Creating Studypress-release-unsigned.apk for release…

-post-package:

-release-prompt-for-password:

-release-nosign:

-release-sign:
[echo] Signing final apk…

BUILD FAILED
C:\Program Files\Android\android-sdk\tools\ant\build.xml:1139: The following error occurred while executing this line:
C:\Program Files\Android\android-sdk\tools\ant\build.xml:1151: Keystore was tampered with, or password was incorrect: Password verification failed

Total time: 19 seconds

E:\PROJECTS\mob-sp\platforms\android\cordova\node_modules\q\q.js:126
throw e;
^
Error code 1 for command: cmd with args: /s,/c,ant,release,-f,E:\PROJECTS\mob-sp\platforms\android\build.xml,-Dout.dir=ant-build,-Dgen.absolute.dir=ant-gen
ERROR building one of the platforms: Error: E:\PROJECTS\mob-sp\platforms\android\cordova\build.bat: Command failed with exit code 8
You may not have the required environment or OS to build this project


#7

At last it solved…actually i did not remove the tag in password field.
Thanks for your great example


#8

Looks like your keystore was either incorrectly created or you entered the incorrect password.


#9

Hello @sjerd pls where is the custom_rules.xml file in the platforms/android folder? Or do I have to create that myself and if so what’s the general template for that.

Thanks.


#10

Hello @nicraboy this process seems not to be working with Crosswalk or the latest release of Ionic CLI. For one there is no custom_rules.xml file in my platforms/android file. Even if I do skip this step like in your tutorial I do not get the prompt to input the necessary passwords. At the end of the build all I get is an unsigned-release apk.

What do you think is the problem?

Thanks.


#11

strange… this is my custom rules file

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <target name="-pre-compile">
        <!-- Fix library references due to bug in build.xml: See: https://groups.google.com/forum/#!topic/android-developers/0ivH-YqCjzg -->
        <pathconvert property="fixedJarsPath" refid="project.all.jars.path">
          <filtermapper>
            <replacestring from="/bin/" to="/ant-build/"/>
            <replacestring from="\bin\" to="\ant-build\"/>
          </filtermapper>
        </pathconvert>
        <path id="project.all.jars.path">
          <pathelement path="${fixedJarsPath}"/>
        </path>
        <echo message="Set jars path to: ${toString:project.all.jars.path}"/>
    </target>
    <!-- Rename AndroidManifest.xml so that Eclipse's import wizard doesn't detect ant-build as a project -->
    <target name="-post-build">
        <move file="ant-build/AndroidManifest.xml" tofile="ant-build/AndroidManifest.cordova.xml" failonerror="false" overwrite="true" />
        <move file="CordovaLib/ant-build/AndroidManifest.xml" tofile="CordovaLib/ant-build/AndroidManifest.cordova.xml" failonerror="false" overwrite="true" />
    </target>
	<property file="secure.properties" />
</project>

`

#12

The problem I thinks it’s because i’m using crosswalk and the uses the gradle build tool. Though I have made it to work but there are some minor modifications to your steps. These are:

  1. In the platforms/android folder there is a gradle.properties file. Open this and modify cdvReleaseSigningPropertiesFile= user/path/to/ant.properties to point to where your gradles’ ant.properties file is. This can be found here: ./org.crosswalk.engine/<app-name>-xwalk_core_library/ant.properties

  2. Secondly modify you ant.properties file with path to your keystore and also all necessary passwords. But the format is quite different in gradle. It’s usually written as seen below.
    storeFile=path/to/keystore storePassword=********* keyAlias=******* keyPassword=********

Using these steps I was able to build, sign and zipalign all @ once.

Thanks.


#13

Hi All,
Any one know why when launch the app on Android Galaxy Tab 7 the Service App Stop?
See the attached image:


#14

I have a key (and password) previously generated using cordova 2.0 and eclipse to sign.

Now to update the app in google play, generated by ionic, I need to step 3?

“3) Generate a file key.store With The CLI and answer all the questions:”

How I can use the same key? Will I have any problems if I create another for the same application (different version)?


#15

yes this did solve my problem I couldn’t find the Zipalign anywhere


#16

This helped me thanks! I did have to do one slight change though. I had to add

key.store=/path/to/key
key.store.password=****
key.alias=****
key.alias.password=****

to the ant.properties in the crosswalk ant.properties found here…

appname/platforms/android/cordova-plugin-crosswalk-webview/appname-xwalk_core_library/ant.properties

Once this was done, ionic build android --release worked 100%


#17

Where do you all put these files? My source code is hosted in a public github repository, so I don’t think it makes sense to include my keystore or my passwords. Are there other options?


"There is a problem parsing the package"
#18

You should no longer use ant.properties and secure.properties you should create a
"release-signing.properties" file with these contents:

key.store=YourApp.keystore
key.store.password=<YourApp keystore password>
key.alias=YourApp
key.alias.password=<YourApp alias password>

no custom-rules.xml just the release-signign.properties and the key.store file
then use ionic build --release


#19

I am trying to update by app on google play, and for that i tried to generate new update, but i am getting below error.

I am sure i am using same keystore file and correct password as well.

Anyone here faced same problem ?

keytool error: java.lang.Exception: Key pair not generated, alias <demo> already exists
java.lang.Exception: Key pair not generated, alias <demo> already exists
        at sun.security.tools.keytool.Main.doGenKeyPair(Unknown Source)
        at sun.security.tools.keytool.Main.doCommands(Unknown Source)
        at sun.security.tools.keytool.Main.run(Unknown Source)
        at sun.security.tools.keytool.Main.main(Unknown Source)

#20

Looks like you’re trying to generate your certificate again? You only need to generate it once, then just use it for all future app releases.