"Android App Development technology: Media Development" Print

Source: Internet
Author: User
Tags drawtext

Guo Xiaoxing
Weibo: Guo Xiaoxing's Sina Weibo
Email:[email protected]
Blog: http://blog.csdn.net/allenwells

In Android 4.4 and later systems, services that print pictures and text directly from Android apps, including printing pictures, HTML pages, and creating custom printed documents, are available.

Print a picture

Printhelper in the Android Support library provides a simple way to print pictures with a single layout option: Setscalemode, which allows you to provide the following options:

    • Scale_mode_fit: This option adjusts the image size, and the entire picture is displayed in the print active area.
    • Scale_mode_fill: This option adjusts the size of the picture proportionally so that the picture fills the entire print area, which may not be printed, and will be the default image stretch if you do not set the Print Layout option for the picture

private void doPhotoPrint () {
    PrintHelper photoPrinter = new PrintHelper (getActivity ());
    photoPrinter.setScaleMode (PrintHelper.SCALE_MODE_FIT);
    Bitmap bitmap = BitmapFactory.decodeResource (getResources (),
    photoPrinter.printBitmap ("droids.jpg-test print", bitmap);
After the above method is called, the Android print interface will appear, allowing the user to select a printer and its printer options. The user can choose to print pictures and cancel the operation. When printing starts, a notification of printing notification will be displayed in the notification bar of the system .

Two print HTML documents
Android 4.4 and later provide the WebView class, which can load a local HTML resource or download a page from the Internet, and then create a print task, and give it to the Android print service.

2.1 Load the print document
The WebView object is generally used as part of the Activity layout. If the application does not currently use WebView, we can create an instance of this class for printing. The steps are as follows:

After the HTML resource is loaded, create a WebViewClient to start a printing task.
Load HTML resources into the WebView object.

Print HTML constructed string

private WebView mWebView;
private void doWebViewPrint () {
    // Create a WebView object specifically for printing
    WebView webView = new WebView (getActivity ());
    webView.setWebViewClient (new WebViewClient () {
            public boolean shouldOverrideUrlLoading (WebView view, String url) {
                return false;
            public void onPageFinished (WebView view, String url) {
                Log.i (TAG, "page finished loading" + url);
                // Call the method to create a print task in the onPageFinished () method in WebViewClient,
                // So that the page is loaded before printing, otherwise it will cause the printout to be incomplete or blank.
                createWebPrintJob (view);
                mWebView = null;
    // Generate an HTML document on the fly:
    String htmlDocument = "<html> <body> <h1> Test Content </ h1> <p> Testing," +
            "testing, testing ... </ p> </ body> </ html>";
    webView.loadDataWithBaseURL (null, htmlDocument, "text / HTML", "UTF-8", null);

    // Retain a reference to a WebView object instance, so that it can be guaranteed that it will not be collected by the garbage collector before the print job is created.
    mWebView = webView;
If we want to print an image, and this image file is in the assets directory of the project, the method is as follows:

webView.loadDataWithBaseURL ("file: // android_asset / images /", htmlBody, "test / HTML", "UTF-8", null);
If we want to load and print a webpage, the method is as follows:

webView.loadUrl ("http://blog.csdn.net/allenwells");
Note: When using WebView to print documents, there are the following restrictions:

You cannot add headers and footers to the document, including page numbers.
The printing options of HTML documents do not include the range of pages selected for printing, for example: for a 10-page HTMl document, it is not possible to print only 2 to 4 pages
An instance of WebView can only process one print job at a time.
If an HTML document contains CSS printing attributes, such as a landscape attribute, this is not supported.
You cannot activate printing through JavaScript scripts in an HTML document.
2.2 Create a print job
After the HTML page is loaded, we can create a print job, as shown below:

private void createWebPrintJob (WebView webView) {
    // Get a PrintManager instance
    PrintManager printManager = (PrintManager) getActivity ()
            .getSystemService (Context.PRINT_SERVICE);
    // Get a print adapter instance
    PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter ();
    // Create a print job with name and adapter instance
    String jobName = getString (R.string.app_name) + "Document";

    // Save an instance of the PrintJob object, this high practice is not necessary, when we monitor whether the printing task in the application is completed,
    // Failed or canceled by the user, we can adopt this approach.
    PrintJob printJob = printManager.print (jobName, printAdapter,
            new PrintAttributes.Builder (). build ());
    // Save the job object for later status checking
    mPrintJobs.add (printJob);
Three print custom documents
For some applications, such as drawing applications, page layout applications and other applications that focus on image output, creating beautiful printed pages will be its core function. In this case, just printing a picture or an HTML document is not enough. The printout of such applications requires precise control of every object that will be displayed on the page, including fonts, text flow, page breaks, headers, footers, and some image elements.

In order to be able to create custom print documents, we need to build and print components that can communicate with each other, adjust print parameters, draw page elements and manage the printing of multiple pages.

3.1 Connect to Print Manager
To connect to the Android printing framework, you must first obtain an instance of the PrintManager class, which initializes a print task and begins the life cycle of the print task.


Get the print manager and start the printing process.

private void doPrint () {
    // Get a PrintManager instance
    PrintManager printManager = (PrintManager) getActivity ()
            .getSystemService (Context.PRINT_SERVICE);
    // Set job name, which will be displayed in the print queue
    String jobName = getActivity (). GetString (R.string.app_name) + "Document";

    // Pass the PrintDocumentAdapter to start the printing task. The last parameter received by the print () method is
    // A PrintAttributes object, we can use this parameter to make some print settings to the print framework, than
    // As preset based on the previous printing cycle, to improve the user experience.
    printManager.print (jobName, new MyPrintDocumentAdapter (getActivity ()),
3.2 Create a print adapter
The print adapter is responsible for interacting with the Android printing framework and handling each step of the printing process. This process requires the user to select the printer and print options before creating a print document. Since users can choose different performance printers, different page sizes or different page orientations, these options may affect the final printing effect. When these options are configured, the printing framework will seek the adapter to lay out and generate a print document, as a preliminary preparation for printing. Once the user clicks the print button, the framework will pass the final print document to a print provider (Print Provider) for printing output. During the printing process, the user can choose to cancel printing, so the print adapter must monitor and respond to the request to cancel printing.

The PrintDocumentAdapter abstract class is responsible for processing the life cycle of printing, and its callback methods are as follows:

onStart (): This method will be called once the printing process starts. If the application has any one-time preparation tasks to perform, such as taking a snapshot of the data to be printed, then let them execute here. In the adapter, this callback method is not necessarily implemented.
onLayout (): Every time the user changes the settings that affect the printout, such as changing the page size or page orientation, this function will be called to give the application an opportunity to recalculate the printed page layout. In addition, this method must return how many pages the printed document contains.
onWrite (): After this method is called, the printed page will be rendered into a file to be printed. This method can be called one or more times after the onLayout () method is called.
onFinish (): This method will be called once the printing process is over. If the application has any one-time destruction tasks to be executed, let these tasks be executed in this method. This callback method does not have to be implemented.
Note: The callback methods of these adapters will be called on the main thread of the application. If the implementation of these methods may take a lot of time to execute, then we can put them in another thread to execute. For example: we can encapsulate the layout or the operation of writing a printed document in an AsyncTask object.

3.3 Calculate the printed document information
When implementing the PrintDocumentAdapter class, the application must be able to specify the type of document to be created, calculate the total number of pages to be printed for the printing task, and provide the size information of the printed page.


Implementation of onLayout () method

// The execution result of the onLayout () method has three kinds of completion, cancellation or failure, we need to pass PrintDocumentAdapter.LayoutResultCallBack
// Appropriate method in the object to indicate one of these structures.
public void onLayout (PrintAttributes oldAttributes,
                     PrintAttributes newAttributes,
                     CancellationSignal cancellationSignal,
                     LayoutResultCallback callback,
                     Bundle metadata) {
// Create a new PdfDocument with the requested page attributes
    mPdfDocument = new PrintedPdfDocument (getActivity (), newAttributes);
    // Respond to cancellation request
    if (cancellationSignal.isCancelled ()) {
        callback.onLayoutCancelled ();
    // Compute the expected number of printed pages
    int pages = computePageCount (newAttributes);
    if (pages> 0) {
        // Return print information to print framework
        PrintDocumentInfo info = new PrintDocumentInfo
                .Builder ("print_output.pdf")
                .setContentType (PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                .setPageCount (pages);
                .build ();
        // Content layout reflow is complete
        callback.onLayoutFinished (info, true);
    } else {
        // Otherwise report an error to the print framework
        callback.onLayoutFailed ("Page count calculation failed.");
// Calculate the number of pages of the printed document and give it to the printer as a printing parameter. The number of printed pages is determined according to the printing direction.
private int computePageCount (PrintAttributes printAttributes) {
    int itemsPerPage = 4; // default item count for portrait mode MediaSize pageSize = printAttributes.getMediaSize ();
    if (! pageSize.isPortrait ()) {
        // Six items per page in landscape orientation
        itemsPerPage = 6;
    // Determine number of print items
    int printItemCount = getPrintItemCount ();
    return (int) Math.ceil (printItemCount / itemsPerPage);
2.4 Write print documents to file
When printing content to a file, Android printing calls the onWrite () method of the PrintDocumentAdapter class. The parameters of this method specify which pages to be written and the output file to be used. The content of the page is rendered into a PDF file containing multiple pages. When this process is over, we need to call the onWriteFinished () method of the callback object.


Implementation of onWrite () method.

// OnWrite () method execution result has 3 kinds of completion, cancellation or failure, we need to pass PrintDocumentAdapter.LayoutResultCallBack
// Appropriate method in the object to indicate one of these structures.
public void onWrite (final PageRange [] pageRanges,
                    final ParcelFileDescriptor destination,
                    final CancellationSignal cancellationSignal,
                    final WriteResultCallback callback) {
    // Iterate over each page of the document,
    // check if it ‘s in the output range.
    for (int i = 0; i <totalPages; i ++) {
        // Check to see if this page is in the output range.
        if (containsPage (pageRanges, i)) {
            // If so, add it to writtenPagesArray. WrittenPagesArray.size ()
            // is used to compute the next output page index.
            writtenPagesArray.append (writtenPagesArray.size (), i);
            PdfDocument.Page page = mPdfDocument.startPage (i);
            // check for cancellation
            if (cancellationSignal.isCancelled ()) {
                callback.onWriteCancelled ();
                mPdfDocument.close ();
                mPdfDocument = null;
            // Draw page content for printing
            drawPage (page);
            // Rendering is complete, so page can be finalized.
            mPdfDocument.finishPage (page);
    // Write PDF document to file
    try {
        mPdfDocument.writeTo (new FileOutputStream (
                destination.getFileDescriptor ()));
    } catch (IOException e) {
        callback.onWriteFailed (e.toString ());
    } finally {
        mPdfDocument.close ();
        mPdfDocument = null;
    } PageRange [] writtenPages = computeWrittenPages ();
    // Signal the print framework the document is complete
    callback.onWriteFinished (writtenPages);
2.5 Draw the contents of PDF pages
When the application prints, we need to generate a PDF document and pass it to the Android printing framework for printing. We can use any PDF generation library to assist in this operation.

The PrintedPdfDocument class uses Canvas objects to draw elements on PDF pages.


Draw the following simple elements on the PDF page.

private void drawPage (PdfDocument.Page page) {
    Canvas canvas = page.getCanvas ();
    // units are in points (1/72 of an inch)
    int titleBaseLine = 72;
    int leftMargin = 54;
    Paint paint = new Paint ();
    paint.setColor (Color.BLACK);
    paint.setTextSize (36);
    canvas.drawText ("Test Title", leftMargin, titleBaseLine, paint);
    paint.setTextSize (11);
    canvas.drawText ("Test paragraph", leftMargin, titleBaseLine + 25, paint);
    paint.setColor (Color.BLUE);
    canvas.drawRect (100, 100, 172, 172, paint);
Note: The Canvas object allows printing elements to be placed on the edge of the PDF document, but many printers cannot print on the edge of the paper, so when we use PrintedPdfDocument to construct a printed document, we should ensure that we can consider which unprintable edge areas.

Copyright notice: When we do something seriously, we can find the endless fun. As programmers, the world is also simpler, and the colorful technology is like the scenery on the road, and enjoy while walking.

[Android Application Development Technology: Media Development] Print

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.