How to render a PDF file in Android

Solution 1:

Since API Level 21 (Lollipop) Android provides a PdfRenderer class:

// create a new renderer
 PdfRenderer renderer = new PdfRenderer(getSeekableFileDescriptor());

 // let us just render all pages
 final int pageCount = renderer.getPageCount();
 for (int i = 0; i < pageCount; i++) {
     Page page = renderer.openPage(i);

     // say we render for showing on the screen
     page.render(mBitmap, null, null, Page.RENDER_MODE_FOR_DISPLAY);

     // do stuff with the bitmap

     // close the page
     page.close();
 }

 // close the renderer
 renderer.close();

For more information see the sample app.

For older APIs I recommend Android PdfViewer library, it is very fast and easy to use, licensed under Apache License 2.0:

pdfView.fromAsset(String)
  .pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
  .enableSwipe(true)
  .swipeHorizontal(false)
  .enableDoubletap(true)
  .defaultPage(0)
  .onDraw(onDrawListener)
  .onLoad(onLoadCompleteListener)
  .onPageChange(onPageChangeListener)
  .onPageScroll(onPageScrollListener)
  .onError(onErrorListener)
  .enableAnnotationRendering(false)
  .password(null)
  .scrollHandle(null)
  .load();

Solution 2:

public class MyPdfViewActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView mWebView=new WebView(MyPdfViewActivity.this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setPluginsEnabled(true);
    mWebView.loadUrl("https://docs.google.com/gview?embedded=true&url="+LinkTo);
    setContentView(mWebView);
  }
}

Solution 3:

I have made a hybrid approach from some of the answers given to this and other similar posts:

This solution checks if a PDF reader app is installed and does the following: - If a reader is installed, download the PDF file to the device and start a PDF reader app - If no reader is installed, ask the user if he wants to view the PDF file online through Google Drive

NOTE! This solution uses the Android DownloadManager class, which was introduced in API9 (Android 2.3 or Gingerbread). This means that it doesn't work on Android 2.2 or earlier.

I wrote a blog post about it here, but I've provided the full code below for completeness:

public class PDFTools {
    private static final String GOOGLE_DRIVE_PDF_READER_PREFIX = "http://drive.google.com/viewer?url=";
    private static final String PDF_MIME_TYPE = "application/pdf";
    private static final String HTML_MIME_TYPE = "text/html";

    /**
     * If a PDF reader is installed, download the PDF file and open it in a reader. 
     * Otherwise ask the user if he/she wants to view it in the Google Drive online PDF reader.<br />
     * <br />
     * <b>BEWARE:</b> This method
     * @param context
     * @param pdfUrl
     * @return
     */
    public static void showPDFUrl( final Context context, final String pdfUrl ) {
        if ( isPDFSupported( context ) ) {
            downloadAndOpenPDF(context, pdfUrl);
        } else {
            askToOpenPDFThroughGoogleDrive( context, pdfUrl );
        }
    }

    /**
     * Downloads a PDF with the Android DownloadManager and opens it with an installed PDF reader app.
     * @param context
     * @param pdfUrl
     */
    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    public static void downloadAndOpenPDF(final Context context, final String pdfUrl) {
        // Get filename
        final String filename = pdfUrl.substring( pdfUrl.lastIndexOf( "/" ) + 1 );
        // The place where the downloaded PDF file will be put
        final File tempFile = new File( context.getExternalFilesDir( Environment.DIRECTORY_DOWNLOADS ), filename );
        if ( tempFile.exists() ) {
            // If we have downloaded the file before, just go ahead and show it.
            openPDF( context, Uri.fromFile( tempFile ) );
            return;
        }

        // Show progress dialog while downloading
        final ProgressDialog progress = ProgressDialog.show( context, context.getString( R.string.pdf_show_local_progress_title ), context.getString( R.string.pdf_show_local_progress_content ), true );

        // Create the download request
        DownloadManager.Request r = new DownloadManager.Request( Uri.parse( pdfUrl ) );
        r.setDestinationInExternalFilesDir( context, Environment.DIRECTORY_DOWNLOADS, filename );
        final DownloadManager dm = (DownloadManager) context.getSystemService( Context.DOWNLOAD_SERVICE );
        BroadcastReceiver onComplete = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if ( !progress.isShowing() ) {
                    return;
                }
                context.unregisterReceiver( this );

                progress.dismiss();
                long downloadId = intent.getLongExtra( DownloadManager.EXTRA_DOWNLOAD_ID, -1 );
                Cursor c = dm.query( new DownloadManager.Query().setFilterById( downloadId ) );

                if ( c.moveToFirst() ) {
                    int status = c.getInt( c.getColumnIndex( DownloadManager.COLUMN_STATUS ) );
                    if ( status == DownloadManager.STATUS_SUCCESSFUL ) {
                        openPDF( context, Uri.fromFile( tempFile ) );
                    }
                }
                c.close();
            }
        };
        context.registerReceiver( onComplete, new IntentFilter( DownloadManager.ACTION_DOWNLOAD_COMPLETE ) );

        // Enqueue the request
        dm.enqueue( r );
    }

    /**
     * Show a dialog asking the user if he wants to open the PDF through Google Drive
     * @param context
     * @param pdfUrl
     */
    public static void askToOpenPDFThroughGoogleDrive( final Context context, final String pdfUrl ) {
        new AlertDialog.Builder( context )
            .setTitle( R.string.pdf_show_online_dialog_title )
            .setMessage( R.string.pdf_show_online_dialog_question )
            .setNegativeButton( R.string.pdf_show_online_dialog_button_no, null )
            .setPositiveButton( R.string.pdf_show_online_dialog_button_yes, new OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    openPDFThroughGoogleDrive(context, pdfUrl); 
                }
            })
            .show();
    }

    /**
     * Launches a browser to view the PDF through Google Drive
     * @param context
     * @param pdfUrl
     */
    public static void openPDFThroughGoogleDrive(final Context context, final String pdfUrl) {
        Intent i = new Intent( Intent.ACTION_VIEW );
        i.setDataAndType(Uri.parse(GOOGLE_DRIVE_PDF_READER_PREFIX + pdfUrl ), HTML_MIME_TYPE );
        context.startActivity( i );
    }
    /**
     * Open a local PDF file with an installed reader
     * @param context
     * @param localUri
     */
    public static final void openPDF(Context context, Uri localUri ) {
        Intent i = new Intent( Intent.ACTION_VIEW );
        i.setDataAndType( localUri, PDF_MIME_TYPE );
        context.startActivity( i );
    }
    /**
     * Checks if any apps are installed that supports reading of PDF files.
     * @param context
     * @return
     */
    public static boolean isPDFSupported( Context context ) {
        Intent i = new Intent( Intent.ACTION_VIEW );
        final File tempFile = new File( context.getExternalFilesDir( Environment.DIRECTORY_DOWNLOADS ), "test.pdf" );
        i.setDataAndType( Uri.fromFile( tempFile ), PDF_MIME_TYPE );
        return context.getPackageManager().queryIntentActivities( i, PackageManager.MATCH_DEFAULT_ONLY ).size() > 0;
    }

}

Solution 4:

you can use a simple method by import

implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'

and the XML code is

<com.github.barteksc.pdfviewer.PDFView
        android:id="@+id/pdfv"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </com.github.barteksc.pdfviewer.PDFView>

and just declare and add a file to an asset folder and just assign the name

   PDFView  pdfView=findViewById(R.id.pdfv);       
    pdfView.fromAsset("agl.pdf").load();