If Your Activity Has an <intent-filter>, Export It
Slightly less than two years ago, I pointed out a problem
in Android where an activity that has an <intent-filter>
, but
is marked as not being exported (android:exported="false"
),
screws up the chooser. The chooser ignores the exported flag and
offers up the non-exported activity to the user… then promptly
crashes if the user actually chooses it.
Dianne Hackborn specifically called this out as being a bug in the app:
would generally consider this a bug in the app – if you have an activity that you aren’t allowing other apps to launch, why the heck are you publishing an intent filter that they will match to try to launch?
What would be nice, of course, is if Google paid attention to its own advice.
The AOSP Music app has five activities that violate this rule:
VideoBrowserActivity
ArtistAlbumBrowserActivity
AlbumBrowserActivity
NowPlayingActivity
TrackBrowserActivity
As a result, apps trying to start activities that match the
<intent-filter>
will crash with a SecurityException
. I
filed an issue about this
over six months ago, with no response to date.
The lesson to you is: don’t be like Google. Instead, be like Google.
If your activity should not be visible to third parties, simply
drop the <intent-filter>
and use an explicit Intent
to start
it. You can still include things like an action string on the
Intent
, but use the explicit class or ComponentName
control
the routing of the Intent
. Dropping the <intent-filter>
will
cause your activity to be non-exported by default, and you will
not show up in choosers when you are not an eligible option.
I still would like the chooser to take permissions, exported status, etc. into account. Maybe I’ll write my own chooser someday…