You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何检测Android中未完成的打印任务并监听状态变化?

Android打印任务状态监控(失败/阻塞检测)

Android系统没有提供直接的PrintJob状态变化回调监听器,你可以通过定时轮询+系统广播监听的组合方案来实现打印任务完成/失败/阻塞的实时通知,具体实现如下:

一、核心思路

  1. 提交打印任务时保存PrintJob实例或其ID,用于后续状态查询
  2. 通过定时轮询主动检查任务状态,覆盖所有场景
  3. 监听系统打印状态广播,被动接收状态变化通知,减少轮询频率

二、关键状态说明

PrintJobInfo的状态值可以覆盖你提到的场景:

  • STATE_COMPLETED:任务成功完成
  • STATE_FAILED:任务直接失败
  • STATE_BLOCKED:任务被阻塞(对应打印机缺墨、纸张不足、断开连接等情况)
  • STATE_CANCELED:任务被取消

三、具体实现

1. 提交打印任务并保存任务ID

提交打印时,获取并保存PrintJob的ID,用于后续定位任务:

// Kotlin示例
val printManager = getSystemService(Context.PRINT_SERVICE) as PrintManager
val printJob = printManager.print("我的文档", customPrintAdapter, null)
// 保存任务ID,可存在SharedPreferences、ViewModel等地方
val targetJobId = printJob.id

2. 定时轮询检查状态

使用协程或Handler定期查询任务状态,适合需要精准监控的场景:

// 在ViewModel或Activity中启动轮询(Kotlin协程)
viewModelScope.launch {
    val printManager = getSystemService(Context.PRINT_SERVICE) as PrintManager
    while (isActive) {
        delay(2000) // 每2秒检查一次,可按需调整
        val printJob = printManager.getPrintJob(targetJobId)
        printJob?.let { job ->
            when (job.info.state) {
                PrintJobInfo.STATE_COMPLETED -> {
                    // 处理任务完成逻辑,比如通知用户
                    cancel() // 停止轮询
                }
                PrintJobInfo.STATE_FAILED, PrintJobInfo.STATE_BLOCKED, PrintJobInfo.STATE_CANCELED -> {
                    // 处理失败/阻塞/取消逻辑,比如提示用户检查打印机
                    cancel() // 停止轮询
                }
                // 其他状态(如STATE_QUEUED、STATE_PRINTING)继续轮询
            }
        } ?: run {
            // 任务已不存在,停止轮询
            cancel()
        }
    }
}

3. 监听系统广播接收状态变化

通过监听系统广播android.intent.action.PRINT_JOB_STATE_CHANGED,被动获取状态更新,降低轮询频率:

步骤1:注册广播接收器(Manifest方式)

<receiver android:name=".PrintJobStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.PRINT_JOB_STATE_CHANGED" />
    </intent-filter>
</receiver>

步骤2:实现广播接收器

class PrintJobStateReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action != "android.intent.action.PRINT_JOB_STATE_CHANGED") return
        
        val printManager = context?.getSystemService(Context.PRINT_SERVICE) as PrintManager
        val targetJobId = // 从保存的位置获取目标任务ID
        val printJob = printManager.getPrintJob(targetJobId)
        
        printJob?.let { job ->
            when (job.info.state) {
                PrintJobInfo.STATE_COMPLETED -> {
                    // 通知任务完成
                }
                PrintJobInfo.STATE_FAILED, PrintJobInfo.STATE_BLOCKED -> {
                    // 通知任务因缺墨/断开连接等原因失败/阻塞
                }
            }
        }
    }
}

四、注意事项

  • 广播会接收系统所有打印任务的状态变化,务必通过任务ID精准匹配自己的任务,避免误处理
  • 轮询间隔不要设置过短,避免不必要的资源消耗
  • STATE_BLOCKED是检测打印机硬件问题(缺墨、断连)的关键状态,需重点处理

内容的提问来源于stack exchange,提问作者Rohan Pande

火山引擎 最新活动