Android Add-On Applications

I recently developed an add-on package for an Android application and thought I'd share some findings. That is, there is a base application and an add-on application which unlocks extras features in the base app.

I chose to put all the functionality in the base application and simply have the add-on unlock it. It turns out that this is very easy to do due to Android's dependence on signing keys. First, I made an application that has no components - it has no launcher, code, or layouts. All it has is a launcher icon (as this is viewable from the market and applications settings). Next, I signed both the base application and the add-on with the same key. Then, you can use the PackageManager to verify if the other application is installed:

public static boolean isAddOnInstalled(Context context) {
   PackageManager pm = context.getPackageManager();
   return pm.checkSignatures(BASE_APPLICATION_PACKAGE, ADDON_APPLICATION_PACKAGE) == PackageManager.SIGNATURE_MATCH;
}

The neat part of this solution is that it relies on the PackageManager's signature checking to verify the add-on. If the add-on application doesn't exist, or it was signed by a different key, this will return false.

An alternative way to do add-ons would be to put actual functionality or data in the add-on package. Again, you can use signing keys to share data. Beyond this, you can use sharedUserId to put both the base application and the add-on application in the same user ID. This will allow the applications to access each others' data files directory. A warning, though: it appears that adding a sharedUserId after the initial install causes the old data directory to still be under the old user ID, thus making all of your old files inaccessible (nor can you start writing new files - it kind of sucks). Google isn't acknowledging this issue, unfortunately.

One might think the way to go would be to use a ContentProvider, but if you're just doing an add-on for your own application, do you need to share the data with others? Besides that, ContentProviders are a much more difficult solution for a simple problem when you're working with just your own data. This isn't to say you shouldn't use ContentProviders, just that you should use the right tool for the job.