Wednesday, December 14, 2011

Exception reporting in Android applications

I was surprised and delighted to discover that the Android Market infrastructure has a mechanism to capture and report program exceptions which occur on the mobile device.  I discovered this because my app had a bug, and this system told me exactly where it was.

When a crash happens in the Android java code, it appears that either the Dalvik JVM and/or some monitor program in the underlying linux operating system captures the stack trace, uploads it to Google, and presents it to the app developer on the Developer Dashboard.  (Click here to go to yours.)

Early last week, I was trolling for statistics when I spotted this on my Developer Dashboard.  It reported one error and one report.  Within a few days, it had jumped to five reports.  (disclaimer: some image fields grayed-out for privacy)



I clicked on the circled link, and the next page summarized the problem, class name, and method name.



I clicked on the 'NullPointerException' link and the next page showed the exact line number.   Very nice.




I debugged the problem.  That line in my source code was not expecting or handling a null input parameter.  So when it got called with null, the app died.  My bad.  But easy to fix.

After I fixed the problem and udated the app version at the Android Market, I went back to the error page and clicked the button to mark this as an 'old' problem.  This seems to have moved the problem lower in my view.



I hope all my code bugs are this easy to fix.  Good luck debugging yours.

Tuesday, December 13, 2011

How to sign an APK for the Android Market


In order to publish an application at the Android Market, the app must be 'signed' with your own  'certificate'.  This tutorial explains how to manually create a certificate and sign the app.

Important:  Future updates and fixes to the app must also be signed with the original certificate in order to maintain the identity of the app.  Therefore, you must archive the certificate and its passwords in a safe place for the lifetime of the application.

This tutorial was developed using Eclipse 3.6.2 and command-line tools on Ubuntu Linux 10.04.  Other platforms are similar.

Prereqs

- Create an Android app using the Eclipse IDE and Android SDK.

- Have command-line tool 'keytool' from the Java JRE in your path.
    example:  /opt/jdk1.6.0_25/bin/keytool

- Have command-line tool 'jarsigner' from the Java JRE in your path.
    example:  /opt/jdk1.6.0_25/bin/jarsigner

- Have command-line tool 'zipalign' from the Android SDK in your path.
    example:  /opt/android-sdk-linux/tools/zipalign

- Recommended: Create directories for release artifacts.   examples:
    /home/sag/android/releases
    /home/sag/android/certificates

Export unsigned APK from Eclipse

From the Package View in Eclipse, right-click the project name-> Android Tools-> Export unsigned application package

Recommended: Specify a filename with 'raw' in the name.
    example:  /home/sag/android/releases/myapp.raw.apk






Optional: Make a backup copy.
    example:  cp  myapp.raw.apk  myapp.raw.apk.bkp

Create certificate

Note: Multiple certificates may be stored in one container file called a 'keystore database'.  This tutorial creates exactly one certificate.

Use the 'keytool' command to create a keystore file containing one certificate.

keytool -genkey
        -v
        -keystore "/home/sag/android/certificates/myalias.keystore"
        -alias myalias
        -storepass xxxxx
        -keypass yyyyy
        -keyalg RSA
        -validity 10000

where myalias is an arbitrary name, and storepass and keypass are passwords you memorize and save.


Enter your information when prompted.  examples:
    First and Last Name: John Doe
    Organizational Unit: Android Mobile Development
    Organization: myapp.example.org
    Location: San Francisco
    State: CA
    Country US

Verify a binary file is created, myalias.keystore.  Mine was 1400+ bytes.

Sign APK

Apply the certificate to the unsigned APK.

Note: This step modifies the existing APK file.

jarsigner -keystore "/home/sag/android/certificates/myalias.keystore"
          -storepass xxxxx
          -keypass yyyyy
          "/home/sag/android/releases/myapp.raw.apk"
          myalias

Optional:  Verify the file is similar in size to the original backup copy.


Zipalign APK

Align the APK on multiple-byte boundaries for efficiency.

Note: This step creates a new APK file.

zipalign  -v 4  myapp.raw.apk  myapp.apk

Verify the new aligned APK file is similar in size to the raw APK.

ls -l
-rw-r--r-- 1 sag  sag  64287 2011-12-12 15:36 myapp.raw.apk.bkp
-rw-r--r-- 1 sag  sag  66375 2011-12-12 15:39 myapp.raw.apk
-rw-r--r-- 1 sag  sag  66382 2011-12-12 15:40 myapp.apk

Et voila.  The new file, myapp.apk, is your final APK.  It may be published on the Android Market.


Postscripts

To install the final APK on a device, you must manually uninstall the previous version of app.  This is required because the previous version was signed by a debug certificate which is built into Eclipse and the Android SDK for our convenience.  Also, be sure to tell any beta testers to manually uninstall for the same reason.

As mentioned earlier, you must archive your keystore file (which contains the certificate) and passwords for future use.  This is required in order to publish updates to the app.  If you lose it and are forced to create a new certificate, the Android Market will treat your updates as a new and different app.  Users will not be able to find or install your updates seamlessly.  That would be bad.  Therefore save your certificate and passwords in multiple places.  You've been warned.

It is supposedly possible to sign APKs using a wizard built-into Eclipse.  It is probably easier than this.  Try it once you understand the manual steps outlined here.