Reader small image

You're reading from  Android Studio 3.5 Development Essentials - Kotlin Edition

Product typeBook
Published inMay 2019
Reading LevelIntermediate
PublisherPackt
ISBN-139781951442002
Edition1st Edition
Languages
Right arrow
Author (1)
Neil Smyth
Neil Smyth
author image
Neil Smyth

Neil Smyth has over 25 years of experience in the IT industry, including roles in software development and enterprise-level UNIX and Linux system administration. In addition to a bachelor's degree in information technology, he also holds A+, Security+, Network+, Project+, and Microsoft Certified Professional certifications and is a CIW Database Design Specialist. Neil is the co-founder and CEO of Payload Media, Inc. (a technical content publishing company), and the author of the Essentials range of programming and system administration books.
Read more about Neil Smyth

Right arrow

74. Accessing Cloud Storage using the Android Storage Access Framework

Recent years have seen the wide adoption of remote storage services (otherwise known as “cloud storage”) to store user files and data. Driving this growth are two key factors. One is that most mobile devices now provide continuous, high speed internet connectivity, thereby making the transfer of data fast and affordable. The second factor is that, relative to traditional computer systems (such as desktops and laptops) these mobile devices are constrained in terms of internal storage resources. A high specification Android tablet today, for example, typically comes with 128Gb of storage capacity. When compared with a mid-range laptop system with a 750Gb disk drive, the need for the seamless remote storage of files is a key requirement for many mobile applications today.

In recognition of this fact, Google introduced the Storage Access Framework as part of the Android 4.4 SDK. This chapter will provide...

74.1 The Storage Access Framework

From the perspective of the user, the Storage Access Framework provides an intuitive user interface that allows the user to browse, select, delete and create files hosted by storage services (also referred to as document providers) from within Android applications. Using this browsing interface (also referred to as the picker), users can, for example, browse through the files (such as documents, audio, images and videos) hosted by their chosen document providers. Figure 74-1, for example, shows the picker user interface displaying a collection of files hosted by a document provider service:

Figure 74-1

Document providers can range from cloud-based services to local document providers running on the same device as the client application. At the time of writing, the most prominent document providers compatible with the Storage Access Framework are Box and, unsurprisingly, Google Drive. It is highly likely that other cloud storage providers...

74.2 Working with the Storage Access Framework

Android includes a set of Intents designed to integrate the features of the Storage Access Framework into Android applications. These intents display the Storage Access Framework picker user interface to the user and return the results of the interaction to the application via a call to the onActivityResult() method of the activity that launched the intent. When the onActivityResult() method is called, it is passed the Uri of the selected file together with a value indicating the success or otherwise of the operation.

The Storage Access Framework intents can be summarized as follows:

ACTION_OPEN_DOCUMENT – Provides the user with access to the picker user interface so that files may be selected from the document providers configured on the device. Selected files are passed back to the application in the form of Uri objects.

ACTION_CREATE_DOCUMENT – Allows the user to select a document provider, a...

74.3 Filtering Picker File Listings

The files listed within the picker user interface when an intent is started may be filtered using a variety of options. Consider, for example, the following code to start an ACTION_OPEN_DOCUMENT intent:

val OPEN_REQUEST_CODE = 41

val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)

startActivityForResult(intent, OPEN_REQUEST_CODE)

When executed, the above code will cause the picker user interface to be displayed, allowing the user to browse and select any files hosted by available document providers. Once a file has been selected by the user, a reference to that file will be provided to the application in the form of a Uri object. The application can then open the file using the openFileDescriptor(Uri, String) method. There is some risk, however, that not all files listed by a document provider can be opened in this way. The exclusion of such files within the picker can be achieved by modifying the intent using the CATEGORY_OPENABLE option...

74.4 Handling Intent Results

When an intent returns control to the application, it does so by calling the onActivityResult() method of the activity which started the intent. This method is passed the request code that was handed to the intent at launch time, a result code indicating whether or not the intent was successful and a result data object containing the Uri of the selected file. The following code, for example, might be used as the basis for handling the results from the ACTION_OPEN_DOCUMENT intent outlined in the previous section:

