在 Android 4.4(API 级别 19)及更高版本中,框架提供直接从 Android 应用打印图片和文档的服务。本文章介绍如何在应用中启用打印功能,包括打印图片、HTML 页面以及创建要打印的自定义文档。
一、打印照片
Android 支持库 PrintHelper 类提供 一种简单的图片打印方法,用于简化图片打印操作。
1、缩放模式
- 通过 setScaleMode() 方法,可设置打印时的图片缩放模式:
- SCALE_MODE_FIT: 调整图片大小,以便在页面的可打印区域内完整显示图片。
- SCALE_MODE_FILL:缩放图片,使其填充整个页面的可打印区域,但可能会裁剪图片的上下或左右边缘的某些部分。此模式为默认选项。
- 两个缩放选项都能保持图片的现有宽高比不变。
2、使用方法
- 调用 printBitmap() 方法后,系统会显示打印界面,用户可以选择打印机和打印选项。
package com.android.androidfunctiondemo.printer
import android.content.Context
import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.print.PrintHelper
import com.android.androidfunctiondemo.R
import com.android.androidfunctiondemo.databinding.ActivityPrinterBinding
class PrintPhotoActivity: AppCompatActivity() {
private lateinit var viewBinding: ActivityPrinterBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewBinding = ActivityPrinterBinding.inflate(layoutInflater)
setContentView(viewBinding.root)
viewBinding.print.setOnClickListener {
doPhotoPrint(this)
}
}
/**
* 打印图片
*/
private fun doPhotoPrint(context: Context) {
try {
val printHelper = PrintHelper(context)
printHelper.scaleMode = PrintHelper.SCALE_MODE_FIT
val bitmap = BitmapFactory.decodeResource(resources, R.mipmap.weather_sun)
bitmap?.let {
printHelper.printBitmap("photo-print", bitmap)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
- 实现效果

二、打印 HTML 文档
使用 WebView 类可打印 HTML 文档,支持直接加载 HTML 页面, 或者以字符串形式构建自定义 HTML 文档。
1、注意事项
- 使用 WebView 创建打印文档时, 存在以下限制:
- 不能向文档中添加页眉或页脚,包括页码。
- HTML 文档的打印选项不支持打印页码选择,只能全部打印。
- WebView 的实例一次只能处理一个打印作业。
- 不能在 HTML 文档中使用 JavaScript 触发打印作业。
2、实现步骤
- 创建 WebViewClient 类,用于监听 HTML 资源加载完成情况,若 HTML 资源已加载完成,则创建打印作业。
- 将 HTML 资源加载到 WebView 对象中。
3、使用方法
- 确保在 onPageFinished() 方法中调用打印任务。若没有等待页面显示 加载完成,则打印输出可能不完整或空白,或者可能完全失败。
- 存储 WebView 对象,使其不会在打印作业之前进行垃圾回收,否则打印流程 可能会失败。
package com.android.androidfunctiondemo.printer
import android.content.Context
import android.os.Bundle
import android.print.PrintAttributes
import android.print.PrintManager
import android.util.Log
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.appcompat.app.AppCompatActivity
import com.android.androidfunctiondemo.databinding.ActivityPrinterBinding
class PrintHtmlActivity: AppCompatActivity() {
private val tag = "PrintHtmlActivity"
private lateinit var viewBinding: ActivityPrinterBinding
private var globalWebView: WebView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewBinding = ActivityPrinterBinding.inflate(layoutInflater)
setContentView(viewBinding.root)
viewBinding.print.setOnClickListener {
doWebViewPrint(this)
}
}
/**
* 打印 HTML 文档
*/
private fun doWebViewPrint(context: Context) {
val webView = WebView(context)
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
return false
}
override fun onPageFinished(view: WebView?, url: String?) {
Log.d(tag, "[onPageFinished] url: $url")
view?.let {
createWebPrintJob(it)
}
globalWebView = null
}
}
try {
// 方法1:生成自定义 html 文档
val htmlDocument = "<html><body><h1>Test Content</h1><p>Testing, testing, testing...</p></body></html>"
webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null)
// 方法2: 直接加载网页内容
// webView.loadUrl("https://developer.android.google.cn/training/printing/html-docs?hl=zh-cn")
globalWebView = webView
} catch (e: Exception) {
e.printStackTrace()
globalWebView = null
}
}
/**
* 创建打印任务
*/
private fun createWebPrintJob(webView: WebView) {
try {
val printManager = getSystemService(Context.PRINT_SERVICE) as PrintManager
val jobName = "WebView Document"
val printAdapter = webView.createPrintDocumentAdapter(jobName)
printManager.print(jobName, printAdapter, PrintAttributes.Builder().build())
} catch (e: Exception) {
e.printStackTrace()
}
}
}
- 实现效果

三、打印 PDF 文档
1、实现步骤
- 创建打印适配器。
- 连接打印管理器。
- 创建打印任务。
2、创建打印适配器
- 打印适配器与 Android 打印框架交互,并处理打印过程的各个步骤。
- 这个过程要求用户在创建打印文档之前选择打印机和打印选项。这些选择会影响最终输出,因为用户可以选择具有不同输出能力、不同页面大小或不同页面方向的打印机。在用户做出这些选择时,打印框架会要求适配器布局并生成打印文档,为最终输出做准备。
- 一旦用户点击打印按钮,框架就会将最终的打印文档传递给打印服务提供商以进行输出。
- 在打印过程中,用户可以选择取消打印操作,因此打印适配器还必须监听并响应取消请求。
(1)PrintDocumentAdapter 类
- PrintDocumentAdapter 抽象类旨在处理打印生命周期,它有四个主要的回调方法。您必须在您的打印适配器中实现这些方法,以便与打印框架正确交互。
- onStart(): 在打印过程开始时调用一次。如果应用程序有任何一次性准备任务需要执行,例如获取要打印数据的快照,可以在这里完成。在适配器中实现此方法并非强制要求。
- onLayout(): 每当用户更改影响输出的打印设置时(例如不同的页面大小或页面方向),此方法都会被调用,为应用程序提供了计算要打印页面布局的机会。此方法必须返回打印文档中预期的页数。
- onWrite(): 被调用来将打印页面渲染到一个将要打印的文件中。此方法可能在每次调用 onLayout() 之后被调用一次或多次。
- onFinish(): 在打印过程结束时调用一次。如果应用程序有任何一次性清理任务需要执行,可以在这里完成。在适配器中实现此方法并非强制要求。
- 这些适配器方法会在您应用程序的主线程中被调用。如果您预计在实现中这些方法的执行会比较耗时,那么应该将它们的执行封装到一个单独的线程中。例如,您可以将布局计算或打印文档的写入工作封装到单独的 AsyncTask 对象中。
(2)计算打印文档信息
- onLayout() 方法指定正在创建的文档类型,并根据打印页面大小的信息计算打印作业的总页数。可通过 PrintDocumentInfo 类提供有关打印作业预期输出的信息,包括页数和内容类型。
- onLayout() 方法的执行有三种结果:完成、取消,或者在无法完成布局计算时出现失败。通过调用 PrintDocumentAdapter.LayoutResu
Android打印功能全解析

最低0.47元/天 解锁文章
1994

被折叠的 条评论
为什么被折叠?



