31

This was my original question:

I want to be able to open a pdf file in my app using the android's built in pdf viewer app, but i dont know how to start other apps. I'm sure i have to call start activity, i just dont know how to identify the app im opening and how to pass the file to that specific app.

Anyone have a clue?

I just learned that the pdf viewer i have on my phone is actually made by HTC and that Adobe just barely released their android pdf viewer (which is great). So the new question is this: how do i verify that the user has installed adobe's viewer, and then how do i open the file in that app from my app?

mtmurdock
  • 12,756
  • 21
  • 65
  • 108
  • 4
    AFAIK there is no built-in PDF viewer in Android. Adobe launched its official Reader port for Android just a couple of days ago: http://techie-buzz.com/mobile-news/adobe-reader-for-android-now-available.html , but you still need to get it from the Market. – Mauricio Scheffer May 26 '10 at 20:01
  • 1
    oh, as it would turn out, my phone came with an HTC made pdf viewer... fancy that. ok then, assuming that the user has this adobe pdf viewer already installed on their device, how would i use it? – mtmurdock May 26 '10 at 20:31
  • I don't have an answer but I was wondering if you got this sorted, and if so, how did you do it? This is very relevant to what I need to do. – NotACleverMan Nov 17 '10 at 16:14
  • Karakuri's answer is great for opening a pdf with any viewer, not just Adobe's – mtmurdock May 21 '12 at 20:44
  • possible duplicate of [PDF Library for Android - PDFBox?](http://stackoverflow.com/questions/5952626/pdf-library-for-android-pdfbox) – Bo Persson Jun 10 '12 at 17:08
  • 1
    How can this be a duplicate? This question is a year older than that one, and This question isn't about a pdf library, its about opening pdf files in other apps. – mtmurdock Jun 11 '12 at 14:37

8 Answers8

42

You can programmatically determine whether a suitable application exists on the user's device, without catching exceptions.

Intent intent = new Intent(Intent.ACTION_VIEW,
        Uri.parse("path-to-document"));
intent.setType("application/pdf");
PackageManager pm = getPackageManager();
List<ResolveInfo> activities = pm.queryIntentActivities(intent, 0);
if (activities.size() > 0) {
    startActivity(intent);
} else {
    // Do something else here. Maybe pop up a Dialog or Toast
}
Karakuri
  • 38,365
  • 12
  • 84
  • 104
16

AFAIK, Adobe has not documented any public Intents it wants developers to use.

You can try an ACTION_VIEW Intent with a Uri pointing to the file (either on the SD card or MODE_WORLD_READABLE in your app-local file store) and a MIME type of "application/pdf".

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 2
    Ok that sounds cool... how would i implement that? This is very new to me. – mtmurdock May 27 '10 at 16:08
  • 3
    Tried this one because I don't want the files to be stored on the sd-card. Unfortunately Adobe Reader won't open files from the app dir (created with MODE_WORLD_READABLE). Anyone solved this so far? – alexleutgoeb Feb 07 '11 at 17:11
  • it always says file does not exist or cannot be read. i have tried with 8 different PDF files that are readable in my device and PC. – dinesh sharma May 17 '12 at 13:21
  • 1
    What if i have web url (http:xyx.com/a.pdf) ? – Max Feb 03 '15 at 07:30
  • It's better to use a FileProvider as MODE_WORLD_READABLE was deprecated in API level 17 – jeprubio Dec 12 '16 at 16:53
  • Can someone tell me how can I put a button at the bottom when a PDF is being displayed? I want to put some extra functionality to the button related to that PDF. – sankalpvk18 Oct 22 '19 at 07:55
3
            FileFinalpath = SdCardpath + "/" + Filepath + Filename;
            File file = new File(FileFinalpath);
            if (file.exists()) {
                Uri filepath = Uri.fromFile(file);
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(filepath, "application/pdf");
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

                try {
                    startActivity(intent);
                } catch (Exception e) {
                    alert.showAlertDialog(PDF_Activity.this, "File Not Started...","File Not Started From SdCard ", false);             
                    Log.e("error", "" + e);
                }

            } else {
                alert.showAlertDialog(PDF_Activity.this, "File Not Found...","File Not Found From SdCard ", false);             

            }
2

Although this is a pretty old topic, here is a solution for opening a PDF that is in the asset/ folder with an external PDF reader app. It uses a custom content provider: https://github.com/commonsguy/cwac-provider

Using this you can define any file to be provided from the assets/ or res/raw/ folder.

Try it! Best and easiest solution I found so far.

david.schreiber
  • 3,851
  • 2
  • 28
  • 46
2

I was also faced same issue when was trying to display PDF on android device and finally end up with the solution (3rd party PDF library integration)

https://github.com/JoanZapata/android-pdfview

while I have tested multiple libraries for this listed below which are also working,

https://github.com/jblough/Android-Pdf-Viewer-Library

& mupdf which comes with the ndk flavour (https://code.google.com/p/mupdf/downloads/detail?name=mupdf-1.2-source.zip&can=2&q=) and need to extract with NDK and then use it in application as a jar or java etc. nice article to explain the use of this library @ http://dixitpatel.com/integrating-pdf-in-android-application/

paxbat14
  • 101
  • 7
2

Android has a built in framework from Android 5.0 / Lollipop, it's called PDFRenderer. If you can make the assumption that your users have Android 5.0, it's probably the best solution.

There's an official example on Google's developer site:

http://developer.android.com/samples/PdfRendererBasic/index.html

It doesn't support annotation or other more advanced features; for those your really back to either using an Intent to open a full app, or embedding an SDK like mupdf.

(Disclaimer: I very occasionally do work on mupdf.)

JosephH
  • 37,173
  • 19
  • 130
  • 154
  • 2
    Oh wow! I'm so excited about this! I still have to support earlier versions, and I have long since moved on from the project that prompted my original question. However, I am super happy to know about this. – mtmurdock Apr 12 '16 at 17:19
0

In addition to the ones marked as answer you would need these permissions in the manifest.xml

**

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

**

Sundara Prabu
  • 2,361
  • 1
  • 21
  • 20
0

Add FLAG_GRANT_READ_URI_PERMISSION

Intent intent = new Intent(Intent.ACTION_VIEW)
Uri outputFileUri = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", file); 
intent.setDataAndType(outputFileUri, "application/pdf"); 
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
Intent in = Intent.createChooser(intent, "Open File");
startActivity(in);

also add provider_paths.xml at res -> xml folder and need to add below code at manifests

<application>
   <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:replace="android:authorities">
            <meta-data
                tools:replace="android:resource"
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>
 </application>
Rezaul Karim
  • 1,311
  • 1
  • 18
  • 26
  • addFlag & setFlag what are the differences @Rezaul ? – gumuruh Mar 13 '22 at 20:34
  • @gumuruh you can check differences between addFlag and setFlag using this link https://stackoverflow.com/questions/6664189/androidwhat-is-difference-between-setflags-and-addflags-for-intent – Rezaul Karim Mar 15 '22 at 04:42