Dave Poulsom
Dave Poulsom

Reputation: 13

How to open Pdf viewer via Intent in Android

VB.NET / SQL Developer new to Android development but concepts are getting through.

I've managed to implement DownloadManager to download a PDF from a URI to DIRECTORY_DOWNLOADS folder but when I attempt to open with Intent I'm only prompted with Dropbox and Word not the normal applications .. code:

Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(Uri.parse(DIRECTORY_DOWNLOADS + File.separator + "WinLib" + File.separator + "WinLib.pdf"), "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);


try{
    startActivity(pdfIntent);
}catch(ActivityNotFoundException e) {
    Toast.makeText(MainActivity.this, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}

When I click on the file from the Downloads folder I'm presented with options for Drive PDF Viewer and OneDrive PDF Viewer.

As I said, I'm a noob to Android/Java so please don't be harsh but any help would be appreciated since Google has run dry on this one!

Thanks in advance

Dave

SOLUTION

User "Shine" pointed me in the direction of "Martin Himmel" post.

I had to combine the intent.setData and intent.setType because when I used setType it reset the data to null so the file couldn't found.

Once that was done I was getting the error:

android.os.FileUriExposedException: file:///storage/emulated/0/Download/WinLib/WinLib.pdf exposed beyond app through ClipData.Item.getUri()

The solution was found in "eranda.del"s post.

So my final code looks like this:

public String get_mime_type(String url) {
    String ext = MimeTypeMap.getFileExtensionFromUrl(url);
    String mime = null;
    if (ext != null) {
        mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext);
    }
    return mime;
}

public void open_file(String filename) {
    File file = new File(Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_DOWNLOADS), filename);

    Uri uri = Uri.fromFile(file);
    String mime = get_mime_type(uri.toString());

    StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
    StrictMode.setVmPolicy(builder.build());

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, mime);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    this.startActivity(Intent.createChooser(intent, "Open file with"));
}

Thanks to Shine and the other contributors who helped me with this task, it's much appreciated!

Dave

Upvotes: 1

Views: 1221

Answers (1)

Shine
Shine

Reputation: 3818

Are you sure about that Uri.parse(DIRECTORY_DOWNLOADS + File.separator + "WinLib" + File.separator + "WinLib.pdf") parameter? I would give a try to FileProvider.getUriForFile() with an approach similar to the one described here. In this way, you would easily be able to both check pdf's Uri and mime type passed to the intent via:

String mime = getContentResolver().getType(uri);

I also imagine .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) call to be required in your case, in order to grant read permission to the external viewing Intent.

Upvotes: 1

Related Questions