Saving Files In Scoped Storage

Syed Taha Alam
2 min readApr 8, 2021

With the release of android 10 google brings the concept of scoped storage. Scoped Storage according to google documentation.

To give users more control over their files and to limit file clutter, apps that target Android 10 (API level 29) and higher are given scoped access into external storage, or scoped storage, by default. Such apps have access only to the app-specific directory on external storage, as well as specific types of media that the app has created.

If it is needed to store files outside the app-specific directory it is required to Content resolvers and MediaStore API.

To save a file we can do following

val contentResolver = context.contentResolver
val relativeLocation = Environment.DIRECTORY_PICTURES
val directoy = "ambit"
val fname = Constants.FILE_NAME + System.currentTimeMillis() + ".png"
val values = ContentValues().apply {
put(MediaStore.Images.Media.RELATIVE_PATH, "$relativeLocation/$directoy")
put(MediaStore.Images.Media.DISPLAY_NAME, fname)
put(MediaStore.Images.Media.MIME_TYPE, "image/png")
put(MediaStore.Images.Media.IS_PENDING, 0)
}
val collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
return try {
val item = contentResolver.insert(collection, values)
item!!
} catch (e: Exception) {
Uri.EMPTY
}

in the above mentioned code:

  • MediaStore.Images.Media.RELATIVE_PATH is the path at which the file will be stored.
  • MediaStore.Images.Media.DISPLAY_NAME that will be displayed on the file display in file explorer.
  • MediaStore.Images.Media.MIME_TYPE type of the image file.
  • MediaStore.Images.Media.IS_PENDING this value makes the file visible or hidden to the file explorer. it has two values 0 and 1. 0 means the file has been saved and ready to be used. 1 means files is under the process. we have to change the value 1 to zero if the process is completed successfully.
  • collection variable is that contains the main directory uri from which the relative path is added.
  • and on last making everything according to the requirement we have to insert it and get the content uri of the newly created file.

After this process an empty file will be created that has no content in it. we can also add it via content resolver.

try {
OutputStream out = context.getContentResolver().openOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();

} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

output stream can be created with the help of content resolvers by by which the data will be stored inside the newly created file.

we can also create PDF or CSV or any other type of file but we have to make the collection path according to it as

val collection = MediaStore.Downloads.EXTERNAL_CONTENT_URI

--

--

Syed Taha Alam

Software Engineer passionate about the web and all the latest tech 🌐