Tips & Tricks on Android

Saturday, June 20, 2009

Ringtones Location

There are 2 locations from which G1 can pick ringtones.

1. On SDCard. /sdcard/Music/ringtones
2. On filesystem. /system/media/audio/ringtones
  (You need to mount /system read-write)

Tuesday, March 10, 2009

Flashing the Android Dev Phone 1

So far it was not super easy to flash your ADP1 to factory settings if you manage to corrupt something or break the OS. People have used hacky ways and images but no official ADP1 build was available.

This has changed now. The OS images along with flashing instructions for restoring your android dev phone to factory image is available here.

Wednesday, February 25, 2009

Hello World C program using Android Toolchain

I had reported earlier how I had gotten a C Hello World statically-linked program running on my Android phone using CodeSourcery's toolchain (on linux). Today I got a dynamically-linked Hello World program running on the phone, compiled using Android's prebuilt toolchain from the source.

It's well known that Android uses a stripped down version of libc, called bionic. When you compile your program with static linking, you don't use bionic because well, you linked statically. This is non-ideal. You want to use the bionic library on the phone, and besides you want to compile using Android's prebuilt cross-compiler arm-eabi-gcc

If you are anxious to get things working, use agcc, a perl wrapper over arm-eabi-gcc that sets up everything for you so that you can just:
$ agcc hello.c -o hello
and the resulting binary (hello) just works. Of course you should have the directory containing arm-eabi-gcc in your PATH for agcc to work.

Let's explore a bit deeper. But let me first simplify my hello program to contain just a main
$ cat hello.c int main(int argc, char* argv[]) {
return 0;
}


The minimal set of flags to pass to arm-eabi-gcc to get this working is:
$ arm-eabi-gcc -o hello hello.c -Wl,-rpath-link=/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib -L/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib -nostdlib /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/crtbegin_dynamic.o -lc

Here /Users/nirnimesh/NIR/android/mydroid/cupcake is the root of my Android source.

$ file hello

hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

Note that the executable binary is dynamically linked.

If you leave out -Wl,-rpath-link=/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: warning: libdl.so, needed by /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/libc.so, not found (try using -rpath or -rpath-link) /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/libc.so: undefined reference to `dl_unwind_find_exidx' collect2: ld returned 1 exit status

If you leave out -L/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: cannot find -lc collect2: ld returned 1 exit status

If you leave out -nostdlib you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: crt0.o: No such file: No such file or directory collect2: ld returned 1 exit status

If you leave out /Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/crtbegin_dynamic.o you get
/Users/nirnimesh/NIR/android/mydroid/cupcake/prebuilt/darwin-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/../../../../arm-eabi/bin/ld: crt0.o: No such file: No such file or directory collect2: ld returned 1 exit status

And finally, f you leave out -lc your compilation fails with:
/Users/nirnimesh/NIR/android/mydroid/cupcake/out/target/product/generic/obj/lib/crtbegin_dynamic.o: In function `_start': bionic/libc/arch-arm/bionic/crtbegin_dynamic.S:(.text+0x10): undefined reference to `__libc_init' collect2: ld returned 1 exit status

So far we've been able to compile C programs using Androids toolchain and run on the phone.
To summarize, it's the most convenient to use agcc as the compiler so you don't have to bother.

Friday, February 20, 2009

cp on Android

The Android Dev Phone (and G1, by extension) does not have the cp command in the adb shell prompt. Since you can compile and run C code on the phone, you could in theory also compile the cp program but that's probably a stretch. Alternatively, you can:
cat source_file > dest_file

This works because the phone has a full-featured shell which supports stream redirection.

Screenshots on Android

If you want to report something about your phone over email, a screenshot goes a long way.

To take a screenshot you need to download the Android SDK for your machine. It includes a tool called ddms which is the dalvic debug monitor. Dalvic is the Java runtime powering all the apps on your android phone.

Connect the phone to your machine, run ddms from the terminal and go to Device > Screen Capture (or Ctrl-S) for taking a screenshot.

Hello World in C on Android

If you've been following the Android world, you'd know that Android's SDK requires you to write apps in Java. Ever since I got my phone I've been dying to run a Hello World C program, but I've been unable to get the right cross compiler for it.

Today I finally managed to do it using CodeSourcery's cross compiler on linux. A cross compiler is something which allows you to compile on one architecture (the host) and run the executable binary on another (the target). In this case, the host is the linux machine where we'll install the toolchain (linux intel x86) and android phone is the host (arm).
  1. Download CodeSourcery's toolchain installer for GNU/Linux target for IA32 host
  2. Install it: sh arm-2008q3-72-arm-none-linux-gnueabi.bin
  3. The toolchain provides the cross compiler arm-none-linux-gnueabi-gcc. You need to put it's directory in your $PATH. Once you have the toolchain, you can easily compile your hello world program: arm-none-linux-gnueabi-gcc -o hello -static hello.c
  4. Copy the binary to your phone and run it from an adb shell prompt: ./hello
