PhoneGap: Compiling a Release APK without using PhoneGap Build
While recently finishing up my first PhoneGap application (which was tailored strictly for the Android platform), I encountered a problem that wasted some of my time. I'm documenting the problem and solution below for the sake of others who may run into the same issue.
When you're compiling a PhoneGap application for release, the PhoneGap team
seems to expect that you'll use PhoneGap build to package your
application. That was not an option for me, however, because the PhoneGap build
system only allows you to upload your web asset files for compilation (ie,
those that live in
app-root/assets/www). For reasons documented
elsewhere, that didn't work for me, because I was forced to modify my
application's main Java file by hand.
Though I assume that this is a fairly common problem, I had a hard time tracking down precisely how to compile an APK for release without using PhoneGap build. Learning how to do so required some sleuthing.
My first step in figuring out how to build a release APK was simply to take a
look at some of the Cordova code, where I noticed that
was simply a wrapper that invoked
app-root/cordova/cordova BOOM. Inspecting
app-root/cordova/cordova, I then discovered that
BOOM merely invokes
ant clean and
ant debug to generate the debugging APKs.
With that, I knew that
ant was actually doing all of the work behind the
scenes. (This would probably be obvious to a Java developer, but I have
virtually no Java experience.) Once I knew that Cordova was silently invoking
the native Android tool chain for compilation, I began reading the appropriate
The Android Build Process
I learned a few things from the Android SDK documentation. The first was that
an Android application must be cryptographically signed before it can be
published to the Google Play store, and that the APKs produced by
BOOM were being automatically signed by a debugging key. (I also learned
that APKs that were signed by a debugging key may not be distributed in the
Play store, so don't waste your time trying to do so.)
I also learned that there are two ways to compile a release APK:
- Generate a debug APK
- Sign it
- Align it
- Generate an unsigned APK from scratch
- Sign and align it in one step
(The concept of "alignment" was new to me, but it seems to be some form of compression/file arrangement whereby asset bytes are aligned in some specified way. My important takeaway here wasn't the details - about which I really didn't care - but that this was a step that needed to be done.)
Simply put, that first approach didn't work for me. I had a recurring problem whereby the APK that was supposed to be unsigned was not signing correctly. (At least, that's what this thread on Stack Overflow led me to believe.) Not wanting to waste time, I moved on and tried the second approach.
My first step in successfully building a release APK was to create a private key with which I could sign the application. I used a shell command modeled after the following to generate a new key:
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name \ -keyalg RSA -keysize 2048-validity 10000
The resultant key is a private key. Do not distribute it with your application!
I then added the following two lines to
(Obviously, you would substitute your actual key name, path, and alias above.)
I was then able to compile a release APK using:
jarsigner -verbose -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore my_application.apk alias_name
With this I had a release APK that I was able to successfully upload to the Play store for distribution.