How I Isolated the Adobe Reader Activity Issue

Earlier today, somebody posted a question on StackOverflow regarding a SecurityException when trying to send a PDF to Adobe Reader via ACTION_SEND. I thought it might be useful to write up how I went about determining the nature of the problem.

The question author took care of my first guess for me, by indicating that the ACTION_SEND code worked fine with other PDF apps. That eliminated any issue regarding read permissions on wherever the PDF was stored (not mentioned in the question).

Fortunately, I have two apps installed on my Galaxy Nexus relevant to this issue. One is Adobe Reader, as you might expect. The other is AppXplore, published by Sony (or Sony Ericsson, as their app description still lists them).

AppXplore is a very handy app for inspecting the manifest of another application installed on your device. Simply running AppXplore and tapping on an app brings up general information about the app itself. Then, choosing a “Show manifest file” options menu item brings up a scrollable TextView of the contents of the manifest… more or less. It is actually “a regenerated verison of AndroidManifest.xml from application’s binary package and may not match exactly with the original AndroidManifest.xml file”.

However, it is certainly ample for problems like this. And, there are no pesky software piracy issues typically involved in getting one’s hands on an APK file for an app on the Play Store.

The SO question helpfully listed the activity that was failing: ARSendForSignature. Scrolling down in the generated manifest for Adobe Reader shows that ARSendForSignature indeed has an <intent-filter> for ACTION_SEND. However, it also has android:exported="false".

The default exported state for Android components is:

  • Components with an <intent-filter> are exported and can be launched by other applications
  • A ContentProvider is exported by default, despite having no <intent-filter>
  • Everything else is not exported by default and therefore cannot be launched by other applications

The android:exported attribute on an <activity> allows you to override those defaults.

So, what happens?

The user does something in the original activity that triggers a startActivity() with an ACTION_SEND Intent for the application/pdf MIME type. The chooser lists all activities that have an <intent-filter> matching that specification. When the user taps on the chooser item for Adobe Reader, the chooser crashes, because it cannot start up Adobe Reader’s ACTION_SEND activity, because it is marked as not exported.

The real problem here is the chooser. The chooser should be filtering out anything that is not exported and is not from its own application, no matter what the <intent-filter> may have. That’s why I went ahead, reproduced the problem with my own code, and filed an issue.

Tactically, though, Adobe should either mark this activity as being exported (so ACTION_SEND works) or remove the <intent-filter> (thereby having it not appear in choosers for ACTION_SEND).