Voila!

Points to note:
  • The above binary is static, that is it does not use the phone's libc libraries. Android ships with its own trimmed down version of libc, called bionic. Next I'll be trying to compile and run using bionic libc, so that I don't have to compile statically
  • The above steps do not use the toolchain in the android source code. I'll try later to cross compile using that.

Wednesday, February 18, 2009

Installing non-Market Apps on Android Phone

If you own an Android Dev phone, at some point you'd probably want to create and try your own apps (or apps from your friends).

To ensure that you do not break your phone by installing malicious apps, Android has a couple of safety features built in. So you need to specifically instruct android to be able to install unsigned / non-market apps.

Menu > Settings > Applications > Unknown Sources

Check "Unknown Sources" to allow install of non-Market applications. While developing, you most likely also want to enable "Stay awake" in Menu > Settings > Applications > Development so that your screen does not go to sleep every often.

Now you can install any app (including malicious ones) the usual way either by browsing to the app using the browser or using adb install command.

Monday, January 19, 2009

Mount a filesystem read-write

Very often when you want to write files to a particular partition on ADP1, you will get a "Permission Denied" if the partition is mounted read-only.
To get around this, you need to mount the partition read-write. Typically this is done with /system partition

$ adb shell
$ su
$ mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system

(Replace /dev/block/mtdblock3 & /system with appropriate device path and mount point, as obtained from cat /proc/mounts)

Sunday, January 18, 2009

Android Dev Phone 1 Button Combinations

The following are the ADP1 / G1 button combinations for booting in various modes.

Regular mode: Power button

Fastboot mode: Power on with Camera + Power button. Wait until Android on skateboard image appears with text "SERIAL0", and press Back button. It'll enter FASTBOOT mode.

Alternatively, Power + Back button takes you directly to fastboot mode

Recovery mode: Power on with Home + Power button.
In recovery mode,
Alt + L - toggle log text display
Alt + s - apply sdcard:update.zip
Alt + W - wipe data/factory reset

Safe mode: Power + Menu button

The 3-button salute (Call + Menu + Hangup) causes a reboot in any of the above modes.

Using ADP1 without sim card

You know that Android Dev Phone 1 is fully unlocked.  But if you've just opened your box and don't have a sim with a working data plan, you'll be greeted with a "No sim card" "Emergency dial" screen on first boot. Now, if you had a sim card with a working data plan, it'd allow you to go ahead and and sign in with your Google account, but you don't. So you cannot do anything at the "No sim card" screen.

There's a workaround, however. You can use wifi to setup your account. It requires you to use the adb tool available from the android sdk.
  • Connect the device to your computer using the USB cable. You should be able to see a listing for your device if you run adb devices. Then execute the following commands.
  • adb shell
  • $ su
  • $ cd /data/data/com.android.providers.settings/databases
  • $ sqlite3 settings.db
  • INSERT INTO system (name, value) VALUES ('device_provisioned', 1);
  • .exit
  • $ reboot
After reboot:
  • $ adb shell
  • am start -a android.intent.action.MAIN -n com.android.settings/.Settings
Go ahead and setup your wifi and then sign up using your Google account.

Friday, January 16, 2009

IP Address

To find the WiFi IP address on the android dev phone, you can:

1. From the phone
Follow Settings >> Wireless Controls >> Wi-Fi settings and tap on the network you are connected to. It'll pop up a dialog with network status, speed, signal strength, security type and IP address.

2. Using adb (from command-line)
Assuming you have the android SDK installed on your computer, do:
$ adb shell ifconfig tiwlan0

tiwlan0 is the name of the wi-fi network interface on the device.

The command will show the IP address, netmask and other interface parameters like up/down state, broadcast or not, and so on.

My Dream Phone

I received my brand new, unlocked Android Dev Phone 1 yesterday.
I had registered as a developer and ordered the phone for $399 + taxes + $25 registration fee.

Hardware Features

  • Touch screen
  • Trackball
  • 3.2 Megapixel camera with auto focus
  • Wi-Fi
  • Bluetooth v2.0
    • Handsfree profile v1.5
    • Headset profile v1.0
  • 3G WCDMA (1700/2100 MHz)
  • Quad-band GSM (850/900/1800/1900 MHz)
  • GPS-enabled
  • QWERTY slider keyboard
  • Includes 1GB MicroSD card (Can be replaced with up to 16GB card)
  • Included in the box
    • HTC Android Dev Phone 1
    • USB Cable
    • AC Adapter (with US plug)
    • Stereo Hands-Free Headset
    • Battery
    • Getting Starting Guide
    • 1G Micro SD Card (inserted into Device)

So far the experience on this phone has been amazing for me. I'm going to use this blog to record my findings as I learn the exciting new platform.

I've downloaded the android SDK from:
http://code.google.com/android/download.html

This includes many important tools, most notably adb - android debug bridge, which allows me to run all kinds of commands on the device directly from my computer, ie without typing on the device. It also eliminates the need to run telnet or ssh server on the device.