PSA: file: Scheme Ban in N Developer Preview

If you are building an app against N Developer Preview 1, with a targetSdkVersion of 'N', it appears that you can no longer use file: Uri values in many places. In particular, based on my testing:

  • You cannot use a file: Uri as the “data” of an Intent to be used with an activity, such as for an ACTION_VIEW Intent, whether to be used immediately or to be wrapped in a PendingIntent. In other words, startActivity(Intent.ACTION_VIEW, Uri.fromFile(...)) will not work.

  • You cannot pass a file: Uri in an Intent extra, such as EXTRA_OUTPUT for ACTION_IMAGE_CAPTURE.

  • You cannot put a file: Uri on the clipboard, using things like ClipData.newUri().

If you try to do these sorts of things, you will crash with a FileUriExposedException exception.

This is coming from an updated edition of StrictMode. StrictMode.VmPolicy.Builder has a penaltyDeathOnFileUriExposure() method that triggers the detection of file: Uri values and the resulting FileUriExposedException exceptions. And, it appears that this is pre-configured, much as how StrictMode is pre-configured to apply penaltyDeathOnNetwork() (the source of your NetworkOnMainThreadException crashes) on Android 4.0+.

It is unclear if this is a “trial balloon” and will be rescinded before Android N ships, or whether this is the expected behavior for the final shipping product. You may wish to keep track of this issue to perhaps find out more about these sorts of plans.

Assuming that it is here to stay, if you plan to use the latest targetSdkVersion once Android N ships, you need to start using content: Uri values:

  • Apps that have been producing file: Uri values will need to use things like FileProvider to produce content: Uri values instead

  • Apps that have been consuming file: Uri values will need to make sure that they also support content: Uri values… and do so correctly

I can understand why Google is doing this. They have been beating the drum for some time now to try to get developers to switch off of file: Uri values.

However, I worry.

Too many apps do not handle content: Uri values well. They assume that a content: Uri must be coming from MediaStore and do some unfortunate things, such as trying to query for a DATA column, in hopes of scoring a file path. FileProvider does not handle this, resulting in crashes. I had to write a LegacyCompatCursorWrapper just to help developers using FileProvider to better cope with poorly-written client apps.

This includes dealing with broken apps from the likes of Samsung, Twitter, and Google. This is not a problem that is somehow limited to inexperienced developers or small firms. In the case of Twitter and Google, I think that they have fixed their apps, but I am sure that plenty of others are out there. After all, I see countless questions from people on Stack Overflow, using older broken advice, trying to just strip the path off a Uri and use it to access the filesystem.

Now Google is trying to force developers to publish content: Uri values. That only works if a preponderance of consumers of content: Uri values do so properly. I fear that too many do not. Developers will be caught between the Scylla of Android N and the Charybdis of user complaints that the app does not work with with XYZ other app that screwed up consuming the content: Uri. Experienced developers can work around this, by keeping targetSdkVersion low or possibly cooking up some reflection-based hack to de-fang StrictMode. Newcomers to Android will wonder why all of the existing blog posts, Stack Overflow answers, and older books are broken when it comes to working with Uri.

On the engineering side, I don’t have a better answer, other than for Google to include some sort of content: Uri compatibility testing as part of evaluating apps for the Play Store.

I really hope that Google will do more to educate developers about this exception and how to correctly produce and consume content: Uri values. Since FileUriExposedException is not included in the N Developer Preview “Behavior Changes” documentation, I do not hold out much hope. Heck, at this moment, the only pages indexed on Google for the search term of FileUriExposedException are things that I wrote, since the N Developer Preview JavaDocs are only distributed in ZIP form.

Time will tell whether FileUriExposedException and the revised StrictMode are a figment of my imagination, are a fluke of the N Developer Preview 1, or are here to stay. However, let this serve as a wakeup call: use file: Uri values at your own peril going forward.