Learn how to use fileprovider in Android with example

Learn how to use fileprovider in Android with example

Today we will be looking at the one of the confusing things in android i.e. fileprovider. It is confusing for beginners they do not understand how to use it and why to use it. So let us learn how to use fileprovider in Android with an example project.

Contents

What is a fileprovider in Android ?
Using FileProvider in Android application
    – Setting up FileProvider in manifest
    – Creating file_paths.xml file to add our file paths
    – Understanding what each file path actually mean
    – Getting the content URI

What is a FileProvider in Android ?

How long have you been exploring this concept of file provider in android ? I think it’s been quite a while but you have not found a easier explanation about it. Here I will simply explain what a fileprovider is and why even bother with it in the first place ?

FileProvider is simply a special subclass of ContentProvider which allows manipulating user data on storage more secure and easy ( not really at first ). It simply creates a content:/// URI instead of file:/// which makes secure.

How does it make the files accessing more secure ? To answer that question we must understand that using the FileProvider only a content:/// is exposed meaning the actual file location is hidden, and adds security.

But adding security means some headaches for developers especially for someone who is just starting with the Android Development. I will break down BITS of FileProvider below so let us continue.

Using FileProvider in Android application

Let us see how we can use the FileProvider in our application step by step.

Setting up FileProvider in manifest

Let us see how we can add the FileProvider definition in out manifest file. Add the code below in your AndroidManifest.xml file.

<manifest> <application> <provider android:name="androidx.core.content.FileProvider" android:authorities="np.com.naveenniraula.fileproviderexample" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest>

Creating file_paths.xml file to add our file paths

Now that we have added the FileProvider definition in our AndroidManifest.xml let us look at the <meta-data /> code.

<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />

You will receive an error at the code above because we have to mention the path for the FileProvider to access. Which we will do below but first lets create an Android resource directory.

Go to projects side bar and navigate to app > res. Right click there and click Android Resource Directory. name the directory xml and select xml from drop down.

After that create the file_paths.xml in the xml directory and add the contents below.

<paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="my_images" path="images/" /> <files-path name="my_docs" path="docs/" /> <external-files-path name="external_files_dir" path="/" /> <cache-path name="cache_dir" path="/" /> <external-cache-path name="external_cache_dir" path="/" /> <external-media-path name="external_media_dir" path="/" /> <external-media-path name="external_media_dir" path="/" /> </paths>

Confused about what the code above means ? Don’t be because I will break everything down.

Also Read: How to get current GPS location in Android

TECHENUM

Understanding what each file path actually mean

Now we have to understand something before proceeding. Everything is scoped with file paths. Meaning accessing anything outside defined file paths will cause a runtime exception.

Each type of paths you see between <paths> </paths> serve a purpose. And we are going to learn what that is with this fileprovider Android example.

Note: name and path is same for each. where name is the pointer and path is the actual location.

<files-path name="" path="/" />

This is the path will will be accessible by invoking this method Context.getFilesDir(). We will get a file instance pointing to the files dir. This directory is located in the internal storage area on your device.

<external-files-path name="" path="/" />

Same as above the only difference is it resides in the external removable storage area of the device. The root path is returned by Context.getExternalFilesDir(null).

<cache-path name="" path="/" />

This is same as files-path but it provides the root directory for internal area cache. Which is what you get when you invoke Context.getCacheDir().

<external-cache-path name="" path="/" />

Same as the the local cache but the difference is the cache directory is located in external storage area. Which you will get once you use Context.getExternalCacheDir().

<external-media-path name="" path="/" >

This path also defines the media directory located on the external storage area of your device. Which returns the path provided by Context.getExternalMediaDirs(). But this method is deprecated and MediaStore must be used.

<external-path name="" path="/" />

This path is relative to the external root of your device. And you can get this file by Environment.getExternalStorageDirectory(). As you normally would, this method is marked deprecated and must not be used normally. Always use file providers for any file reading.

Also Read: Learn How To Create Tabs With ViewPager2

TECHENUM

Getting the content URI

Now that we have understood what each means. Let us move forward and retrieve out URI, as it was our main goal.

We have set everything up let us create a temporary file in our cache directory. Let us write the code in out MainActivity as

val file = File(cacheDir.absolutePath, "test_file.txt") // create the parent files if necessary if (file.parentFile?.exists() == false) file.parentFile?.mkdirs()

Now that will create a file named test_file.txt in our cache directory, remember <cache-dir /> ?

Next we will update the URI into our TextView just to make sure it worked.

// get the URI for your file // do whatever you want with the URI val uri = FileProvider.getUriForFile(this, FILE_AUTHORITY, file) // show the uri in the UI val textView: TextView = findViewById(R.id.hello_world) textView.text = uri.toString()

Look at the FILE_AUTHORITY which we have declared in the companion object block. The full code for MainActivity is provided below:

class MainActivity : AppCompatActivity() { companion object { // same as the one defined in android:authorities in AndroidManifest.xml const val FILE_AUTHORITY = "np.com.naveenniraula.fileproviderexample" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val file = File(cacheDir.absolutePath, "test_file.txt") // create the parent files if necessary if (file.parentFile?.exists() == false) file.parentFile?.mkdirs() // get the URI for your file // do whatever you want with the URI val uri = FileProvider.getUriForFile(this, FILE_AUTHORITY, file) // show the uri in the UI val textView: TextView = findViewById(R.id.hello_world) textView.text = uri.toString() Log.i("MainActivity", "we have uri : $uri") } }

Now we are done. What you do with the URI is up to you. Next time I will teach you how can you get the actual file from URI. Till then, keep learning.

For reference you can checkout official documentation, here.

Also Read: 3 Essential Datastructures in Object Oriented Programming

TECHENUM

Naveen Niraula

An Android developer with passion for latest technologies. Likes to learn and share the findings and techniques. Also shows keen interest in networking.

Leave a Reply