在Android上打印超出简单照片的内容需要在打印文档中组合文本和图形。Android框架提供了一种使用HTML编写文档并以最少的代码打印它的方法。
在Android 4.4(API级别19)中,WebView
类已更新,可启用打印HTML内容。此类允许您加载本地HTML资源或从网络下载页面,创建打印作业并将其交给Android的打印服务。
本课程将向您展示如何快速构建包含文本和图形的HTML文档,并使用WebView
打印它。
加载HTML文档
使用WebView
打印HTML文档涉及加载HTML资源或将HTML文档构建为字符串。本节介绍如何构建HTML字符串并将其加载到WebView
中以进行打印。
此视图对象通常用作活动布局的一部分。但是,如果您的应用程序未使用WebView
,则可以专门为打印目的创建该类的实例。创建此自定义打印视图的主要步骤是
- 创建一个
WebViewClient
,在加载HTML资源后启动打印作业。 - 将HTML资源加载到
WebView
对象中。
以下代码示例演示如何创建一个简单的WebViewClient
并加载动态创建的HTML文档
Kotlin
private var mWebView: WebView? = null private fun doWebViewPrint() { // Create a WebView object specifically for printing val webView = WebView(activity) webView.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false override fun onPageFinished(view: WebView, url: String) { Log.i(TAG, "page finished loading $url") createWebPrintJob(view) mWebView = null } } // Generate an HTML document on the fly: val htmlDocument = "<html><body><h1>Test Content</h1><p>Testing, testing, testing...</p></body></html>" webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null) // Keep a reference to WebView object until you pass the PrintDocumentAdapter // to the PrintManager mWebView = webView }
Java
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; } @Override public void onPageFinished(WebView view, String url) { Log.i(TAG, "page finished loading " + url); 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); // Keep a reference to WebView object until you pass the PrintDocumentAdapter // to the PrintManager mWebView = webView; }
注意:确保您生成打印作业的调用发生在您在上节中创建的onPageFinished()
方法中。如果您不等待页面加载完成,则打印输出可能不完整或为空白,或者可能完全失败。
注意:上面的示例代码保留了WebView
对象的实例,因此在创建打印作业之前不会被垃圾回收。确保您在自己的实现中也这样做,否则打印过程可能会失败。
如果要在页面中包含图形,请将图形文件放在项目的assets/
目录中,并在loadDataWithBaseURL()
方法的第一个参数中指定一个基本URL,如下面的代码示例所示
Kotlin
webView.loadDataWithBaseURL( "file:///android_asset/images/", htmlBody, "text/HTML", "UTF-8", null )
Java
webView.loadDataWithBaseURL("file:///android_asset/images/", htmlBody, "text/HTML", "UTF-8", null);
您还可以通过将loadDataWithBaseURL()
方法替换为loadUrl()
来加载网页进行打印,如下所示。
Kotlin
webView.loadUrl("https://developer.android.com/about/index.html")
Java
// Print an existing web page (remember to request INTERNET permission!): webView.loadUrl("https://developer.android.com/about/index.html");
当使用WebView
创建打印文档时,您应该注意以下限制
- 您无法向文档添加页眉或页脚,包括页码。
- HTML文档的打印选项不包括打印页面范围的功能,例如:不支持打印10页HTML文档的第2页到第4页。
WebView
的实例一次只能处理一个打印作业。- 包含CSS打印属性(例如横向属性)的HTML文档不受支持。
- 您不能在HTML文档中使用JavaScript来触发打印。
注意:包含在布局中的WebView
对象的內容,在加载文档后也可以打印。
如果您想创建更自定义的打印输出并完全控制打印页面上的内容绘制,请跳转到下一课:打印自定义文档 课。
创建打印作业
创建WebView
并加载您的HTML内容后,您的应用程序几乎完成了其打印过程的部分工作。接下来的步骤是访问PrintManager
,创建打印适配器,最后创建打印作业。以下示例说明了如何执行这些步骤
Kotlin
private fun createWebPrintJob(webView: WebView) { // Get a PrintManager instance (activity?.getSystemService(Context.PRINT_SERVICE) as? PrintManager)?.let { printManager -> val jobName = "${getString(R.string.app_name)} Document" // Get a print adapter instance val printAdapter = webView.createPrintDocumentAdapter(jobName) // Create a print job with name and adapter instance printManager.print( jobName, printAdapter, PrintAttributes.Builder().build() ).also { printJob -> // Save the job object for later status checking printJobs += printJob } } }
Java
private void createWebPrintJob(WebView webView) { // Get a PrintManager instance PrintManager printManager = (PrintManager) getActivity() .getSystemService(Context.PRINT_SERVICE); String jobName = getString(R.string.app_name) + " Document"; // Get a print adapter instance PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(jobName); // Create a print job with name and adapter instance PrintJob printJob = printManager.print(jobName, printAdapter, new PrintAttributes.Builder().build()); // Save the job object for later status checking printJobs.add(printJob); }
此示例保存了PrintJob
对象的实例供应用程序使用,这不是必需的。您的应用程序可以使用此对象跟踪打印作业在处理过程中的进度。当您想在应用程序中监控打印作业的完成、失败或用户取消状态时,此方法很有用。无需创建应用内通知,因为打印框架会自动为打印作业创建系统通知。