HTC Tattoo Skin

I use this skin to test my apps with it.
It gives a better view on how the app would look on a device with this screen size.

Download link: htc-tattoo-skin.zip
htc-tattoo-screenshot

Nexus One Skin

A friend of mine asked for this one.
Feel free to download it: nexus-one-skin.zip
nexus-one

Send SMS using an Intent

I know this is a common topic but this solution actually worked for me.
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.putExtra("address", "XXXXXXXXXX"); // phone number
    intent.putExtra("sms_body", "..."); // message
    intent.setType("vnd.android-dir/mms-sms");
    startActivity(intent);
It's a nice thing when you have access to source code. I'm talking about the Mms.app in this case. ;-)

Compact Android Emulator Skin

Since I don't have two displays I find it hard to monitor the logs or debug the application while using the emulator. The reason for this is that the emulator skins require too much display space. I created an emulator skin that is just a little taller than the HVGA resolution. If you have the same problem you can use this skin too: download

Samsung i7500 Skin

Now I'm not sure for which phone should I wait! :D Feel free to download the skin: download

The Friends List

Sometimes you need to manage a list of friends inside your Android application. In my case the friends list is a list of contacts entries. Using a contacts entry as a friend is a good idea for your application because:
  • the user has to use a well known activity (the Edit Contact activity) to edit the friend's contact details
  • you don't have to write the code for that part :)
I use a table called friends that is kept in-sync with content://contacts/people so that it always contains an entry for each contact.
public final class FriendsColumns implements BaseColumns {
  public static final String PERSON_ID = "person";
  public static final String IS_FRIEND = "is_friend";

  // cached details from contacts
  public static final String DISPLAY_NAME = "display_name";

  // additional application-related columns
}
The column is_friend is a boolean column that marks the contact as a friend. The column display_name is filled with the contact's display name while synchronizing the table. It's purpose is only to remove the need for additional queries while rendering the list activity. For synchronization I created service that runs in a background thread and makes use of the CursorJoiner class.
  Cursor peopleCursor = contentResolver.query(Contacts.People.CONTENT_URI,
      new String[] {Contacts.People._ID, Contacts.People.DISPLAY_NAME},
      null,
      null,
      Contacts.People._ID);
  Cursor friendsCursor = contentResolver.query(Friends.CONTENT_URI,
      new String[] {Friends._ID, Friends.PERSON_ID, Friends.DISPLAY_NAME},
      null,
      null,
      Friends.PERSON_ID);

  CursorJoiner joiner = new CursorJoiner(peopleCursor,
      new String[] {Contacts.People._ID},
      friendsCursor,
      new String[] {Friends.PERSON_ID});
  Uri friendUri;
  for (CursorJoiner.Result result : joiner) {
    switch (result) {
    case LEFT:
      ContentValues insertValues = new ContentValues();
      insertValues.put(Friends.PERSON_ID, peopleCursor.getLong(0));
      insertValues.put(Friends.IS_FRIEND, 0); // false
      insertValues.put(Friends.DISPLAY_NAME, peopleCursor.getString(1));
      contentResolver.insert(Friends.CONTENT_URI, insertValues);
      break;
    case RIGHT:
      friendUri = ContentUris.withAppendedId(Friends.CONTENT_URI,
          friendsCursor.getLong(0));
      contentResolver.delete(friendUri, null, null);
      break;
    case BOTH:
      ContentValues updateValues = new ContentValues();
      updateValues.put(Friends.DISPLAY_NAME, peopleCursor.getString(1));
      friendUri = ContentUris.withAppendedId(Friends.CONTENT_URI,
          friendsCursor.getLong(0));
      contentResolver.update(friendUri, updateValues, null, null);
      break;
    }
  }
            
  friendsCursor.close();
  peopleCursor.close();
The synchronization service is started when the friends list activity is created and when the contents of content://contacts/people changed.
public void onCreate(Bundle savedInstanceState) {
  // ...

  synchronizeFriendsWithContacts();
  ContentObserver contentObserver = new ContentObserver(null) {
    @Override
    public void onChange(boolean selfChange) {
      synchronizeFriendsWithContacts();
    }
  }
  getContentResolver().registerContentObserver(Contacts.People.CONTENT_URI,
      true,
      contentObserver);

  // ...
}

private void synchronizeFriendsWithContacts() {
  startService(new Intent(this, FriendsSynchronizer.class));
}
By using this approach I achieved:
  • great performance in rendering the list activity, because of the local copies from contacts
  • when adding a new friend to the list I already have a list of remaining contacts, by using is_friend as false
  • removing a friend from the list is done by just setting is_friend to false
  • when the user removes a contact the friends list is automaticaly cleaned too
  • I don't need to write a new activity that edits the friend's contact details :)

Black Magic Skin

After some Gimp-ing I managed to make also a black skin. You can download this one too. Mandatory screenshot:

HTC Magic Skin

This will be my next phone... Because I like it so much, I created this android skin to feel much better while developing on the emulator.

This skin is available for download.

What other better way to demonstrate the skin than using some screenshots?

Emulator screenshot:



Phone buttons: