您现在的位置是:网站首页> Android

Android 基于打印服务的打印的实现

  • Android
  • 2022-04-09
  • 917人已阅读
摘要

Android打印实现

赋予权限

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

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.qdian.testmyapp" >

    <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY" />

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

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



    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:roundIcon="@mipmap/ic_launcher_round"

        android:supportsRtl="true"

        android:requestLegacyExternalStorage="true"

        android:theme="@style/AppTheme" >

        <activity android:name=".MainActivity" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>


</manifest>


Context.getExternalFilesDir() ;//取代android:requestLegacyExternalStorage="true"

import android.print.PrintAttributes;

import android.print.PrintManager;

void doPrint()

{

 PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);

        PrintAttributes.Builder builder = new PrintAttributes.Builder();

        builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);

        printManager.print("test pdf print", new MyPrintDocumentAdapterEx(this,filePath), builder.build());

}

package com.qdian.testmyapp;


import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.pdf.PdfDocument;

import android.graphics.pdf.PdfRenderer;

import android.os.Bundle;

import android.os.CancellationSignal;

import android.os.ParcelFileDescriptor;

import android.print.PageRange;

import android.print.PrintAttributes;

import android.print.PrintDocumentAdapter;

import android.print.PrintDocumentInfo;

import android.print.pdf.PrintedPdfDocument;


import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;


public class MyPrintDocumentAdapterEx extends PrintDocumentAdapter {

    private Context context;

    private int pageHeight;

    private int pageWidth;

    private PdfDocument mPdfDocument;

    private int totalpages = 1;

    private String pdfPath;

    private List<Bitmap> mlist;


    public MyPrintDocumentAdapterEx(Context context, String pdfPath) {


        this.context = context;

        this.pdfPath = pdfPath;


    }


    @Override

    //在onLayout()方法中,你的适配器需要告诉系统框架文本类型,总页数等信息

    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,

                         LayoutResultCallback callback,

                         Bundle metadata) {


        mPdfDocument = new PrintedPdfDocument(context, newAttributes); //创建可打印PDF文档对象


        pageHeight = newAttributes.getMediaSize().ISO_A4.getHeightMils() * 72 / 1000;  //设置尺寸

        pageWidth = newAttributes.getMediaSize().ISO_A4.getWidthMils() * 72 / 1000;


        if (cancellationSignal.isCanceled()) {

            callback.onLayoutCancelled();

            return;

        }


       totalpages=2;


        if (totalpages > 0) {

            PrintDocumentInfo.Builder builder = new PrintDocumentInfo

                    .Builder("快速入门.pdf")

                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)

                    .setPageCount(totalpages);  //构建文档配置信息


            PrintDocumentInfo info = builder.build();

            callback.onLayoutFinished(info, true);

        } else {

            callback.onLayoutFailed("Page count is zero.");

        }

    }


    @Override

    //当需要将打印结果输出到文件中时,系统会调用onWrite()方法,该方法的参数指明要打印的页以及结果写入的文件,你的方法实现需要将页面的内容写入到一个多页面的PDF文档中,当这个过程完成时,需要调用onWriteFinished

    public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,

                        final WriteResultCallback callback) {


               for(int i=0;i<2;i++){

                PdfDocument.PageInfo newPage = new PdfDocument.PageInfo.Builder(pageWidth,

                        pageHeight, i).create();

                PdfDocument.Page page =

                        mPdfDocument.startPage(newPage);  //创建新页面


                if (cancellationSignal.isCanceled()) {  //取消信号

                    callback.onWriteCancelled();

                    mPdfDocument.close();

                    mPdfDocument = null;

                    return;

                }

                drawPage(page, i);  //将内容绘制到页面Canvas上

                mPdfDocument.finishPage(page);

          }


        try {

            mPdfDocument.writeTo(new FileOutputStream(

                    destination.getFileDescriptor()));

        } catch (IOException e) {

            callback.onWriteFailed(e.toString());

            return;

        } finally {

            mPdfDocument.close();

            mPdfDocument = null;

        }


        callback.onWriteFinished(pageRanges);

    }


    //页面绘制(渲染)

    private void drawPage(PdfDocument.Page page, int pagenumber) {

        Canvas canvas = page.getCanvas();


        /*

            Paint paint = new Paint();

           paint.setTextSize(100);

            canvas.drawText("打印测试",20,20,paint);

*/

        int titleBaseLine = 72;

        int leftMargin = 54;


        Paint paint = new Paint();

        paint.setColor(Color.RED);

        paint.setTextSize(36);

        canvas.drawText("Hello Title", leftMargin, titleBaseLine, paint);


        paint.setTextSize(11);

        canvas.drawText("Hello paragraph", leftMargin, titleBaseLine + 25, paint);


        paint.setColor(Color.BLUE);

        canvas.drawRect(100, 100, 172, 172, paint);

    }

}



