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:
- The
packages/apps/Camera2
copy - The
packages/apps/Gallery2
copy - The
packages/apps/Launcher3
copy - And the
packages/apps/Messaging
copy
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
.