Categories
tech

Scoped Storage Stories: Trees

Android 10 is a great deal proscribing get admission to to exterior garage by way of filesystem APIs. Instead, we wish to use different APIs to paintings with content material. This is the fourth put up in a chain the place we will be able to discover tips on how to paintings with the ones possible choices, beginning with the Storage Access Framework (SAF).


Working with particular person items of content material by way of ACTION_OPEN_DOCUMENT or ACTION_CREATE_DOCUMENT isn’t that tricky and isn’t that other than running with information.

However, assume you want to paintings with a number of comparable items of content material. For instance, you need to provide a guide backup mechanism, and moderately than backing up a number of information to a unmarried ZIP, you need to provide a backup to a user-chosen listing.

In concept, it’s essential to nonetheless use ACTION_CREATE_DOCUMENT for this, asking the person for the positioning of each and every piece of content material that you simply need to create as a part of the backup. This is tense for the person, as they’ve to move in the course of the ACTION_CREATE_DOCUMENT UI N instances to your N items of content material. And if the person screws one thing up — akin to opting for other directories as an alternative of the similar listing for the entire content material — your app would possibly run into issues in eating that content material afterward.

What could be higher is that if the person may just create a listing for you, then grant you get admission to to that complete listing. You may just then put your content material into that listing as you spot are compatible.

Unfortunately, that isn’t totally supported. What is supported is for the person to select some “listing”, by way of ACTION_OPEN_DOCUMENT_TREE, on Android 5.1+. Your app can then create its personal “sub-directory” within the user-chosen location, then put your content material there.

Here, I’ve “listing” and “sub-directory” in quotes, as a result of technically that isn’t what you might be running with. You are running with file timber, reflecting the title ACTION_OPEN_DOCUMENT_TREE. Whether or now not a given file tree displays some listing on some filesystem on some gadget is as much as the implementers of the user-selected file supplier. In follow, it’s more likely to be a filesystem listing at the software, as few cloud garage suppliers appear to give a boost to ACTION_OPEN_DOCUMENT_TREE.

At the outset, you utilize ACTION_OPEN_DOCUMENT_TREE in a similar way to how you utilize ACTION_OPEN_DOCUMENT. You create an Intent with ACTION_OPEN_DOCUMENT_TREE because the motion, then cross that Intent to get startedActivityForEnd result():

get startedActivityForEnd result(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), REQUEST_TREE)  

Then, in onActivityEnd result(), you’ll be able to get a Uri that represents the tree:

override amusing onActivityEnd result(requestCode: Int, resultCode: Int, information: Intent?) {    tremendous.onActivityEnd result(requestCode, resultCode, information)      if (resultCode == Activity.RESULT_OK) {      information?.information?.let { useTheTree(it) }    }  }    non-public amusing useTheTree(root: Uri) {    TODO("one thing helpful, however on a background thread please")  }  

From there, what you do will range in line with state of affairs.

Suppose you need to save lots of a backup of a number of information, as steered previous. You may just:

  • Wrap that Uri in a RecordFile, by way of RecordFile.fromTreeUri()

  • Call createDirectory() on that RecordFile to create some form of sub-tree and come up with a RecordFile pointing to it

  • Call createFile() at the sub-tree RecordFile for each and every report that you need to again up, to get a RecordFile representing the backup of that report

  • Call getUri() at the backup RecordFile and use that with ContentResolver and openOutputStream() to get an OutputStream that you’ll be able to use to create the backup itself

Suppose as an alternative that you need to revive from the backup. If your directions are for the person to select the sub-tree that you simply created above, it’s essential to then do that with the Uri from ACTION_OPEN_DOCUMENT_TREE:

  • Wrap that Uri in a RecordFile, by way of RecordFile.fromTreeUri()

  • Call checklistFiles() to get an array of RecordFile items, representing the contents of that tree

  • Examine the ones to peer if they appear to be your backed-up content material, appearing some error to the person if it looks as if they selected the fallacious position

  • Use getUri() for each and every of the ones RecordFile items and use that with ContentResolver and openInputStream() to get an InputStream that you’ll be able to use to revive the content material from the backup

There are many different patterns that it’s essential to observe — those are only for representation functions. The key’s that you simply use RecordFile similar to you possibly can use File for growing or iterating over the contents of a listing. While the main points are other, the overall method is equal to with vintage Java report I/O.


Previously, I lined:

  • The fundamentals of the usage of the Storage Access Framework
  • Getting sturdy get admission to to the chosen content material
  • Working with RecordFile for particular person paperwork

In my subsequent put up within the sequence, I will be able to indicate the constraints of RecordFile for batch operations, and can indicate choice approaches that can reinforce efficiency.

#Google #Android #Smartphones #OS #News @ndrdnws #ndrdnws #AndroidNews