URI (Unique Resource Identifier)

URI (Unique Resource Identifier)

Unique Android Resource Identifier to read or write the files

Table of contents

No heading

No headings in the article.

The name only suggests that it is a unique identifier for the resource. In Windows or macOS, we can identify the uniqueness of the file with the path and the name specified for that file.

But in Android, there are four majorly different types of resources that we can differentiate based on their access.

  1. Resource URI

  2. File URI

  3. Content URI

  4. Data URI

We will see the details of these types one by one, as follows.

  1. Resource URI: It is one type of resource that is stored under the 'res' folder of the Android project, where users can parse and read the file as a normal byte array.

Example Code:
val uri = Uri.parse("android.resource://$packageName/drawable/fileName")

val bytes = contentResolver.openInputStream(uri)?.use{ it.readBytes() }

  1. File URI: It is another type of resource where the app can use the internal storage, which is only accessible to that app for reading and writing files. Additionally, this resource is private to that particular app and not exposed to any other app.

Example Code:
val file = File(fileDir, "fileName.jpg") FileOutputStream(file).use{ it.write(bytes) }

println(file.toUri()) //Prints [file://data/user/0/com.example.code/files/fileName.jpg](file://data/user/0/com.example.code/files/f..)

Here, we can get the file path, but the permissions related to that particular file are not similar to the permissions in Windows or Linux. In Android, permissions related to files may vary based on the path where it is stored and the access that is granted to that particular file.

  1. Content: This is another type of resource where we want to share our files between the apps using Content Uris.

Example Code:

setContent{ UrisTheme{ val pickImage = rememberLauncherForActivityResult( contract = ActivityResultContracts.GetContent(), onResult = { contentUri -> println(contentUri) } ) Button( onClick ={ pickImage.launch("image/*") } ){ Text(text="pick Image") } } }
//Prints content://com.android.providers.media.documents/document/image%6678678

In the above example, upon button click, the app tries to get the file from the gallery. When we pick up a file from it, the gallery app converts the actual file into a content URI, grants temporary permission to read the file, and sends it to the app via the activity result launcher, from which we can obtain the URI of that particular file.

And also, the URI may not represent an exact file path. If the user deletes that particular file in another app, the app might want to showcase it in the future. In that case, it may store it in the internal storage by converting it to a byte array, as mentioned in the example above (example 2).

  1. Data: This type of resource is very rarely used. It can be defined based on the data type, such as plain text and charset, along with the actual data

    Example Code:

val dataUri = Uri.parse("data:text/pain;charset=UTF-8,Hello%20World")

Learned from: Phillip Lackner

Did you find this article valuable?

Support Sandeep Kulkarni by becoming a sponsor. Any amount is appreciated!