7

I am writing an Android application to display pdf files on the device. And I need to use the current versioncode (35498) of the Adobe Reader to display the pdf files.I have with code to display list of files on the screen. Now I need to invoke the Adobe reader (not any other pdf reader installed on the device) onclick of each document. I am not sure how I code that. I am an Android newbie. Any help will be greatly appreciated.

Thanks in Advance, Navin

Shog9
  • 156,901
  • 35
  • 231
  • 235
NavinC
  • 243
  • 1
  • 7
  • 14
  • 3
    Any reason why you need the Adobe reader? The whole point of Android's intent system is to use the app for PDFs that the user chose (and has available). – EboMike Feb 25 '11 at 04:08
  • @EboMike - hats because Adobe reader is by far best among the Android pdf viewers that I have seen in terms of look and feel. And another important reason being in its current version it doesn't allow any copy/paste/print features and we dont want the user to copy the contents of the document. Is there any other way we can keep the documents secure? As I said I am a newbie in Android and I may be wrong in what I say. – NavinC Feb 25 '11 at 12:28
  • 1
    Doesn't matter. It's up to the users to decide what they think the "best" reader is for their needs. Besides, your approach would fail if the user doesn't have that particular reader installed. – EboMike Feb 25 '11 at 17:33
  • If you want to guarantee this sort of security, you should write your own PDF decoder. Limiting it to only Adobe Reader and even more to a specific version isn't how Android was built, so you're going to have to hack around to get it to work. – jakebasile Mar 08 '11 at 23:10

4 Answers4

9

I see that you want to open Adobe specifically, but you may want to consider doing it the more Android-like way of opening a general intent and allowing the user to choose how it opens. For your reference, you'd do that with the following code:

private void openFile(File f, String mimeType)
{
    Intent viewIntent = new Intent();
    viewIntent.setAction(Intent.ACTION_VIEW);
    viewIntent.setDataAndType(Uri.fromFile(file), mimeType);
    // using the packagemanager to query is faster than trying startActivity
    // and catching the activity not found exception, which causes a stack unwind.
    List<ResolveInfo> resolved = getPackageManager().queryIntentActivities(viewIntent, 0);
    if(resolved != null && resolved.size() > 0)
    {
        startActivity(viewIntent);
    }
    else
    {
        // notify the user they can't open it.
    }
}

If you really need to use both Abode Reader specifically, and a specific version, you would need to query for it using PackageManager.getPackageInfo(String, int)

Andrew Whitaker
  • 124,656
  • 32
  • 289
  • 307
jakebasile
  • 8,084
  • 3
  • 28
  • 34
8

Try the following code

private void loadDocInReader(String doc)
     throws ActivityNotFoundException, Exception {

    try {
                Intent intent = new Intent();

                intent.setPackage("com.adobe.reader");
                intent.setDataAndType(Uri.parse(doc), "application/pdf");

                startActivity(intent);

    } catch (ActivityNotFoundException activityNotFoundException) {
                activityNotFoundException.printStackTrace();

                throw activityNotFoundException;
    } catch (Exception otherException) {
                otherException.printStackTrace();

                throw otherException;
    }
}
Mudassir
  • 13,031
  • 8
  • 59
  • 87
  • 1
    Obviously, in real life you'll want to replace the catch() block with a Dialog saying "you don't have the reader installed". Other than that, nice. +1. – EboMike Feb 25 '11 at 04:18
6

If you are in "online mode", here is an interesting alternate solution using Google docs.

String myPDFURL = "http://{link of your pdf file}";

String link;
try {
    link = "http://docs.google.com/viewer?url="
    + URLEncoder.encode(myPDFURL, "UTF-8")
    + "&embedded=true";
} catch (Exception e) {
    e.printStackTrace();
}

Uri uri = Uri.parse(link);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
Gabriel Klein
  • 367
  • 2
  • 6
2

This works, setDataAndType method cannot seem to correctly recognize the PDF type if used via URL.

private static Intent newPDFLinkIntent(String url) {
    Uri pdfURL = Uri.parse(url);
    Intent pdfDownloadIntent = new Intent(Intent.ACTION_VIEW, pdfURL);
    pdfDownloadIntent.setType("application/pdf");
    pdfDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    return pdfDownloadIntent ;
}

Unfortunately, the PDF applications I'm using don't anticipate downloading and caching the online content (some will have memory leak error, some will reject link downloading), so you'll eventually end up invoking an intent that downloads the PDF first, before opening the downloaded content via the notification link. I eventually used the solution below:

private static Intent newPDFLinkIntent(String url) {
    Intent pdfDownloadIntent = null;
    try {
        pdfDownloadIntent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
        pdfDownloadIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
    } catch (URISyntaxException e) {
        Log.e("PDF Link Tag", e.getMessage());
    }
    return pdfDownloadIntent;
}
Pier Betos
  • 1,038
  • 9
  • 17