Android generates pdf files
1. Use the official method
Using the official way is the use of the PdfDocument class
1.1 Basic use
/*** * Write tv content to pdf file */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void newPdf() { // Create a PDF text object PdfDocument document = new PdfDocument(); // Create The information of the current page, the parameters in the Builder represent the width and height of the page, and the number of pages PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(binding.pdfTv.getWidth(), binding.pdfTv.getHeight(), 1) .create(); // Generate the current page PdfDocument.Page page = document.startPage(pageInfo); // Draw on the current page, that is, draw the required view on the canvas of the page View content = pdfTv ; content.draw(page.getCanvas()) ; // End the current page document.finishPage(page); String filePath = getExternalFilesDir("").getAbsolutePath() + "/test.pdf"; try { FileOutputStream outputStream = new FileOutputStream(new File(filePath)); //write Into the file document.writeTo(outputStream); } catch (IOException e) { e.printStackTrace(); } //Close document.close(); }
Precautions
1. Need to apply for permission to write files
2. The minimum API is 19, and there are restrictions on the api version
1.2 Generate a pdf file from the content of the root layout
/*** * Save the content of a screen (including text, pictures, buttons, etc. in the interface) */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void pdfTvAndIv() { // Create a PDF text object PdfDocument document = new PdfDocument(); //Create the information of the current page, the parameters in the Builder indicate the width and height of the page, and the page PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(binding.getRoot().getWidth() , binding.getRoot().getHeight(), 1) .create(); // Generate the current page PdfDocument.Page page = document.startPage(pageInfo); // Draw on the current page, that is, put the required The view of the view is drawn on the canvas of the page View content = binding.getRoot(); content.draw(page.getCanvas()) ; // 结束当前页 document.finishPage(page); String filePath = getExternalFilesDir("").getAbsolutePath() + "/tviv.pdf"; try { FileOutputStream outputStream = new FileOutputStream(new File(filePath)); document.writeTo(outputStream); } catch (IOException e) { e.printStackTrace(); } document.close(); }
It's just as easy. binding.getRoot() is the root layout of the xml file
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> </data> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".pdf.PdfActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/pdf_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" /> <ImageView android:id="@+id/pdf_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="fitXY" android:src="@mipmap/logo" android:visibility="visible" /> <Button android:id="@+id/pdf1" android:layout_width="match_parent" android:layout_height="wrap_content" </LinearLayout> android:text="The official way to generate pdf" /> </ScrollView> </layout>
1.3 TextView has many lines, more than one screen
/*** * Write multiple lines of text to a pdf file */ @RequiresApi(api = Build.VERSION_CODES.KITKAT) private void pdfInterviewContent() { TextView tv_content = binding.pdfTv; // Create a PDF text object PdfDocument document = new PdfDocument(); // The height of one page of pdf int onePageHeight = tv_content.getLineHeight() * 30; // How many lines are there in the TextView int lineCount = tv_content.getLineCount(); // Calculate how many pages the TextView needs to be divided into int pdfCount = lineCount % 30 == 0 ? lineCount / 30 : lineCount / 30 + 1; for (int i = 0; i < pdfCount; i++) { PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(tv_content.getWidth( ), onePageHeight + 120, 1) .setContentRect(new Rect(0, 60, tv_content.getWidth(), onePageHeight + 60)) .create(); PdfDocument.Page page = document.startPage(pageInfo); Canvas canvas = page.getCanvas(); canvas.translate(0, -onePageHeight * i); tv_content.draw(canvas); document.finishPage(page); } //document = pdfImageviewContent(document); File file = new File(getExternalFilesDir("").getAbsolutePath() + "/test.pdf"); try { FileOutputStream outputStream = new FileOutputStream(file); document.writeTo(outputStream); } catch (IOException e) { e.printStackTrace(); } document.close(); }
1.4 Summary
1. The saved file is a bit large 2. It is difficult to save the content of more than one screen, which involves the movement of canvas 3. It is difficult to save text and pictures at the same time (if it exceeds one screen, the picture will be blank after saving. No more than One screen, it can be displayed normally after saving) 4. If there is a special view in the interface, the save may fail! For example, SurfaceView. [A link to the solution is attached](https://www.jianshu.com/p/1ebaf5e6fac1)
2. Ways to use itext
For Itext, there are mainly two versions, one is 5.x and the other is 7.x. These two versions are completely incompatible. For the difference, please refer to the official website: iText 7 and iText 5: roadmaps, differences, updates |iTextPDF ,
Documentation for 5.x: iText Javadoc Home
Documentation for 7.x: iText Javadoc Home
2.1 7.x
/** * 创建PDF文件 */ private void createPDF(String path) { if (XXPermissions.isGranted(TextActivity.this, Permission.MANAGE_EXTERNAL_STORAGE)) { File file = new File(path); if (file.exists()) { file.delete(); } file.getParentFile().mkdirs(); // 创建Document PdfWriter writer = null; try { writer = new PdfWriter(new FileOutputStream(path)); } catch (FileNotFoundException e) { Log.e("FileNotFoundException", e.toString()); } PdfDocument pdf_document = new PdfDocument(writer); // Generated PDF document information PdfDocumentInfo info = pdf_document.getDocumentInfo(); // Title info.setTitle("First pdf file"); // Author info.setAuthor("Quinto"); // Subject info.setSubject(" test"); // keywords info.setKeywords("pdf"); // creation date info.setCreator("2022-10-20"); Document document = new Document(pdf_document, PageSize.A4, false); // Text font (display Chinese), size, color PdfFont font = null; try { font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H"); } catch (IOException e) { Log.e("IOException", e.toString()); } float title_size = 36.0f; float text_title_size = 30.0f; float text_size = 24.0f; Color title_color = new DeviceRgb(0, 0 , 0); Color text_title_color = new DeviceRgb(65, 136, 160); Color text_color = new DeviceRgb(43, 43, 43); // Line separator // Solid line: SolidLine() Dotted line: DottedLine() Dashboard line: DashedLine() LineSeparator separator = new LineSeparator(new SolidLine()); separator.setStrokeColor(new DeviceRgb(0, 0, 68)); // Add a large title Text title = new Text("This is the title of the pdf file").setFont(font).setFontSize(title_size).setFontColor(title_color); Paragraph paragraph_title = new Paragraph(title).setTextAlignment(TextAlignment.CENTER); document.add( paragraph_title); for (int i = 1; i < 10; i++) { // Add text subtitle Text text_title = new Text("th" + i + "line:").setFont(font).setFontSize(text_title_size ).setFontColor(text_title_color); Paragraph paragraph_text_title = new Paragraph(text_title); document.add(paragraph_text_title); // Add text content String content = "I am text content" + i + i + i + i + i + i + i + i + i + i; Text text = new Text(content).setFont(font).setFontSize(text_size).setFontColor(text_color); Paragraph paragraph_text = new Paragraph(text); document.add(paragraph_text); // Add a newline space document.add (new Paragraph("")); // Add a horizontal line document.add(separator); // Add a breakable space document.add(new Paragraph("")); } / ** * Add a list */ List list = new List().setSymbolIndent(12).setListSymbol("\u2022").setFont(font); list.add(new ListItem("List1")) .add(new ListItem("List 2")) .add(new ListItem("列表3")); document.add(list); /** * 添加图片 */ Text text_image = new Text("图片:").setFont(font).setFontSize(text_title_size).setFontColor(text_title_color); Paragraph image = new Paragraph(text_image); document.add(image); Image image1 = null; Image image2 = null; Image image3 = null; try { /*image1 = new Image(ImageDataFactory.create("/storage/emulated/0/DCIM/Camera/IMG_20221003_181926.jpg")).setWidth(PageSize.A4.getWidth() * 2 / 3); image2 = new Image(ImageDataFactory.create("/storage/emulated/0/Download/互传/folder/证件/XHS_159716343059020494b83-da6a-39d7-ae3b-13fd92cfbb53.jpg")).setWidth(PageSize.A4.getWidth() / 3); image3 = new Image(ImageDataFactory.create("/storage/emulated/0/Download/互传/folder/证件/XHS_1597163520524f0b4df77-8db1-35c6-9dfa-3e0aa74f1fef.jpg")).setWidth(PageSize.A4.getWidth() / 3);*/ image1 = new Image(ImageDataFactory.create("/storage/emulated/0/Pictures/JPEG_20230609_154240_8941441911022988116.jpg")).setWidth(PageSize.A4.getWidth() * 2 / 3); image2 = new Image(ImageDataFactory.create("/storage/emulated/0/Tencent/QQ_Images/-318f738d395e5630.jpg")).setWidth(PageSize.A4.getWidth() / 3); image3 = new Image(ImageDataFactory.create("/storage/emulated/0/Pictures/Screenshots/Screenshot_20230615_145522_com.hermes.wl.jpg")).setWidth(PageSize.A4.getWidth() / 3); } catch (MalformedURLException e) { Log.e("MalformedURLException", e.toString()); } Paragraph paragraph_image = new Paragraph().add(image1) .add(" ") .add(image2) .add(" ") .add(image3); document.add(paragraph_image); document.add(new Paragraph("")); /** * 添加表格 */ Text text_table = new Text("Form:").setFont(font).setFontSize(text_title_size).setFontColor(text_title_color); Paragraph paragraph_table = new Paragraph(text_table); document.add(paragraph_table); // 3 columns float[] pointColumnWidths = {100f, 100f, 100f}; Table table = new Table(pointColumnWidths); // Set border style, color, width Color table_color = new DeviceRgb(80, 136, 255); Border border = new DottedBorder(table_color, 3 ); table.setBorder(border); // Set cell text to center table.setTextAlignment(TextAlignment.CENTER); // Add cell content Color table_header = new DeviceRgb(0, 0, 255); Color table_content = new DeviceRgb(255, 0, 0); Color table_footer = new DeviceRgb(0, 255, 0); Text text1 = new Text("姓名").setFont(font).setFontSize(20.0f).setFontColor(table_header); Text text2 = new Text("年龄").setFont(font).setFontSize(20.0f).setFontColor(table_header); Text text3 = new Text("性别").setFont(font).setFontSize(20.0f).setFontColor(table_header); table.addHeaderCell(new Paragraph(text1)); table.addHeaderCell(new Paragraph(text2)); table.addHeaderCell(new Paragraph(text3)); Text text4 = new Text("张三").setFont(font).setFontSize(15.0f).setFontColor(table_content); Text text5 = new Text("30").setFont(font).setFontSize(15.0f).setFontColor(table_content); Text text6 = new Text("男").setFont(font).setFontSize(15.0f).setFontColor(table_content); table.addCell(new Paragraph(text4)); table.addCell(new Paragraph(text5)); table.addCell(new Paragraph(text6)); Text text7 = new Text("丽萨").setFont(font).setFontSize(15.0f).setFontColor(table_footer); Text text8 = new Text("20").setFont(font).setFontSize(15.0f).setFontColor(table_footer); Text text9 = new Text("女").setFont(font).setFontSize(15.0f).setFontColor(table_footer); table.addFooterCell(new Paragraph(text7)); table.addFooterCell(new Paragraph(text8)); table.addFooterCell(new Paragraph(text9)); //Add the table to the pdf file document.add(table); / ** * Add header, footer, watermark */ Rectangle pageSize; PdfCanvas canvas; int n = pdf_document.getNumberOfPages(); Log.i("zxd", "createPDF: " + n); for (int i = 1; i <= n; i++) { PdfPage page = pdf_document.getPage(i); Log.i ("zxd", "createPDF page: " + page.getPageSize()); pageSize = page.getPageSize(); canvas = new PdfCanvas(page); // header canvas.beginText().setFontAndSize(font, 7) .moveText(pageSize.getWidth() / 2 - 18, pageSize.getHeight() - 10) .showText("I am the header") .endText(); // Footer canvas.setStrokeColor(text_color) .setLineWidth( .2f) .moveTo(pageSize.getWidth() / 2 - 30, 20) .lineTo(pageSize.getWidth() / 2 + 30, 20).stroke(); canvas.beginText().setFontAndSize(font, 7) .moveText(pageSize.getWidth() / 2 - 6, 10) .showText(String.valueOf(i)) .endText(); // watermark Paragraph p = new Paragraph("Quinto").setFontSize(60); canvas.saveState(); PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.2f); canvas.setExtGState(gs1); document.showTextAligned(p, pageSize .getWidth() / 2, pageSize.getHeight() / 2, pdf_document.getPageNumber(page), TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45); canvas.restoreState(); } // Close document.close(); Toast.makeText(this, "PDF file has been generated", Toast.LENGTH_SHORT).show(); } else { //No permission //requestPermission(); } }
Precautions
1.pdfdocument.getPageSize() is not set as an instance of the object iText7, and an error is reported when getting the page size, because the parameter of immediate refresh is set to true
You can tell 文档
not to refresh its contents by default by passing the third parameter ( ) false
in the constructorimmediateflush
Document document = new Document(pdf_document, PageSize.A4, false);
pdfdocument.getPageSize() not set to instance of object iText7
2. If the image resource is not found, an io error will be reported
2.2 Basic use of 7.x
2.2.1 Display Chinese
When itext7 uses the default font to display Chinese, because the default font does not support Chinese, the Chinese in the generated pdf will display blank. To solve this problem, you need to import the font yourself.
1. Download a Chinese font (.ttf file, SourceHanSansCN.ttf)
2. Load local font styles
InputStream inputStream = new FileInputStream(new File("SourceHanSansCN.ttf")); //The third parameter is embedded, whether it is a built-in font, here is provided by yourself, so pass false PdfFont font = PdfFontFactory.createFont(IOUtils.toByteArray( inputStream), PdfEncodings. IDENTITY_H, false);
3. Set the font
//The default is A4 paper size Document document = new Document(pdfDocument, new PageSize()); document.setFont(font);
2.2.2 Resolution
If there is a need for pdf printing, it involves the issue of resolution.
In itext, except for the inserted pictures, the others are vector graphics, so you don’t have to worry about the resolution. You only need to ensure the resolution of the inserted pictures. The default resolution of the pictures generated in itext is 72dpi. Here, some processing is required. , as follows:
int defaultDpi = 72; int targetDpi = 300; Image test = new Image(ImageDataFactory.create("test.jpg")); test.scale(defaultDpi/targetDpi, defaultDpi/targetDpi);
2.2.3 Layout
The Itext coordinate system is as shown in the figure below. When using an absolute layout, it is necessary to calculate the length of the element from the left side and the bottom side. When using a relative layout, the elements are arranged from top to bottom.
absolute layout
setFixedPosition(float left, float bottom, float width)
relative layout
When using a relative layout, setFixedPosition is not required, and only the length of the distance from top to bottom, left, and right can be set.
setMarginLeft(float value); setMarginRight(float value); setMarginBottom(float value); setMarginTop(float value); setMargin(float commonMargin);
2.2.4 Automatic pagination + generate page number
When using absolute layout, in most cases the page content is of fixed size and position, and paging also needs to be controlled by writing code yourself. But if the content of the pdf is not fixed, it is not so flexible to use the absolute layout at this time, and you need to calculate the height of the element and set the absolute position. At this time, it is more appropriate and simpler for us to choose to use the relative layout. The code is as follows: class PageEventHandler implements IEventHandler { private Document document; private PdfFont font; // Because of the need for unified and Chinese fonts, a pdffont parameter is added. If there is no such requirement, public PageEventHandler(Document document, PdfFont font may not be added ){ this.document = document; this.font = font; } @Override public void handleEvent(Event event) { PdfDocumentEvent pdfEvent = (PdfDocumentEvent) event; PdfPage page = pdfEvent.getPage(); PdfDocument pdfDoc = pdfEvent.getDocument(); // Get the current page number int pageNumber = pdfDoc.getPageNumber(page); PdfCanvas pdfCanvas = new PdfCanvas( page.newContentStreamBefore(), page.getResources(), pdfDoc); // In Write the page number at a distance of 50 from the previous element this.document.setTopMargin(50f); pdfCanvas.beginText () .setFontAndSize(this.font, 32) //Write the current page at a place where the page is generally wide, due to font positioning The origin is also in the lower left corner, so here the x-axis subtracts half of the width of the page number, making sure that the page number is written in the middle //The y-axis is 20px from the bottom .moveText(PageSize.A4.getWidth()/2-32/ 2, 20f) .showText(String.valueOf(pageNumber)) .endText(); pdfCanvas.release(); } } //使用 pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new PageEventHandler(document, font));
2.2.5 Common components
table
//Do not specify the width of each column of the table, adapt to the content of the column public Table(int numColumns); //Specify the width of each column public Table(float[] pointColumnWidths); //Add cells to the table, the default is Add horizontally, and when the specified number of columns is reached, the line will automatically wrap public Table addCell(Cell cell); //Set the border of the table or cell, here you need to pay attention, if you don't want to display the border, you need to set the border to none in each cell, only Setting the border of the table will still display the border public T setBorder(Border border); //No border cell.setBorder(Border.NO_BORDER); //Solid border cell.setBorder(new SolidBorder(1)); //Dotted border cell.setBorder(new DashedBorder(1)); //four are rounded corners cell.setBorderRadius(new BorderRadius(10f)); //rounded corner - lower right corner cell.setBorderBottomRightRadius(new BorderRadius(10f)); // Rounded Corner - Bottom Left cell.setBorderBottomLeftRadius(new BorderRadius(10f)); //Rounded corner - upper right corner cell.setBorderTopRightRadius(new BorderRadius(10f)); //Rounded corner - upper left corner cell.setBorderTopLeftRadius(new BorderRadius(10f)); //About The rounded corners, the rounded corners in the table, seem to be set and cannot take effect, but it can be achieved by setting the border of the outer table to none and setting the border of the inner cell
Implement a progress bar with table
-
Idea: the outer layer is a table with one row and one column, and the inner cell is set with a table with one row and one column as the actual progress, and the width of the inner table is calculated according to the percentage
//percent here is a decimal public void processBar(Document document, float width, float percent){ float processWidth = width * percent; DeviceRgb processColor = new DeviceRgb(11,11,11);//Just write a color DeviceRgb processBgColor = new DeviceRgb(101,11,11);//Just write a color Table table = new Table(new float[]{width}).setMargin(0).setPadding(0);//Add unnecessary Gaps are killed in the cradle Table processTable = new Table(new float[]{processWidth}).setMargin(0).setPadding(0); processTable.addCell(new Cell().setBorder(Border.NO_BORDER) .setMargin(0 ).setPadding(0).setBackgroundColor(processColor)); table.addCell(new Cell().setBorder(Border.NO_BORDER).setBackgroundColor(processBgColor) .setMargin(0).setPadding(0).setBorder(Border.NO_BORDER).add(processTable)); }
Paragraph
Paragraph should be the most frequently used class, and this class will be used to write text in pdf.
Paragraph para = new Paragraph("I am a paragraph") .setFontSize(14)//Set the font size.setBold ()//Set the text to bold.setFontColor (new DeviceRgb(0,0,0))//Set Font color.setTextAlignment(TextAlignment.CENTER)//The text is centered horizontally.setFixedLeading(14);//Similar to the line height in css
Sometimes there will be some requirements that part of the text in the same paragraph needs to be set to another color or style. At this time, Text can be used to handle it, as follows:
//This processing method can't deal with the problem of bolding. If the text you want to be bold is just in the middle of the paragraph, but if you set it to bold, it will cause the entire text to become bold (italics are the same) para . add(new Text("I want to be different").setFontSize("20").setFontColor(new DeviceRgb(255,255,255)));
Image
//For image resolution issues, see the resolution section above Image image = new Image(ImageDataFactory.create("/home/test.jpg"));
Reference: Itext7 generates the most complete api summary of pdf
2.2.6 Basic usage
private void pdf1() { path = getExternalFilesDir("").getAbsolutePath() + "/itext_basic.pdf"; PdfWriter writer;//创建一个写入传递的输出流的 PdfWriter。 try { writer = new PdfWriter(new FileOutputStream(path)); PdfFont font = PdfFontFactory.createFont(StandardFonts.TIMES_ROMAN); PdfDocument pdf = new PdfDocument(writer); Document document = new Document(pdf); Text text = new Text("Hello World PDF created using iText") .setFont(font) .setFontSize(15) .setFontColor(ColorConstants.MAGENTA); //Add paragraph to the document document.add(new Paragraph(text)); document.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
2.2.7 Font style
try { PdfDocument pdf = new PdfDocument(new PdfWriter(path)); PdfFont font = PdfFontFactory.createFont(StandardFonts.COURIER); Style style = new Style().setFont(font) .setFontSize(14) .setFontColor(ColorConstants.RED) .setBackgroundColor(ColorConstants.YELLOW); Document document = new Document(pdf); document.add(new Paragraph() .add("In this PDF, ") .add(new Text("Text is styled").addStyle(style)) .add(" using iText ") .add(new Text("Style").addStyle(style)) .add(".")); document.close(); } catch (IOException e) { e.printStackTrace(); }
2.2.8 txt to pdf
private void pdf3(String source, String des) { try { BufferedReader br = new BufferedReader(new FileReader(source)); PdfDocument pdf = new PdfDocument(new PdfWriter(des)); Document document = new Document(pdf); String line; PdfFont font = PdfFontFactory.createFont(StandardFonts.COURIER); while ((line = br.readLine()) != null) { document.add(new Paragraph(line).setFont(font)); } br.close(); document.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
Reference: Generate Chinese PDF in Java using iText 7
2.3 open pdf
/** * 打开PDF文件 */ private void openPDF() { new Handler().postDelayed(new Runnable() { @Override public void run() { try { FileUtils.openFile(context, new File(path)); } catch (Exception e) { Log.e("Exception", e.toString()); } } }, 1000); }
open PDF file
/** * 打开PDF文件 * * @param context * @param url * @throws ActivityNotFoundException * @throws IOException */ public static void openFile(Context context, File url) throws ActivityNotFoundException { if (url.exists()) { Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", url); String urlString = url.toString().toLowerCase(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); /** * Security */ List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantU riPermission(packageName, uri, Intent. FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); } // Check the file type you want to open by comparing the url and extension. // When the if condition matches, the plugin sets the correct intent (mime) type // so Android knows what program to use to open the file if (urlString.toLowerCase().contains(".doc") || urlString.toLowerCase(). contains(".docx")) { // Word document intent.setDataAndType(uri, "application/msword"); } else if (urlString.toLowerCase().contains(".pdf")) { // PDF file intent.setDataAndType(uri, "application/pdf"); } else if (urlString.toLowerCase().contains(".ppt") || urlString.toLowerCase().contains(".pptx")) { // Powerpoint file intent.setDataAndType(uri, "application/vnd.ms-powerpoint"); } else if (urlString.toLowerCase().contains(".xls") || urlString.toLowerCase().contains(".xlsx")) { // Excel file intent.setDataAndType(uri, "application/vnd.ms-excel"); } else if (urlString.toLowerCase().contains(".zip") || urlString.toLowerCase().contains(".rar")) { // ZIP file intent.setDataAndType(uri, "application/trap"); } else if (urlString.toLowerCase().contains(".rtf")) { // RTF file intent.setDataAndType(uri, "application/rtf"); } else if (urlString.toLowerCase().contains(".wav") || urlString.toLowerCase().contains(".mp3")) { // WAV/MP3 audio file intent.setDataAndType(uri, "audio/*"); } else if (urlString.toLowerCase().contains(".gif")) { // GIF file intent.setDataAndType(uri, "image/gif"); } else if (urlString.toLowerCase().contains(".jpg") || urlString.toLowerCase().contains(".jpeg") || urlString.toLowerCase().contains(".png")) { // JPG file intent.setDataAndType(uri, "image/jpeg"); } else if (urlString.toLowerCase().contains(".txt")) { // Text file intent.setDataAndType(uri, "text/plain"); } else if (urlString.toLowerCase().contains(".3gp") || urlString.toLowerCase().contains(".mpg") || urlString.toLowerCase().contains(".mpeg") || urlString.toLowerCase().contains(".mpe") || urlString.toLowerCase().contains(".mp4") || urlString.toLowerCase().contains(".avi")) { // Video files intent.setDataAndType(uri, "video/*"); } else { // You can also define the intent type for any other file if you want // Also, use the else clause below to manage other unknown extensions // In this case Android will show all apps installed on the device // so you can choose which one to use intent.setDataAndType(uri, "*/*"); } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context .startActivity(intent); } else { Toast.makeText(context, "The file does not exist", Toast.LENGTH_SHORT).show(); } }
manifest.xml
<provider android:name="androidx.core.content.FileProvider" android:authorities="com.zg.pdfdemo.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider>
provider_paths
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="external_files" path="."/> </paths>
2.4 Simple use of pdfRender
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) private void pdf4() { path = getExternalFilesDir("").getAbsolutePath() + "/itext_basic.pdf"; try { // 1. Create a file File pdfFile = new File( path); // 2. Get the ParcelFileDescriptor object ParcelFileDescriptor parcelFileDescriptor = ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY); // 3. Create a PdfRenderer object PdfRenderer renderer = new PdfRenderer(parcelFileDescriptor); // Render page data to bitmap // 1. Get page number data Page object PdfRenderer.Page page = renderer.openPage(0); int pageCount = renderer.getPageCount(); Log.i("zxd", "pdf4: Total = " + pageCount); // 2. Create ARGB_8888 bitmap Bitmap bitmap = Bitmap.createBitmap(page.getWidth(), page.getHeight(), Bitmap.Config. ARGB_8888); //3. Render page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); //Render to iv binding.iv.setImageBitmap(bitmap); //Close current page data page.close( ); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
Summarize
Advantages: It is provided by Android itself. It is relatively lightweight and does not need to rely on third-party SDK. The core code is all natively implemented, and the execution efficiency is relatively high.
Disadvantages: It can only be used on Android 5.0 or above. Since the implementation is native, it is impossible to customize the rendering algorithm by yourself, and it is cumbersome to control the thread safety by yourself when using it.
reference:
[API Reference Document](https://www.apiref.com/)
Android PdfRenderer simple to use