public override fun onActivityResult(requestCode: Int, resultCode: Int,

                                     resultData: Intent?) {

 

    var currentUri: Uri? = null

 

    if (resultCode == Activity...

74.5 Reading the Content of a File

The exact steps required to read the content of a file hosted by a document provider will depend to a large extent on the type of the file. The steps to read lines from a text file, for example, differ from those for image or audio files.

An image file can be assigned to a Bitmap object by extracting the file descriptor from the Uri object and then decoding the image into a BitmapFactory instance. For example:

val pFileDescriptor = contentResolver.openFileDescriptor(uri, "r")

val fileDescriptor = pFileDescriptor.fileDescriptor

 

val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)

 

pFileDescriptor.close()

 

val myImageView = ImageView(this)

myImageView.setImageBitmap(image)

Note that the file descriptor is opened in “r” mode. This indicates that the file is to be opened for reading. Other options are “w” for write access and “rwt” for read...

74.6 Writing Content to a File

Writing to an open file hosted by a document provider is similar to reading with the exception that an output stream is used instead of an input stream. The following code, for example, writes text to the output stream of the storage based file referenced by the specified Uri:

try {

    val pfd = contentResolver.openFileDescriptor(uri, "w")

 

    val fileOutputStream = FileOutputStream(

            pfd.fileDescriptor)

 

    val textContent = fileText.text.toString()

 

    fileOutputStream.write(textContent.toByteArray())

 

    fileOutputStream.close()

    pfd.close()

} catch (e: FileNotFoundException) {

    e.printStackTrace()

} catch (e: IOException) {

    e...

74.7 Deleting a File

Whether a file can be deleted from storage depends on whether or not the file’s document provider supports deletion of the file. Assuming deletion is permitted, it may be performed on a designated Uri as follows:

if (DocumentsContract.deleteDocument(contentResolver, uri))

    // Deletion was successful

else

    // Deletion failed

74.8 Gaining Persistent Access to a File

When an application gains access to a file via the Storage Access Framework, the access will remain valid until the Android device on which the application is running is restarted. Persistent access to a specific file can be obtained by “taking” the necessary permissions for the Uri. The following code, for example, persists read and write permissions for the file referenced by the fileUri Uri instance:

val takeFlags = (intent.flags and (Intent.FLAG_GRANT_READ_URI_PERMISSION

                                       or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)

 

contentResolver.takePersistableUriPermission(fileUri, takeFlags)

Once the permissions for the file have been taken by the application, and assuming the Uri has been...

74.9 Summary

It is interesting to consider how perceptions of storage have changed in recent years. Once synonymous with high capacity internal hard disk drives, the term “storage” is now just as likely to refer to storage space hosted remotely in the cloud and accessed over an internet connection. This is increasingly the case with the wide adoption of resource constrained, “always-connected” mobile devices with minimal internal storage capacity.

The Android Storage Access Framework provides a simple mechanism for both users and application developers to seamlessly gain access to files stored in the cloud. Through the use of a set of intents and a built-in user interface for selecting document providers and files, comprehensive cloud based storage can now be integrated into Android applications with a minimal amount of coding.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Android Studio 3.5 Development Essentials - Kotlin Edition
Published in: May 2019Publisher: PacktISBN-13: 9781951442002
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at AU $19.99/month. Cancel anytime

Author (1)

author image
Neil Smyth

Neil Smyth has over 25 years of experience in the IT industry, including roles in software development and enterprise-level UNIX and Linux system administration. In addition to a bachelor's degree in information technology, he also holds A+, Security+, Network+, Project+, and Microsoft Certified Professional certifications and is a CIW Database Design Specialist. Neil is the co-founder and CEO of Payload Media, Inc. (a technical content publishing company), and the author of the Essentials range of programming and system administration books.
Read more about Neil Smyth