Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileProvider - Open File from Download Directory

I can't open any file from Download Folder.

I can download a file and save in Download Folder with this:

   DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
    request.setDescription(descricao);
    request.setTitle(titulo);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        request.allowScanningByMediaScanner();
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    }
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, nome);

    enq = downloadManager.enqueue(request);

After this, my file is correct saved at Directory Folder: Android >> Internal Shared Storage >> Download. ***This path I see manually opening the device's hd in ubuntu. As the image shows the path. Android HD by ubuntu folder - see the path

And I try open this file with this:

downloadManager = (DownloadManager)getContext().getSystemService(DOWNLOAD_SERVICE);
        BroadcastReceiver receiver = new BroadcastReceiver() {

            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if(DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                    long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                    DownloadManager.Query query = new DownloadManager.Query();
                    query.setFilterById(enq);
                    Cursor c = downloadManager.query(query);
                    if(c.moveToFirst()) {
                        int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS);
                        if(DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) {
                            String uriString = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));

                            if (uriString.substring(0, 7).matches("file://")) {
                                uriString =  uriString.substring(7);
                            }

                            File file = new File(uriString);

                            Uri uriFile = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".fileprovider", file);
                            String mimetype = "application/pdf";
                            Intent myIntent = new Intent(Intent.ACTION_VIEW);
                            myIntent.setDataAndType(uriFile, mimetype);

                            Intent intentChooser = Intent.createChooser(myIntent, "Choose Pdf Application");
                            startActivity(intentChooser);
                        }
                    }
                }
            }
        };

        getContext().registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

I declare my file provider in manifest with this:

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

and with this:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="Download" path="Download/"/>
</paths>

But when I click the button to download I receive this message: "This file coud be not accessed. Check the location or the network and try again."

Resuming:

1 - The file is downloaded and saved at the directory folder.

2 - The intent is started, but the file is not openned.

3 - Debug mode give me this at "new File(urlString)": "urlString=/storage/emulated/0/Download/name.pdf"

4 - At "FileProvider.getUriFromFile..." debug mode have this:

"uriFile = content://com.example.android.parlamentaresapp.fileprovider/Download/name.pdf"

Thank you.

like image 275
Sarara Avatar asked Mar 29 '17 20:03

Sarara


People also ask

Why we use file Provider?

FileProvider is a special subclass of ContentProvider that facilitates secure sharing of files associated with an app by creating a content:// Uri for a file instead of a file:/// Uri . A content URI allows you to grant read and write access using temporary access permissions.

How do I get real path from FileProvider URI?

You can try this solution for get real path from file provider URI. First you need to define file provider path file as following. Declare file provider in AndroidMenifest. xml as following.

How do I use FileProvider?

To make FileProvider work follow these three steps: Define the FileProvider in your AndroidManifest file. Create an XML file that contains all paths that the FileProvider will share with other applications. Bundle a valid URI in the Intent and activate it.


1 Answers

Call addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) on the Intent that you use with startActivity() and the FileProvider Uri. Without that, the activity has no rights to access your content.

like image 75
CommonsWare Avatar answered Oct 08 '22 23:10

CommonsWare