Posts Tagged ‘code’

Creating a contact with multiple fields in Android

For the impatient: skip the article, download the code.

Recently, when writing a physician directory for the Canton of Geneva, I wanted to include a feature for adding a new contact. That is, I wanted a button that would pop up the “Add a new contact” screen, with various fields (such as phone number, postal address, and email address) already filled in. Piece of cake, right?

Adding a contact in the physicians app.

Adding a contact in the physicians app.

Unfortunately, it turns out that the Android docs and Stack Overflow are pretty bereft of clear, concise instructions for creating a contact with multiple fields of various types, e.g. work phone, mobile phone, or home fax (if such a thing still exists).

Plus, the entire ContactsContract changed in API level 11 (Honeycomb), meaning that anything written for ICS or Jelly Bean wouldn’t work in Gingerbread, and vice-versa. Oh joy.

Luckily for you — assuming you stumbled across this post after a frustrated trip to Google — I’ve written a helper class to do all the heavy lifting. It provides a simple, fluent API that works for Android version 2.1 (Eclair) through 4.2 (Jelly Bean), and it’s open source.

You create a contact like this:

Intent intent = new AddContactIntentBuilder("Joe Blow")
    .addFormattedAddress("123 Fake Street, Springfield USA",
        StructuredPostal.TYPE_HOME)
    .addPhone("555-867-5309", Phone.TYPE_HOME)
    .addPhone("555-123-4567", Phone.TYPE_WORK)
    .addPhone("555-987-6543", Phone.TYPE_FAX_WORK)
    .addEmail("joe.blow@gmail.com", Email.TYPE_HOME)
    .addEmail("joe@blow.com", Email.TYPE_WORK)
    .build();

startActivity(intent);

And here’s what this code produces, in both Jelly Bean and Gingerbread:

Adding a contact in Jelly Bean and Gingerbread.

Adding a contact in Jelly Bean and Gingerbread.

Happy contact creating!

Download or fork the code from GitHub.

Share and share alike – just not with Facebook

Edit: Facebook has fixed this bug in the latest version of their app.

Here’s a common situation when you’re writing an Android app: you’ve got some text (a link, a test result, a poem you wrote about your love for Android) and you want to allow the user to “share” it with others. And if you’re lazy like me, you’ll quickly discover the fastest way to do it:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Android, oh Android.");
intent.putExtra(android.content.Intent.EXTRA_TEXT, "Wherefore art thou, Android?");
startActivity(Intent.createChooser(intent , "Share"));

This generates a screen that looks like this:

Isn’t that nice? And it only cost you five lines of code! But oh, if only it were so easy…

See, the problem is with the fourth guy there – Facebook. The Facebook Android app only supports sharing URLs, not arbitrary text. Most other apps work fine, but when you click on Facebook, you get this sad, broken-looking page:

For my own apps where I wanted to enable sharing (Japanese Name Converter and CatLog), I could have just left this as-is. I mean, this is Facebook’s bug – not mine, right? But then I realized that, whether it’s my fault or not, my users would see this ugly page and assume it was a bug in my app. So I had to get Facebook out of there.

After some Googling, I found this discussion, which pointed me in the right direction. In the thread, one of the posters basically gives you all the tools you need to build your own custom SEND_ACTION chooser. However, I found it was a non-trivial amount of effort to co-opt their code to do what I wanted it to do.

So I built a more easily extensible version.  Here’s the final product, based off that poster’s original Launchables class.  It uses the PackageManager to find all apps that respond to SEND_ACTION, then filters out Facebook and displays the rest in a simple ListAdapter.  The code is open source; do whatever you’d like with it. All you have to do is copy SenderAppAdapter.java and the resource files into your app, and then use it as in DemoActivity.java. It will create an AlertDialog like this:

It looks almost exactly the same as the default chooser, but Facebook is gone! Plus, I threw in a “copy to clipboard” action as a little bonus. This way, the user can always post her lovely poem to Facebook by copying the text, opening up the Facebook app, and pasting in the damn text manually.

And most importantly, no one will blame you for Facebook’s oversight.

Download the source code