Opening pdf file Error: This file could not be accessed Check the location or the network and try again. Android 6 Marshmallow

16,315

Solution 1

Just found a working solution for both previous and new Android OS:

Step 1: Create a class names SampleContentProvider

import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * Created by naveed on 7/2/16.
 */
public class SampleContentProvider extends ContentProvider {

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        File privateFile = new File(uri.getPath());
        return ParcelFileDescriptor.open(privateFile, ParcelFileDescriptor.MODE_READ_ONLY);
    }

    @Override
    public boolean onCreate() {
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        return null;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        return null;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        return 0;
    }
}

Step2: Add the provider in application body of manifest:

<provider
        android:name=".SampleContentProvider"
        android:authorities="your_package_name"
        android:exported="true" />

Step 3: Now finally pass the file absolute path to the intent by using Uri

  Intent intent = new Intent(Intent.ACTION_VIEW);
        File file = new File(getFilesDir(), "myfile.pdf");
        String absoluteFilePath = file.getAbsolutePath();
        String mimeType = "application/pdf";
        Uri uri = Uri.parse("content://"+"Your_package_name"+"/" + absoluteFilePath);
        intent.setDataAndType(uri, mimeType);
        Intent intentChooser = Intent.createChooser(intent, "Choose Pdf Application");
        startActivity(intentChooser);

I hope this will help you. Thanks everyone for your help.

Solution 2

After reviewing the answers above the simplest solution is as follows.

    Uri pdf = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", file);

    Intent pdfOpenintent = new Intent(Intent.ACTION_VIEW);
    pdfOpenintent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    pdfOpenintent.setDataAndType(pdf, "application/pdf");

    try {
        startActivity(pdfOpenintent);
    } catch (ActivityNotFoundException e) {
        // handle no application here....
    }

The key is to set the both the FLAG_GRANT_READ_URI_PERMISSION and FLAG_ACTIVITY_CLEAR_TOP at the same time.

Make sure to have your provider declared in the ApplicationManifest.xml

<provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>
    </provider>

Hers is the provider_paths file

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

Solution 3

Use FileProvider (which is anyway the accepted approach since Android Nougat - otherwise you'll be getting android.os.FileUriExposedException) and then don't forget to grant permissions to all the packages it needs:

Uri uri = FileProvider.getUriForFile(
                                context,
                                context.getApplicationContext().getPackageName(), myFile);

                        Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
                        pdfIntent.setDataAndType(apkURI, "application/pdf");
                        pdfIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        grantAllUriPermissions(context, pdfIntent, apkURI);

Where grantAllUriPermissions():

private void grantAllUriPermissions(Context context, Intent intent, Uri uri) {
        List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (ResolveInfo resolveInfo : resInfoList) {
            String packageName = resolveInfo.activityInfo.packageName;
            context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
}
Share:
16,315

Related videos on Youtube

Naveed Ahmad
Author by

Naveed Ahmad

-Design and build advanced applications for the Android and iOS. -Collaborate with cross-functional teams to define, design, and ship new features. -Work with outside data sources and API's. -Unit-test code for robustness, including edge cases, usability, and general reliability. -Work on bug fixing and improving application performance. -Continuously discover, evaluate, and implement new technologies to maximize development efficiency. Some key points: Can work with team. Quality and in time solutions to complex problems. Meet the tough deadlines. Ability to work on multiple projects. Technical discussions Email : [email protected] Skype : naveedahmad6699 Contact # : +92-345-9647789

Updated on October 14, 2022

Comments

  • Naveed Ahmad
    Naveed Ahmad over 1 year

    I am trying to get file from external storage, then I have to send that file to pdf readers using intents. Previously below code was working fine but after installing Android 6 (Marshmallow update), my code is not working and getting a toast message

    "This file could not be accessed Check the location or the network and try again."

    (This is due to new android runtime permissions). I just tried all the solutions (Content Providers etc but not working) Any Solutions?

     File file = new File(getFilesDir(), "myfile.pdf");
     Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.setDataAndType(Uri.fromFile(file), "application/pdf");
            intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            Intent intentChooser = Intent.createChooser(intent, "Choose Pdf Application");
            try {
                startActivity(intentChooser);
            } catch (ActivityNotFoundException e) {
                //com.adobe.reader
                startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=com.adobe.reader")));
            }
    
    • Naveed Ahmad
      Naveed Ahmad almost 8 years
      I tried this solution but didn't work for me. I just found a solution, posted as answer. Thanks for your help and support.
  • CommonsWare
    CommonsWare almost 8 years
    A simpler and more robust solution would be to use FileProvider. Your provider, since it does not support the OpenableColumns and does not support getType(), will fail with some consumers of your content.
  • Naveed Ahmad
    Naveed Ahmad almost 8 years
    @CommonsWare I checked your solutions but I was failed, do you have simple sample app with full documentation?
  • CommonsWare
    CommonsWare almost 8 years
    "With full documentation" comes in the form of my book. Several sample apps from that book are available that show FileProvider in use, such as this one, this one, and this one.
  • fanjavaid
    fanjavaid almost 7 years
    It should be as accepted answer. "The key is to set the both the FLAG_GRANT_READ_URI_PERMISSION and FLAG_ACTIVITY_CLEAR_TOP at the same time." Thank you!
  • priyanka kamthe
    priyanka kamthe almost 7 years
    Its works on 7.1 but not in 7.0. when I'm trying to run in 7.0 its showing same error.
  • karthik prasad
    karthik prasad about 6 years
    does it need to be external path? can it be internal to app? e.g - <files-path name="pdf_path" path="pdf/"/>
  • Simão Garcia
    Simão Garcia over 5 years
    Works perfectly. Cheers.
  • Moshe Stauber
    Moshe Stauber over 4 years
    The trick for me was adding Intent.FLAG_GRANT_READ_URI_PERMISSION. Thanks!
  • Hareesh
    Hareesh about 4 years
    Perfect answer. Thanks for saving my day with this helpful content The key is to set the both the FLAG_GRANT_READ_URI_PERMISSION and FLAG_ACTIVITY_CLEAR_TOP at the same time
  • diaryfolio
    diaryfolio over 2 years
    have the exact same problem as a Normal user. Any suggestion how to do it without the need of code ? (like via settings or any place directly to update settings?)