Testing Whether an Application Is Installed on the SD Card

Here’s a little code snippet that can be very useful whenever you have to deal with broadcast intents: it checks whether an application is installed on SD card. The reason why this is useful in combination with broadcast receivers is that apps installed to external storage will simply not receive all broadcasts (for instance, BOOT_COMPLETED cannot be received by apps on SD.)

To test whether an app is installed on external storage, do this:

Ignition 0.2 Released

We’ve just released version 0.2 of our ignition utility library for Android.

Don’t know which benefits ignition brings to the table? Read about it here.

What’s new?

We’ve worked a lot on improving IgnitedAsyncTask and IgnitedLocationManager, pushed many bug fixes, and restructured the samples apps. We’ve also added a sample for EndlessListAdapter for your convenience.

Read the full changelog here.

Ignition 0.1 Is Here

Today it’s “Fun Friday” (10% time) at Qype, so we thought this would be a good opportunity to release the first version of our ignition library for Android!

What’s ignition? In short, it’s a rewrite of Droid-Fu. What is Droid-Fu? It was an attempt to create a utility library for Android that makes your life easier by creating add-ons and wrappers for the Android framework classes that are just a little friendler to use. Our approach with Droid-Fu was to pull all the helper code and boilerplate we wrote for our Qype app into a reusable library, but we did a poor job at maintaining it. We didn’t have proper release and issue management in place and since I was short of spare time (not least due to my work on Android in Practice), it just never happened. We soon had many issues filed, but it was virtually impossible for us to backtrack through all the snapshot versions to find out which one it was actually affecting.

Moreover, we did mistakes with Droid-Fu’s API design, and we wanted to have a chance of fixing these without horribly breaking all the apps that used it. Yes, we could have done a “Droid-Fu 2.0” (even though there never even was a 1.0) or a “Droid-Fu NG”, but I felt the least intrusive way would be to start out fresh as morning dew.

The fruit of this labor is ignition, and I believe we improved things a lot. First, here’s what ignition has to offer in the first place:

Cross-cutting stuff

  • helper classes for dealing with Intents, dialogs, device screens, etc.
  • an improved version of AsyncTask (IgnitedAsyncTask) which makes it a lot easier to deal with the following things:
    • task life-cycle: there are onStart, onComplete, onSuccess, and onError callbacks
    • yes, your task may now raise exceptions while running
    • all callbacks are guaranteed to be passed a valid Context object, so that you can immediately update the UI (those must be bound and unbound using connect/disconnect to avoid memory leaks!)
    • re-use task logic from pre- and post-execute handlers by being able to bind to different callables that execute the actual job logic
  • EndlessListAdapter can be used to implement lists that fetch more content when reaching the bottom of the list

Dealing with remote images

  • RemoteImageView is a drop-in replacement for ImageView which can download its image resource from the Web and show a progress spinner in the mean time
  • if you’re showing a whole bunch of these, you can use RemoteImageGalleryAdapter which will feed RemoteImageViews into an Android gallery widget
  • both are backed by RemoteImageLoader, which can be used independently to download images drawable into ImageViews asynchronously. We use this to download thumbnail images for list elements in ListViews on the fly.
  • all this in turn is backed by ImageCache, a 2-level cache which is able to cache to both internal storage and SD card, therefore minimizing network traffic when dealing with lots of data (as is the case with images)

Dealing with HTTP requests and network failures

  • speaking of caching, you can not only cache image data, but also HTTP responses using HttpResponseCache
  • better yet, IgnitedHttp is an abstraction of Android’s Apache HttpClient that exposes a simple DSL to build and send HTTP requests, like so:
    • new IgnitedHttp().get(“http://example.com”).expecting(200, 404).retries(3).withTimeout(5000).send();
  • it integrates with the response cache by setting a single flag
  • it will enable GZip uncompression of response data with a single flag
  • it will register a BroadcastReceiver which listens for changes in network configuration and automatically update e.g. proxy settings for you (this can be a major source of error in your app for users who must go through carrier proxies on 3G and then fail over from or to Wi-Fi)
  • it has a more robust request-retry logic than the standard HttpClient does

Dealing with location

Stefano has build a fantastic new way of dealing with location on Android. It takes all the cruft out of your Activities and hides it in a single annotation you drop onto an Activity. It will then automagically inject location fixes into a prepared field, using the power of AspectJ. Read more about it on his blog.

What’s different to Droid-Fu?

Except for the location module, all of this has existed in Droid-Fu. As I mentioned before, the motivation behind iginition was not to build a new library, but re-launch what worked well for us in a more maintainable and less intrusive way. Here’s what changed:

  • The project is now split into multiple modules, so you can decide which ones you’d like to link. This makes the whole thing less monolithic, and for instance doesn’t force the Maps dependency on you if you do not want to use the location stuff
  • The project is less intrusive. You do not have to inherit from BetterApplication, BetterActivity or BetterService anymore (these classes have been removed). This was done as to make ignition integrate seamlessly with other libraries like Roboguice. We felt that ignition was not supposed to be a framework: it should be an all-opt-in solution.
  • The API has received a major cleanup. Things have been renamed, restructured, and generally made more consistent.

Where can I get more information?

It’s all on GitHub right now, but here are some quick links to useful stuff:

Thanks again for everyone who contributed issue report and fixes! We promise we’ll do more regular updates with this library.

Getting to Grips With the Android 4.0.3 Social APIs

This post also appears on engineering.qype.com.

We recently started getting our hands onto some of the shiny new Ice Cream Sandwich APIs, particularly Beam and the social stream API that was introduced with Android 4.0.3. Integration turned out to be a little harder than we expected, mostly due to two things: code verbosity (you’ll write a lot of boilerplate) and undocumented pitfalls. With this post I’d like to shed some light on a few things that bit us when developing with the new APIs.

Integrating with the social stream

First of all, you should know that to get going with the social stream, you will have to go through two major steps:

  1. Publish your app as an account provider, and log in your users via the AccountManager API, so that contacts from your service can be synced with the Android address book (now called the People app in ICS)
  2. Once your contacts are synced with the People app, import their status updates into the “Recent Updates” feed

I won’t talk about 1. There are two excellent blog posts on how to deal with connecting accounts and syncing contacts respectively, plus the SampleSyncAdapter app that is shipped with the SDK ApiDemos. Once you’re there, adding support for publishing a user’s social feed is generally quite simple. From here on I assume that you have read all the documentation that is available, since I want to focus on the difficult parts. Let’s have a look at the final product first.

[[posterous-content:yFlmybGeCDDFFbADcDyf]]

Let’s quickly recap when the “Recent Updates” pane appears. It becomes available whenever there are status updates from the contact you’re looking at that are no older than a few days (I believe it’s five days, but I haven’t exactly checked that). There is also a threshold for how many items will ever show up at the same time, and as pointed out in the docs, this threshold is platform or even device specific.

There are two ways to import these status updates from your service: eagerly, as part of the contacts sync (i.e. in your contacts SyncAdapter), or lazily, via an Intent that is fired whenever a user looks at another user’s profile. Again, the general mechanics behind this are outlined on the Android dev blog.

Generally, you don’t want to fetch status updates (plus images) for a hundred or more contacts as part of the sync, since it’s very unlikely that a user would look at all of them to see their status updates. I say “plus images”, because you will have to download them synchronously and either insert them in binary form into the StreamItemPhotos table, or write them to disk using an AssetFileDescriptor. Since ICS devices often have high resolution displays, you want to download high res images, so that’s a lot of data you’re pushing over the wire, keep that in mind.

Hence, you most likely want to go down the callback route, perhaps with optionally pre-populating important contacts with their status updates during contacts sync (what important means depends on your service, but you could for instance check if the user has starred a contact, and prefetch status updates accordingly).

Regardless for which sync strategy you settle (lazy or pre-fetched or hybrid), here are a few things that bit me while syncing social stream items. Read on →

The Signpost OAuth Project Has an Owner Again!

In 2009, I introduced Signpost, a lightweight, client-side OAuth library for Java. I initially created it to power the API connector in our Qype Android app, and kept maintaining it for a year or two, until I got bored with fixing random issues with random OAuth service providers that I honestly didn’t care about whatsoever. In its latest release, the library still works flawlessly for us, so I had little motivation to continue work on it.

However, I understand that it probably doesn’t work flawlessly for everyone, so with me backing away from developing it further, a project maintainer was obviously needed. It looks like we’ve finally found someone who’s willing to enter the painful world of OAuth 1.0! Meet Takahiro Horikawa, who will take full ownership of the project from here on, managing issues, releases, and the project website.

If you’re interested in helping out, give us a shout on signpost-developers!

Signpost project page

Takahiro’s Twitter

Takahiro’s GitHub

Robolectric: Setting ANDROID_HOME for All Tests (MacOS/Eclipse)

I just stumbled over the somewhat annoying issue that when running Robolectric tests in Eclipse, the library must see the ANDROID_HOME environment variable, or resource lookups in the android namespace will fail (you’ll see a warning about this on the console).

Now, you can of course fix that by adding ANDROID_HOME to every single Eclipse Run configuration for your tests, but that would be cumbersome. It would be better to have this variable set for Eclipse so that all Java processes forked from it will inherit it, including your test runs. Unfortunately MacOS X doesn’t seem to have a straight forward solution to that. I tried modifying Eclipse’s plist file, to define LSEnvironment, but that did not have any effect.

However, what you can do is have all MacOS processes inherit it by setting it in /etc/launchd.conf. This is somewhat quick and dirty, since you only really need it in Eclipse and Terminal, but it does the job:

$sudo vim /etc/launchd.conf

Now add this line:

setenv ANDROID_HOME /path/to/android-sdk

Reboot, and rejoice.

Which Screen Am I? No More Getting Lost in Android Screen Configurations

Are you as puzzled as me when it comes to Android screen classification? According to the official docs, Android puts device screens into buckets, based on two properties: screen size, and pixel density. However, the lines are blurry, it’s often not clear which exact values are used to put a device in one bucket or the next.

If you keep pondering the screen class of your device(s), ponder no more. I’ve built a little app that helps developers decide in which of these buckets your device falls. It’s called Which Screen Am I? and it’s free and open source. This is how it looks on a FroYo emulator that uses the HVGA skin and a medium pixel density:

[[posterous-content:zvpucdcdirfbBIjfDeHk]]

If you’re targeting different screen configurations with different APKs, this takes at least some of the pain out of the testing process.

GitHub: https://github.com/kaeppler/WhichScreenAmI

Android Market (Web): https://market.android.com/details?id=com.github.kaeppler.whichscreen