1.打印网页 


PrintManager printManager = (PrintManager)mContext.getSystemService(Context.PRINT_SERVICE);

//打印任务的名字

String jobName = getString(R.string.app_name) + " 处方打印";

//这里需要webview创建PrintDocumentAdapter

PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter();

PrintAttributes.Builder builder = new PrintAttributes.Builder();

//选择A5纸张横向打印

builder.setMediaSize(PrintAttributes.MediaSize.ISO_A5.asLandscape());

printManager.print(jobName, printAdapter,builder.build());

上面的方法需要个你当前的webview,将当前的webview传给他他们,执行上面的方法就会跳转到系统的打印页面,非常简单


2、打印图片


try {

    PrintHelper printHelper = new PrintHelper(this);

    printHelper.printBitmap("jobName", BitmapFactory.decodeStream(getAssets().open("timg.jpg")));

} catch (IOException e) {

    e.printStackTrace(); 

}

直接传给该方法一个bitmap,就直接跳转到预览打印页面,你就可以选择相应的打印机进行打印了


打印PDF文件

赋予权限

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

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.qdian.testmyapp" >

    <uses-permission android:name="android.permission.START_PRINT_SERVICE_CONFIG_ACTIVITY" />

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

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



    <application

        android:allowBackup="true"

        android:icon="@mipmap/ic_launcher"

        android:label="@string/app_name"

        android:roundIcon="@mipmap/ic_launcher_round"

        android:supportsRtl="true"

        android:requestLegacyExternalStorage="true"

        android:theme="@style/AppTheme" >

        <activity android:name=".MainActivity" >

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />


                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>


</manifest>


Context.getExternalFilesDir() ;//取代android:requestLegacyExternalStorage="true"

动态获取权限

MainActivity.java


 private static final int REQUEST_EXTERNAL_STORAGE = 1;

    private static String[] PERMISSIONS_STORAGE = {

            Manifest.permission.READ_EXTERNAL_STORAGE,

            Manifest.permission.WRITE_EXTERNAL_STORAGE };


    public static void verifyStoragePermissions(Activity activity) {

        // Check if we have write permission

        int permission = ActivityCompat.checkSelfPermission(activity,

                Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {

            // We don't have permission so prompt the user

            ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,

                    REQUEST_EXTERNAL_STORAGE);

        }

    }

@Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);


    // Example of a call to a native method

    TextView tv = (TextView) findViewById(R.id.sample_text);

    tv.setText(stringFromJNI());

    verifyStoragePermissions(this);

    findViewById(R.id.mybt).setOnClickListener(new View.OnClickListener() {

        @Override

        public void onClick(View v) {

            Intent intent = new Intent(Intent.ACTION_GET_CONTENT);

            String[] strArray=new String[1];

            strArray[0]="application/pdf";

            intent.putExtra(Intent.EXTRA_MIME_TYPES,strArray);

            intent.setType("*/*");//无类型限制

            intent.addCategory(Intent.CATEGORY_OPENABLE);

            startActivityForResult(intent, 1);



        }

    });

    }

public static String getPath(Context context, Uri uri) throws URISyntaxException {


        if ("content".equalsIgnoreCase(uri.getScheme())) {

            String[] projection = { "_data" };

            Cursor cursor = null;

            try {


                    cursor = context.getContentResolver().query(uri, projection, null, null, null);

                int column_index = cursor.getColumnIndexOrThrow("_data");

                if (cursor.moveToFirst()) {


                    return cursor.getString(column_index);


                }


            } catch (Exception e) {


// Eat it Or Log it.


            }


        } else if ("file".equalsIgnoreCase(uri.getScheme())) {


            return uri.getPath();


        }

        return null;

    }


 @Override

      protected void onActivityResult(int requestCode, int resultCode, Intent data) {

                 if (resultCode == Activity.RESULT_OK) {

                     Uri uri = data.getData();

                     filePath = uri.getPath();

                     try {

                         filePath=getPath(MainActivity.this,uri);

                     } catch (URISyntaxException e) {

                         e.printStackTrace();

                     }

                     doPrint();                     

                 }



        }

void doPrint() {

 PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);

        PrintAttributes.Builder builder = new PrintAttributes.Builder();

        builder.setColorMode(PrintAttributes.COLOR_MODE_COLOR);

        printManager.print("test pdf print", new MyPrintDocumentAdapterPDF(this,filePath), builder.build());



    }

MyPrintDocumentAdapterPDF.java



package com.qdian.testmyapp;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.pdf.PdfDocument;

import android.graphics.pdf.PdfRenderer;

import android.os.Bundle;

import android.os.CancellationSignal;

import android.os.ParcelFileDescriptor;

import android.print.PageRange;

import android.print.PrintAttributes;

import android.print.PrintDocumentAdapter;

