Monday, December 21, 2015

Lollipop external sdcard access with ACTION_OPEN_DOCUMENT_TREE

This is a very late post on the subject of the closure of external sdcard access.  The initial release in 4.4 was so very poor.  (  The above thread was closed with their last post on the subject.

So let's talk about OPEN_DOCUMENT_TREE.  On the surface it seems to do what an app would like.  On the technical side, it does accomplish it with lots of problems.  However, it leads to a poor user experience which is probably the worst of the issues.

It is easy to kick off the selection process, simply add:
Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(i, RESPONSE_ID)

You can give it a list of mimetypes in order to limit the possible locations:
i.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);

This open a 'picker' app that is system implemented.  It really looks crappy, imo.  What's worse is that many devices default to not showing the external sdcard.  It only shows the internal flash.  The user has to go to the overflow menu and 'unhide' the external sdcard.  While there are many users that understand technology, many of them don't and would not expect this.  At this point, the typical user will simply select some new directory on the internal flash which doesn't accomplish the goal at all.  (Most of the time users are trying to move items to external flash to preserve space of internal flash.)

Issue #2 is that you can't provide a hint to the directory that you would like access to.  There are some issues with trying to implement it (more on that later) but it would be nice if you could indicate the storage drive to use and possible path.  That way the user can just look at what the app suggests and hit ok or find another location.

Let me give an example here of why would you want it.  In my case, I want to provide access to external sdcard due to space requirements.  So the app is currently using internal flash and the user would like to use the external flash.  The Picker app is bad enough that the user many not realize they are simply picking a new internal flash spot.

Issue #3, you must use a ContentProvider in order to do things like inapp sharing.  Unfortunately, many apps, including Google apps, have no standard way of providing it.  Some require hard paths to files which is not possible with the new sdcard system.  (Note, copying the file to a temp location is not an answer).  The destination app crashes most of the time if you give a DocumentFile uri.  So you end up having to provide a hodge podge of solutions based upon the request.  It is getting better as new versions of the OS come out.

I know Google claimed security when this was implemented but they were not thinking of the user when they did.  They didn't implement security for both internal and external flash.  It was a very poorly thought out system.  And really it was made to enhance Google services rather than help developers or the user.  It's unfortunate that they took this track.  I like Android and that it is mostly open.

So, enough of the rant, what would I like to see:

1) Ability to provide a path to the directory you would like to use.
2) Indicate the flash to use (there could be more than one external flash drive)
3) Support for URIs in all file handling - some tools require a path to a file and simply cannot work with URIs (that are also DocumentFile uris).  Image processing, etc., to name a few.
4) Instead of a uri, allow getting the file path so that the hundreds of libraries out there that use file paths will work.  The current method is to retrieve an InputStream to the file and pass it to the library.  This probably needs some type of method to determine whether the file is local since the URI could be pointing to some cloud item.  The URI won't work for many libraries, they just don't have this ability.
5) Easy way to determine the amount of storage currently used in the device.