Runtime Permissions, Files, and ACTION_SEND
There has been pressure over the past couple of years for developers to
Uri values instead of
particularly for things like
ACTION_SEND. Android 6.0’s runtime
permission system increases that pressure a bit further.
READ_EXTERNAL_STORAGE is a
dangerous permission on Android 6.0,
and therefore is subject to the runtime permission system if your
targetSdkVersion is 23 or higher. This does not directly affect
the sending app in an
ACTION_SEND scenario, as that app could
be writing to
neither of which require any permissions as of Android 4.4. However,
those locations are app-specific, and so while the sender’s locations
are accessible by other apps handling
ACTION_SEND, the recipient needs
READ_EXTERNAL_STORAGE. Some developers will be trying to
move away from having such a permission, as they have to prompt users
Worse, there is a corner case that will trip up many implementers
ACTION_SEND. Suppose the following occurs:
The user installs the recipient app, but does not run it, or does not do anything when running it that would trigger
The user then uses some other app’s
ACTION_SENDcapability to try to send some content to the recipient app, in the form of a
Uripointing to a file on external storage
The recipient app is buggy, by not handling runtime permissions properly in its
Activity, believing (incorrectly) that the permission must already have been granted by this point
Stack Overflow user Daniele B ran into this, where Gmail and Hangouts were recipient apps with the bug. If Google can’t get this right, many other developers won’t get it right either.
If you are implementing an
you plan on supporting
Uri values, you need to include
the appropriate runtime permission checks in that
However, if you are the sender of
Intents, this is a
fine reason to move off of
Uri values and use
Uri values instead. This eliminates the whole
requirement in the first place.
provides a canned
ContentProvider implementation for serving up files.
The documentation is wrong, claiming that
getExternalFilesDir(), when it really points to
Environment.getExternalStorageDirectory(). Since I filed the issue two years ago, and it is still outstanding, it is unlikely that Google will ever fix the documentation.
Many recipients of
ACTION_SENDwill incorrectly assume that a
Uriis a file and attempt to get a local filesystem path from
MediaStore. Such developers are misguided, as there is no requirement that the
MediaStore, let alone have a filesystem path that the recipient can access (e.g., the file is on removable storage on Android 4.4+). However, you as the sender have to put up with misguided developers. Some apps will behave better if you subclass
FileProviderand put a
DATAcolumn in the results returned from
LegacyCompatCursorWrappercan help with this, as seen in this sample app covered in this really nifty book.
We are likely to stumble over these sorts of cases from time to time
over the next year, as we collectively apply the runtime permissions
system to our apps and see where things go haywire. When interacting
with other apps, the fewer
dangerous permissions you can require
them to have, the better off you will be in general.