zoukankan      html  css  js  c++  java
  • PrintService类打印

    系统打印服务框架代码位于android.printservice包中。系统并没有实现具体打印功能,需要打印机厂商制作插件接入系统打印服务之后,自行实现

    主要类:

    PrintDocument:表示待打印文件
    PrintDiscoverySession:用于发现打印机和打印机状态更新
    PrintJob:代表打印任务
    PrintService:接入系统打印Service

    打印机发现过程:

    当用户在设置里开启你的打印服务插件和进入系统打印服务界面时,系统会调用 PrinterDiscoverySession 里的 onStartPrinterDiscovery(List priorityList) 函数,通知你的插件查找打印机。具体查找方式需要自己实现,可能是查找USB接口,可能是搜索网络。系统只管结果,你通过调用其父类的 addPrinters() 方法将打印机添加进去。打印机是放在List数组里传入。

    打印机选择过程

    当用户通过一些有打印功能的APP调用系统打印服务时,如果选择了你的插件的打印机,那么系统会调用 PrinterDiscoverySession 里的 onStartPrinterStateTracking(PrinterId printerId) 方法。这里系统主要希望得到打印机的 PrinterCapabilitiesInfo 和状态,里面包括打印机支持的纸张大小,以及色彩等详细功能参数。

    打印过程:

    当用户在刚刚的系统打印服务界面点击右上角的打印按钮时,系统会调用打印机所属的 PrintService 里的 onPrintJobQueued(PrintJob printJob) 方法,插件需要处理该 PrintJob 。首先需要通过 PrintJob.isQueued() 判断,该PrintJob是否准备好打印,返回true代表可以打印。然后可以通过 PrintJob.getDocument() 获得要打印的文档,这里面的数据可以通过 PrintDocument.getData() 读取。开始打印的时候,调用PrintJob.start()标记开始状态。当打印成功时,调用 PrintJob.complete() 标记打印成功。或者打印失败时,调用 PrintJob.fail( String) 标记失败。

    打印服务需要添加的权限:

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

    打印类:

    public class MyPrintService extends PrintService {
    
        private static final String TAG = "MyPrintService";
    
        @Override
        protected PrinterDiscoverySession onCreatePrinterDiscoverySession() {
            Log.d(TAG, "onCreatePrinterDiscoverySession()");
            return new MyPrintDiscoverySession(this);
        }
    
        @Override
        protected void onRequestCancelPrintJob(PrintJob printJob) {
            Log.d(TAG, "onRequestCancelPrintJob()");
            printJob.cancel();
        }
    
        @Override
        protected void onPrintJobQueued(PrintJob printJob) {
            Log.d(TAG, "onPrintJobQueued()");
            PrintJobInfo printjobinfo = printJob.getInfo();
            PrintDocument printdocument = printJob.getDocument();
            if (printJob.isQueued()) {
                return;
            }
            printJob.start();
    
            String filename = "docu.pdf";
            File outfile = new File(this.getFilesDir(), filename);
            outfile.delete();
            FileInputStream file = new ParcelFileDescriptor.AutoCloseInputStream(printdocument.getData());
            //创建一个长度为1024的内存空间
            byte[] bbuf = new byte[1024];
            //用于保存实际读取的字节数
            int hasRead = 0;
            //使用循环来重复读取数据
            try {
                FileOutputStream outStream = new FileOutputStream(outfile);
                while ((hasRead = file.read(bbuf)) > 0) {
                    //将字节数组转换为字符串输出
                    //System.out.print(new String(bbuf, 0, hasRead));
                    outStream.write(bbuf);
                }
                outStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                //关闭文件输出流,放在finally块里更安全
                try {
                    file.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            printJob.complete();
        }
    }

    PrinterDiscoverySession实现类编写:

    public class MyPrintDiscoverySession extends PrinterDiscoverySession {
        private static final String TAG = "MyPrintDiscoverySession";
        private final MyPrintService myPrintService;
    
        public MyPrintDiscoverySession(MyPrintService myPrintService) {
            Log.d(TAG, "MyPrintDiscoverySession()");
            this.myPrintService = myPrintService;
        }
    
        @Override
        public void onStartPrinterDiscovery(List<PrinterId> priorityList) {
            Log.d(TAG, "onStartPrinterDiscovery()");
            List<PrinterInfo> printers = this.getPrinters();
            String name = "printer1";
            PrinterInfo myprinter = new PrinterInfo
                    .Builder(myPrintService.generatePrinterId(name), name, PrinterInfo.STATUS_IDLE)
                    .build();
            printers.add(myprinter);
            addPrinters(printers);
        }
    
        @Override
        public void onStopPrinterDiscovery() {
            Log.d(TAG, "onStopPrinterDiscovery()");
        }
    
        /**
         * 确定这些打印机存在
         * @param printerIds
         */
        @Override
        public void onValidatePrinters(List<PrinterId> printerIds) {
            Log.d(TAG, "onValidatePrinters()");
        }
    
        /**
         * 选择打印机时调用该方法更新打印机的状态,能力
         * @param printerId
         */
        @Override
        public void onStartPrinterStateTracking(PrinterId printerId) {
            Log.d(TAG, "onStartPrinterStateTracking()");
            PrinterInfo printer = findPrinterInfo(printerId);
            if (printer != null) {
                PrinterCapabilitiesInfo capabilities =
                        new PrinterCapabilitiesInfo.Builder(printerId)
                                .setMinMargins(new PrintAttributes.Margins(200, 200, 200, 200))
                                .addMediaSize(PrintAttributes.MediaSize.ISO_A4, true)
                                //.addMediaSize(PrintAttributes.MediaSize.ISO_A5, false)
                                .addResolution(new PrintAttributes.Resolution("R1", "200x200", 200, 200), false)
                                .addResolution(new PrintAttributes.Resolution("R2", "300x300", 300, 300), true)
                                .setColorModes(PrintAttributes.COLOR_MODE_COLOR
                                                | PrintAttributes.COLOR_MODE_MONOCHROME,
                                        PrintAttributes.COLOR_MODE_MONOCHROME)
                                .build();
    
                printer = new PrinterInfo.Builder(printer)
                        .setCapabilities(capabilities)
                        .setStatus(PrinterInfo.STATUS_IDLE)
                //        .setDescription("fake print 1!")
                        .build();
                List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
    
                printers.add(printer);
                addPrinters(printers);
            }
        }
    
        @Override
        public void onStopPrinterStateTracking(PrinterId printerId) {
            Log.d(TAG, "onStopPrinterStateTracking()");
        }
    
        @Override
        public void onDestroy() {
            Log.d(TAG, "onDestroy()");
        }
    
        private PrinterInfo findPrinterInfo(PrinterId printerId) {
            List<PrinterInfo> printers = getPrinters();
            final int printerCount = getPrinters().size();
            for (int i = 0; i < printerCount; i++) {
                PrinterInfo printer = printers.get(i);
                if (printer.getId().equals(printerId)) {
                    return printer;
                }
            }
            return null;
        }
    
    }
  • 相关阅读:
    Notes about "Exploring Expect"
    Reuse Sonar Checkstyle Violation Report for Custom Data Analysis
    Eclipse带参数调试的方法
    MIT Scheme Development on Ubuntu
    Manage Historical Snapshots in Sonarqube
    U盘自动弹出脚本
    hg的常用配置
    Java程序员的推荐阅读书籍
    使用shared memory 计算矩阵乘法 (其实并没有加速多少)
    CUDA 笔记
  • 原文地址:https://www.cnblogs.com/jiayonghua/p/10401490.html
Copyright © 2011-2022 走看看