Rendern Sie eine PDF-Datei mit Java unter Android

Mir wurde klar, dass Android keine integrierte Methode zum Anzeigen von PDF-Dateien bietet.

Wie kann ich eine PDF-Datei mit Java auf Android rendern?

Solutions Collecting From Web of "Rendern Sie eine PDF-Datei mit Java unter Android"

Seit API Level 21 (Lollipop) bietet Android eine 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(); 

Weitere Informationen finden Sie in der Beispielanwendung .

Für ältere APIs empfehle ich die Android PdfViewer-Bibliothek , sie ist sehr schnell und einfach zu benutzen, lizenziert unter 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(); 

Aus meinem Blog:

 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); } } 

Ich habe einen hybriden Ansatz aus einigen der Antworten auf diese und andere ähnliche Beiträge gemacht:

Diese Lösung prüft, ob eine PDF-Reader-App installiert ist und führt Folgendes aus: – Wenn ein Reader installiert ist, laden Sie die PDF-Datei auf das Gerät und starten Sie eine PDF-Reader-App – Wenn kein Reader installiert ist, fragen Sie den Benutzer, ob er ihn anzeigen möchte die PDF-Datei online über Google Drive

HINWEIS! Diese Lösung verwendet die Android DownloadManager class, die in API9 (Android 2.3 oder Gingerbread) eingeführt wurde. Dies bedeutet, dass es unter Android 2.2 oder früher nicht funktioniert.

Ich habe hier einen Blogpost darüber geschrieben, aber ich habe den folgenden vollständigen Code zur Vollständigkeit angegeben:

 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.
*
* BEWARE: 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; } }

Ich war schließlich in der Lage, den Code von butelo zu ändern, um eine beliebige PDF-Datei im Android-Dateisystem mit pdf.js . Der Code kann auf meinem GitHub gefunden werden

Was ich getan habe, war die pdffile.js geändert, um HTML-Argument- file wie pdffile.js zu lesen:

 var url = getURLParameter('file'); function getURLParameter(name) { return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null} 

Also, was Sie tun müssen, ist nur den Dateipfad nach der index.html wie folgt anhängen:

 Uri path = Uri.parse(Environment.getExternalStorageDirectory().toString() + "/data/test.pdf"); webView.loadUrl("file:///android_asset/pdfviewer/index.html?file=" + path); 

Aktualisieren Sie die Pfadvariable so, dass sie auf eine gültige PDF im Adroid-Dateisystem verweist.

Laden Sie den Quellcode hier herunter ( PDF-Datei in meiner Android-Anwendung anzeigen )

Fügen Sie diese Abhängigkeit in Ihrer Bewertung hinzu: compile ‘com.github.barteksc: android-pdf-viewer: 2.0.3’

activity_main.xml

     

Hauptaktivität.java

 import android.app.Activity; import android.database.Cursor; import android.net.Uri; import android.provider.OpenableColumns; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import com.github.barteksc.pdfviewer.PDFView; import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener; import com.github.barteksc.pdfviewer.listener.OnPageChangeListener; import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle; import com.shockwave.pdfium.PdfDocument; import java.util.List; public class MainActivity extends Activity implements OnPageChangeListener,OnLoadCompleteListener{ private static final String TAG = MainActivity.class.getSimpleName(); public static final String SAMPLE_FILE = "android_tutorial.pdf"; PDFView pdfView; Integer pageNumber = 0; String pdfFileName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pdfView= (PDFView)findViewById(R.id.pdfView); displayFromAsset(SAMPLE_FILE); } private void displayFromAsset(String assetFileName) { pdfFileName = assetFileName; pdfView.fromAsset(SAMPLE_FILE) .defaultPage(pageNumber) .enableSwipe(true) .swipeHorizontal(false) .onPageChange(this) .enableAnnotationRendering(true) .onLoad(this) .scrollHandle(new DefaultScrollHandle(this)) .load(); } @Override public void onPageChanged(int page, int pageCount) { pageNumber = page; setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount)); } @Override public void loadComplete(int nbPages) { PdfDocument.Meta meta = pdfView.getDocumentMeta(); printBookmarksTree(pdfView.getTableOfContents(), "-"); } public void printBookmarksTree(List tree, String sep) { for (PdfDocument.Bookmark b : tree) { Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx())); if (b.hasChildren()) { printBookmarksTree(b.getChildren(), sep + "-"); } } } } 

