A Tale of Two ExifInterfaces

Many applications need access to EXIF headers from JPEG files, for everything from getting at geotag information to simply knowing how to rotate the image to display to the user.

Android has had an ExifInterface class in the Android SDK since API Level 5. While support for a few more tags have been added over the years, the class is largely unchanged since it was introduced.

This includes one major limitation: it only works on files. You have to supply it with a filesystem path to the JPEG image to examine.

Back in 2009, this was not an unreasonable choice, given the programming techniques of that Android era. Nowadays, it is just another hurdle for developers to overcome, as many times your JPEG comes via a content Uri. You get such a Uri quite frequently from ACTION_GET_CONTENT and all the time from ACTION_OPEN_DOCUMENT. For compatibility with other apps (e.g., email clients), you may support content schemes in your ACTION_VIEW <intent-filter>, or need to deal with them in reading streams in your ACTION_SEND activity, etc.

Some developers attempt to handle this by trying to hack some way to get the filesystem path behind the Uri. Such developers desperately need to be slapped with a trout. There is no requirement that a Uri be backed by a file on the filesystem, let alone one that you can access and read.

Some developers wind up making a copy of the content as a local file, just to feed it to ExifInterface.

What makes all of this sad is that Android has had better EXIF tag code for years. This includes support for processing tags from an InputStream, such as the one you might get via ContentResolver for the JPEG identified by a Uri. The class that provides this support even has a familiar name: ExifInterface.

It’s just a different ExifInterface.

What is even more bizarre is that Google has copies of ExifInterface in several projects, rather than consolidating on one that everybody can access, including us lowly Android app developers.

We have:

It would be lovely if one of those would make it into the Android Support Library.

Even without that, though, if you need to read EXIF tags, consider using one of those implementations, rather than going through all sorts of shenanigans to get your JPEG into a local file, just to be able to use the SDK’s limited ExifInterface.