How to open PDF Programmatically using Intent in Android

Yesterday I received an email from one of our readers and he asked me to fix his issue where he was not able to open PDF from the storage when the user clicked on the button. And his application was running flawlessly on an older version of Android. After Android 11, his application was not working as per his plan.

I thought to resolve this, but he didn’t share the complete code, so I thought, why not create a demo application from scratch for our readers?

While developing the demo application to open PDF files, I got the following errors: “android.os.FileUriExposedException: file:///storage/emulated/0/TRENDOCEANS.pdf exposed beyond app through Intent.getData()” and “Couldn’t find meta-data for provider with authority”. If you also get this kind of error, then you can read our dedicated article on this issue.

Open PDF Programmatically using Intent

Before starting the process, let me walk through the concept of our demo application. First and foremost, we will ask for permission. Then, the user will see a button that will invoke intent to open a pdf file that is already available in the root folder of the device, and that’s it.

Fair enough!

Create new project in Android Studio

I’m not going to show you how to create a new project in Android Studio because you know how to do it very well. Still, if you want, then take a glimpse at how to create a new project in Android Studio, which is very similar to this project.

Create Basic Layout in activity_main.xml

After creating a new project, the first thing you need to do is modify activity_main.xml to add a button that will invoke the openPDF() method, which we are going to create in the MainActivity file. And the rest of the options are just for visual appeal that you can skip for now. 

Modify AndroidManifest.xml

Now you will modify AndroidManifest.xml to add <uses-permission></uses-permission> and <provider></provider> tag nested with <meta></meta> tag.

A first <uses-permission/> advisable to list out the available applications to support the particular actions.

I would recommend you read this article for a better perspective on package filtering.

And the last <uses-permission/> is necessary for the latest Android version. If you are using Android 12, you will see two types of permission are available compared to the previous Android version when you want to read files.

List of Permission in Android 12 to read file
List of Permission in Android 12 to read the file

At the bottom, you need to add <provider/> tag which is nested with <meta/> tag to provide a location to access the storage directory.

At present, you cannot access any file directly. First, you need to add <provider/> <meta/> tag and specify the location in @xml/file_path.xml “Couldn’t find meta-data for provider with authority.”

Create file_path in xml resource

The file @xml/file_path will get highlighted in red to indicate the missing file. Simply, you just need to hover on @xml/file_path and click on Create xml resource file to create the missing file.

Click on “Create xml resource file”

The next screen will ask you to enter the following details. After making the changes, click on “OK” to move ahead. 

Change root elements to "paths"
Change root elements to “paths”

And copy the below content to @xml/file_path to read the root directory of the external storage with the “external_file” name.

Modify MainActivity to open PDF file in external applications

First, you need to add a static constant value for permission check under the MainActivity class. You can simply copy the below code and paste it into your editor.

Inside the onCreate method, you need to call verifyStoragePermission (this). After that, initialize the button to set a click listener. Under the click listener, create a new method called openPDF ().

This verifyStoragePermission method is used to request and verify read permission.

The first step will be used to check the current status of permission. If it’s –1, then it will prompt you to accept the permission. For Android 12, devices need extra permission to read all files.

That’s a reason you need to use Intent to ask permission to read all file access permissions.

Inside openPDF(), you need to specify the location of the PDF file using the File class and save the value in a file variable which you will use in uriPdfPath to declare the path; after that, using Intent, you can call an external app to read the PDF.

Earlier, we used “Uri path = Uri.fromFile(file);” to get the URI of a location, but it’s not working anymore, so you have to use “Uri uriPdfPath = FileProvider.getUriForFile()” and specify the .provider to declare the location you are going to access in @xml/file_path.xml.

And that’s a reason for the following error: “android.os.FileUriExposedException: file:///storage/emulated/0/TRENDOCEANS.pdf exposed beyond app through Intent.getData()”

Before running the application please verify the code of MainActivity.

Run application to read PDF

Once the application is ready install it on your device and tests the functionality before that keep the PDF in the specified location of your device.

Wrap up

That’s all to open PDF programmatically using Intent in Android.

Along with that, we have shown you the method to resolve “android.os.FileUriExposedException: file:///storage/emulated/0/TRENDOCEANS.pdf exposed beyond app through Intent.getData()” and “Couldn’t find meta-data for provider with authority”.

And I’ll upload this project on Github for your reference.

Leave a Reply