Um ein wenig Licht hinzuzufügen, müsste ich mit der pdf.js-Lösung von Mozilla gehen. Hier ist der Link zu einer bereits gut geschriebenen Implementierung: https://bitbucket.org/butelo/pdfviewer/ .

Hier sind die Änderungen, die ich in meiner Android-Aktivität hinzugefügt habe:

 private String getInternalPDFURL(String interalPDFName){ return "file:///android_asset/pdfviewer/index.html?pdf=" + interalPDFName + ".pdf"; } 

Hier sind die Änderungen, die ich in pdffile.js vorgenommen pdffile.js :

 var url = '../' + getPDFURL(); function getPDFURL(){ var query = window.location.search.substring(1); var vars = query.split("="); var pdfPage = vars[1]; return pdfPage; } 

Ich habe den folgenden Code verwendet, um die PDF-Datei mithilfe von Wi-Fi zu öffnen und zu drucken. Ich sende meinen ganzen Code, und ich hoffe, es ist hilfreich.

 public class MainActivity extends Activity { int Result_code = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button mButton = (Button)findViewById(R.id.button1); mButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub PrintManager printManager = (PrintManager)getSystemService(Context.PRINT_SERVICE); String jobName = " Document"; printManager.print(jobName, pda, null); } }); } public void openDocument(String name) { Intent intent = new Intent(android.content.Intent.ACTION_VIEW); File file = new File(name); String extension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(Uri.fromFile(file).toString()); String mimetype = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); if (extension.equalsIgnoreCase("") || mimetype == null) { // if there is no extension or there is no definite mimetype, still try to open the file intent.setDataAndType(Uri.fromFile(file), "text/*"); } else { intent.setDataAndType(Uri.fromFile(file), mimetype); } // custom message for the intent startActivityForResult((Intent.createChooser(intent, "Choose an Application:")), Result_code); //startActivityForResult(intent, Result_code); //Toast.makeText(getApplicationContext(),"There are no email clients installed.", Toast.LENGTH_SHORT).show(); } @SuppressLint("NewApi") PrintDocumentAdapter pda = new PrintDocumentAdapter(){ @Override public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback){ InputStream input = null; OutputStream output = null; try { String filename = Environment.getExternalStorageDirectory() + "/" + "Holiday.pdf"; File file = new File(filename); input = new FileInputStream(file); output = new FileOutputStream(destination.getFileDescriptor()); byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = input.read(buf)) > 0) { output.write(buf, 0, bytesRead); } callback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES}); } catch (FileNotFoundException ee){ //Catch exception } catch (Exception e) { //Catch exception } finally { try { input.close(); output.close(); } catch (IOException e) { e.printStackTrace(); } } } @Override public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras){ if (cancellationSignal.isCanceled()) { callback.onLayoutCancelled(); return; } // int pages = computePageCount(newAttributes); PrintDocumentInfo pdi = new PrintDocumentInfo.Builder("Name of file").setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT).build(); callback.onLayoutFinished(pdi, true); } }; } 

Es gibt sowieso keine Vorschau PDF-Dokument in Android Webview.Wenn Sie eine Vorschau von base64 pdf. Es erfordert eine Bibliothek von Drittanbietern.

build.Gradle

 compile 'com.github.barteksc:android-pdf-viewer:2.7.0' 

dialog_pdf_viewer

 < ?xml version="1.0" encoding="utf-8"?>          

DailogPDFViewer.java

 public class DialogPdfViewer extends Dialog { PDFView pdfView; byte[] decodedString; public interface OnDialogPdfViewerListener { void onAgreeClick(DialogPdfViewer dialogFullEula); void onCloseClick(DialogPdfViewer dialogFullEula); } public DialogPdfViewer(Context context, String base64, final DialogPdfViewer.OnDialogPdfViewerListener onDialogPdfViewerListener) { super(context); setContentView(R.layout.dialog_pdf_viewer); findViewById(R.id.dialog_pdf_viewer_close).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onDialogPdfViewerListener.onCloseClick(DialogPdfViewer.this); } }); findViewById(R.id.dialog_pdf_viewer_button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onDialogPdfViewerListener.onAgreeClick(DialogPdfViewer.this); } }); decodedString = Base64.decode(base64.toString(), Base64.DEFAULT); pdfView = ((PDFView) findViewById(R.id.pdfView)); pdfView.fromBytes(decodedString).load(); setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { onDialogPdfViewerListener.onCloseClick(DialogPdfViewer.this); } return true; } }); } }