import android.print.PrintDocumentInfo;

import android.print.pdf.PrintedPdfDocument;


import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.List;


public class MyPrintDocumentAdapterPDF extends PrintDocumentAdapter {

    private Context context;

    private int pageHeight;

    private int pageWidth;

    private PdfDocument mPdfDocument;

    private int totalpages = 1;

    private String pdfPath;

    private List<Bitmap> mlist;


    public MyPrintDocumentAdapterPDF(Context context, String pdfPath) {


        this.context = context;

        this.pdfPath = pdfPath;


    }


    @Override

    //在onLayout()方法中,你的适配器需要告诉系统框架文本类型,总页数等信息

    public void onLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal,

                         LayoutResultCallback callback,

                         Bundle metadata) {


        mPdfDocument = new PrintedPdfDocument(context, newAttributes); //创建可打印PDF文档对象


        pageHeight = newAttributes.getMediaSize().ISO_A4.getHeightMils() * 72 / 1000; //设置尺寸

        pageWidth = newAttributes.getMediaSize().ISO_A4.getWidthMils() * 72 / 1000;


        if (cancellationSignal.isCanceled()) {

            callback.onLayoutCancelled();

            return;

        }


        ParcelFileDescriptor mFileDescriptor = null;

        PdfRenderer pdfRender = null;

        PdfRenderer.Page page = null;

        try {

            mFileDescriptor = ParcelFileDescriptor.open(new File(pdfPath), ParcelFileDescriptor.MODE_READ_ONLY);

            if (mFileDescriptor != null)

                pdfRender = new PdfRenderer(mFileDescriptor);


            mlist = new ArrayList<>();


            if (pdfRender.getPageCount() > 0) {

                totalpages = pdfRender.getPageCount();

                for (int i = 0; i < pdfRender.getPageCount(); i++) {

                    if(null != page)

                        page.close();

                    page = pdfRender.openPage(i);

                    Bitmap bmp = Bitmap.createBitmap(page.getWidth()*2,page.getHeight()*2, Bitmap.Config.ARGB_8888);

                    page.render(bmp, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);

                    mlist.add(bmp);

                }

            }

            if(null != page)

                page.close();

            if(null != mFileDescriptor)

                mFileDescriptor.close();

            if (null != pdfRender)

                pdfRender.close();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        }


        if (totalpages > 0) {

            PrintDocumentInfo.Builder builder = new PrintDocumentInfo

                    .Builder("快速入门.pdf")

                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)

                    .setPageCount(totalpages); //构建文档配置信息


            PrintDocumentInfo info = builder.build();

            callback.onLayoutFinished(info, true);

        } else {

            callback.onLayoutFailed("Page count is zero.");

        }

    }


    @Override

    public void onWrite(final PageRange[] pageRanges, final ParcelFileDescriptor destination, final CancellationSignal cancellationSignal,

                        final WriteResultCallback callback) {

        for (int i = 0; i < totalpages; i++) {

            if (pageInRange(pageRanges, i)) //保证页码正确

            {

                PdfDocument.PageInfo newPage = new PdfDocument.PageInfo.Builder(pageWidth,

                        pageHeight, i).create();

                PdfDocument.Page page =

                        mPdfDocument.startPage(newPage); //创建新页面


                if (cancellationSignal.isCanceled()) { //取消信号

                    callback.onWriteCancelled();

                    mPdfDocument.close();

                    mPdfDocument = null;

                    return;

                }

                drawPage(page, i); //将内容绘制到页面Canvas上

                mPdfDocument.finishPage(page);

            }

        }


        try {

            mPdfDocument.writeTo(new FileOutputStream(

                    destination.getFileDescriptor()));

        } catch (IOException e) {

            callback.onWriteFailed(e.toString());

            return;

        } finally {

            mPdfDocument.close();

            mPdfDocument = null;

        }


        callback.onWriteFinished(pageRanges);

    }


    private boolean pageInRange(PageRange[] pageRanges, int page) {

        for (int i = 0; i < pageRanges.length; i++) {

            if ((page >= pageRanges[i].getStart()) &&

                    (page <= pageRanges[i].getEnd()))

                return true;

        }

        return false;

    }


    //页面绘制(渲染)

    private void drawPage(PdfDocument.Page page,int pagenumber) {

        Canvas canvas = page.getCanvas();

        if(mlist != null){

            Paint paint = new Paint();

            Bitmap bitmap = mlist.get(pagenumber);

            int bitmapWidth = bitmap.getWidth();

            int bitmapHeight = bitmap.getHeight();

            // 计算缩放比例

            float scale = (float)pageWidth/(float)bitmapWidth;

            // 取得想要缩放的matrix参数

            Matrix matrix = new Matrix();

            matrix.postScale(scale, scale);

            canvas.drawBitmap(bitmap,matrix,paint);

        }

    }


}


Top