Monday, December 29, 2008

Android Pt. 1: Developing and deploying first steps

To get things rolling I took the Hello World app that I had initially created using the Eclipse plugin and modified it to show a couple of buttons that pop up dialogs. Most of the code was taken and adapted from the alert dialog example programs.

Everything worked out when running the program under the emulator. My next step was to see what it would take to deploy to the G1.

When I opened up the manifest.xml file in Eclipse I noticed a link that read, "Export the unsigned apk". I clicked the link but didn't see output in the Eclipse editor, nothing to suggest that anything had happened. But, when I checked my home directory, I did find a new .apk file.

Note: If you right-click your project in the Eclipse package view you will find a menu item under Android tools that performs the same export function.

According to Google's documentation, my next step was to sign the apk. Since I'm only testing a deployment to my personal phone, I was hoping that this would be fairly painless: I didn't want to mess around with the details of key generation right then.

I read that there is a debug.keystore that Eclipse uses when automatically signing debug builds for deployment to the emulator. I hoped I would be able to skip the keytool step because of this and use the same key generated by Eclipse. Skipping to the jar signing step, I ran the following.

jarsigner -verbose -keystore ~/.android/debug.keystore picthere.apk  PictHere

When prompted for a password, I used the android default which is "android" according to this page.

me@mrroboto:~$ jarsigner -verbose -keystore ~/.android/debug.keystore picthere.apk PictHere
Enter Passphrase for keystore: android
jarsigner: Certificate chain not found for: PictHere. PictHere must reference a valid KeyStore key entry containing a private key and corresponding public key certificate chain.

Whoops. Wrong alias for the last argument. After correcting, all worked as expected.

me@mrroboto:~$ jarsigner -verbose -keystore ~/.android/debug.keystore picthere.apk androiddebugkey
Enter Passphrase for keystore: android
signing: res/drawable/alert_dialog_icon.png
signing: res/drawable/icon.png
signing: res/layout/main.xml
signing: AndroidManifest.xml
signing: resources.arsc
signing: classes.dex

I verified that the apk (actually a jar file) had been signed as suggested by Google.

I had a bit of a hiccup during the next step: using DDMS to deploy the app to the actual device.

There is a DDMS perspective in Eclipse that is really very, very nice. Unfortunately, after plugging the G1 into my computer via USB, the emulator showed up and not my actual device. A number of posts suggested that the "Unknown Sources" checkbox must be enabled on the G1 (found under Settings/Applications). After checking the box, I plugged the G1 back in and restarted Eclipse, but no device listed---still just the emulator.

I decided to try it from the command line:

me@mrroboto:~/src/android-sdk-linux_x86-1.0_r2/tools$ ./adb devices
List of devices attached
emulator-5554 device

Nope...nothing there but the emulator.

This page suggested that I add udev rules. Made sense...need to give the USB device the right permissions. (I probably should have mentioned that I'm developing on an Ubuntu box.)

If you're developing on Ubuntu Linux, you need to add a rules file:
  1. Login as root and create this file: /etc/udev/rules.d/50-android.rules. For Gusty/Hardy, edit the file to read:
    SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"
    For Dapper, edit the file to read:
    SUBSYSTEM=="usb_device", SYSFS{idVendor}=="0bb4", MODE="0666"
  2. Now execute:
    chmod a+rx /etc/udev/rules.d/50-android.rules

After unplugging and re-plugging the G1, it showed up for the party...

me@mrroboto:~/src/android-sdk-linux_x86-1.0_r2/tools$ ./adb devices
List of devices attached
emulator-5554 device
HT849GZ16642 device

At this point I was confident that I would be able to see the device in the DDMS perspective in Eclipse. Sure enough, it was there.

But sadly, when I chose the "push file to device" and selected my apk, I got the following error:

[2008-12-29 21:35:22 - ddms]transfer error: Read-only file system

Could it be that I am not going to be able to copy my app directly to the phone? Apparently this is the reason I should have picked up the Android Dev Phone, at least according to this post, which states that the Dev Phone is the same as the G1 but "there are no software restrictions on the device, users can directly load their own applications and test code straight to the unit rather than just relying on emulators to test code."

We shall see...


justin said...

Hi there, I see you've gone thru most of what I've been struggling with tonight.

I just bought my G1 yesterday and I'm very excited about developing on Android. I did the simple Hello World app in Eclipse and tested it in the emulator ...all good.

So then I followed the steps listed above exactly for Ubuntu adding udev rules as prescribed for the Gutsy/Hardy Ubuntu release (suspecting those are the most recent) even though I have the very latest Jaunty release of Ubuntu.

Anyway, so I connect my phone with the USB cable. The phone notices and links up. I can mount my SD card in it as a drive and access it from my desktop so that all works... great!

I'm all smiles until I issue the "adb devices" command and all I see is my emulator like you did at first.

/usr/bin/eclipse/android/v1.5/tools$ adb devices
List of devices attached
emulator-5554 device

I've unplugged the phone and plugged it back in several times ...but no new adb devices show up.

I've tried a few other suggestions I've found on other sites:
- I've restarted the udev daemon like so: sudo /etc/init.d/udev restart
- I've listed the connected usb devices with "lsusb" and my phone shows up as:
Bus 002 Device 009: ID 0bb4:0c02 High Tech Computer Corp.
- I've reset adb from the Devices view inside Eclipse.
Then all I get in the console are these errors:
[2009-05-19 00:44:03 - DeviceMonitor]Adb connection Error:EOF
[2009-05-19 00:44:03 - DeviceMonitor]Connection attempts: 1

I see the directions you've listed above are the same official directions listed here:
...and I think I've done everything there and then some.

I see you published this helpful blog post back in December and you managed to get farther than I have all night. Boy, I would be so eternally grateful if you had any wisdom you'd like to share.


justin said...

Just an update for anyone else who runs into the problems I did here using Ubuntu Jaunty ...another helpful developer on a forum I cross-posted to found a solution here:

...well, originally here: