Android實現(xiàn)系統(tǒng)打印功能
本文實例為大家分享了Android實現(xiàn)系統(tǒng)打印的具體代碼,供大家參考,具體內(nèi)容如下
一、打印圖片
使用PrintHelper類,如:
private void doPhotoPrint() { PrintHelper photoPrinter = new PrintHelper(getActivity()); photoPrinter.setScaleMode(PrintHelper.SCALE_MODE_FIT); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.droids); photoPrinter.printBitmap("droids.jpg - test print", bitmap); }
可以在應(yīng)用的菜單欄中調(diào)用該方法,當(dāng)printBitmap()方法調(diào)用時,Android系統(tǒng)的打印界面
會彈出,用戶可以設(shè)置一些參數(shù),然后進(jìn)行打印或取消。
二、打印自定義文檔
1.連接到PrintManager類:
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"; // Start a print job, passing in a PrintDocumentAdapter implementation // to handle the generation of a print document printManager.print(jobName, new MyPrintDocumentAdapter(getActivity()), null); // }
注:print函數(shù)第二個參數(shù)為繼承了抽象類PrintDocumentAdapter 的適配器類,第三個參數(shù)為 PrintAttributes對象,
可以用來設(shè)置一些打印時的屬性。
2.創(chuàng)建打印適配器類
打印適配器與Android系統(tǒng)的打印框架進(jìn)行交互,處理打印的生命周期方法。打印過程主要有以下生命周期方法:
- onStart():當(dāng)打印過程開始的時候調(diào)用;
- onLayout():當(dāng)用戶更改打印設(shè)置導(dǎo)致打印結(jié)果改變時調(diào)用,如更改紙張尺寸,紙張方向等;
- onWrite():當(dāng)將要打印的結(jié)果寫入到文件中時調(diào)用,該方法在每次onLayout()調(diào)用后會調(diào)用一次或多次;
- onFinish():當(dāng)打印過程結(jié)束時調(diào)用。
注:關(guān)鍵方法有onLayout()和onWrite(),這些方法默認(rèn)都是在主線程中調(diào)用,因此如果打印過程比較耗時,應(yīng)該在后臺線程中進(jìn)行。
3.覆蓋onLayout()方法
在onLayout()方法中,你的適配器需要告訴系統(tǒng)框架文本類型,總頁數(shù)等信息,如:
@Override 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(); return; } // 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."); } }
注:onLayout()方法的執(zhí)行有完成,取消,和失敗三種結(jié)果,你必須通過調(diào)用 PrintDocumentAdapter.LayoutResultCallback類的適當(dāng)回調(diào)方法表明執(zhí)行結(jié)果, onLayoutFinished()方法的布爾型參數(shù)指示布局內(nèi)容是否已經(jīng)改變。
onLayout()方法的主要任務(wù)就是計算在新的設(shè)置下,需要打印的頁數(shù),如通過打印的方向決定頁數(shù): 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); }
4.覆蓋onWrite()方法
當(dāng)需要將打印結(jié)果輸出到文件中時,系統(tǒng)會調(diào)用onWrite()方法,該方法的參數(shù)指明要打印的頁以及結(jié)果寫入的文件,你的方法實現(xiàn)需要將頁面的內(nèi)容寫入到一個多頁面的PDF文檔中,當(dāng)這個過程完成時,需要調(diào)用onWriteFinished() 方法,如:
@Override 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; return; } // 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()); return; } finally { mPdfDocument.close(); mPdfDocument = null; } PageRange[] writtenPages = computeWrittenPages(); // Signal the print framework the document is complete callback.onWriteFinished(writtenPages); ... }
drawPage()方法實現(xiàn):
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); }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實現(xiàn)PDF預(yù)覽打印功能
- Android gradle插件打印時間戳的方法詳解
- Android編程實現(xiàn)計算兩個日期之間天數(shù)并打印所有日期的方法
- Android中如何安全地打印日志詳解
- Mac 下 Android Studio 不打印日志的解決辦法
- Android jni調(diào)試打印char陣列的實例詳解
- Android下的POS打印機調(diào)用的簡單實現(xiàn)
- Android 藍(lán)牙連接 ESC/POS 熱敏打印機打印實例(ESC/POS指令篇)
- Android 藍(lán)牙連接 ESC/POS 熱敏打印機打印實例(藍(lán)牙連接篇)
- Android打印機--小票打印格式及模板設(shè)置實例代碼
- Android進(jìn)階——安卓調(diào)用ESC/POS打印機打印實例
- Android手機通過藍(lán)牙連接佳博打印機的實例代碼
相關(guān)文章
解析離線安裝Eclipse的Android ADT開發(fā)插件的具體操作(圖文)
本篇文章是對離線安裝Eclipse的Android ADT開發(fā)插件的具體操作進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05Android中AOP的應(yīng)用實踐之過濾重復(fù)點擊
這篇文章主要給大家介紹了關(guān)于Android中AOP的應(yīng)用實踐之過濾重復(fù)點擊的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Kotlin創(chuàng)建一個好用的協(xié)程作用域
這篇文章主要介紹了Kotlin創(chuàng)建一個好用的協(xié)程作用域,kotlin中使用協(xié)程,是一定要跟協(xié)程作用域一起配合使用的,否則可能協(xié)程的生命周期無法被準(zhǔn)確控制,造成內(nèi)存泄漏或其他問題2022-07-07Jetpack?Compose對比React?Hooks?API相似度
這篇文章主要為大家介紹了Jetpack?Compose對比React?Hooks?API相似度,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08探究Android中ListView復(fù)用導(dǎo)致布局錯亂的解決方案
這篇文章主要介紹了探究Android中ListView復(fù)用導(dǎo)致布局錯亂的解決方案,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-10-10Android?如何獲取傳感器的數(shù)據(jù)方法詳解
這篇文章主要介紹了Android?如何獲取傳感器的數(shù)據(jù),傳感器?Sensor?是一種檢測裝置,能感受到被測量的信息,并能將感受到的信息,按一定規(guī)律變換成為電信號或其他所需形式的信息輸出,以滿足信息的傳輸、處理、存儲、顯示、記錄和控制等要求2022-07-07Android Studio導(dǎo)入項目非常慢的解決方法
這篇文章主要為大家詳細(xì)介紹了Android Studio導(dǎo)入項目非常慢的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11android圖像繪制(四)自定義一個SurfaceView控件
自定義控件(類似按鈕等)的使用,自定義一個SurfaceView。如某一塊的動態(tài)圖(自定義相應(yīng)),或者類似UC瀏覽器下面的工具欄,感興趣的朋友可以了解下2013-01-01