You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Android中通过DNS名称编程指定打印机接入PrintService?

解决安卓通过DNS名称指定打印机打印的问题

看来你已经摸透了自定义PrintService和PrinterDiscoverySession的基础流程,现在卡在了如何通过DNS名称精准定位并指定打印机这一步对吧?其实核心就是把DNS信息嵌入到打印机的识别逻辑里,我给你拆解关键环节:

1. 构造关联DNS的PrinterInfo与PrinterId

你已经能添加打印机,但要让系统识别到指定DNS的那台,需要在创建PrinterInfo时把DNS作为核心标识:

@Override
public void onStartPrinterDiscovery(@NonNull List<PrinterId> priorityList) {
    final List<PrinterInfo> printers = new ArrayList<>();
    // 替换为你要指定的目标打印机DNS名称
    String targetPrinterDns = "printer-office.local";
    
    // 用DNS名称生成唯一PrinterId,确保每台打印机的标识唯一
    PrinterId printerId = generatePrinterId(targetPrinterDns);
    
    // 构造PrinterInfo,把DNS作为打印机地址和显示标识
    PrinterInfo.Builder printerBuilder = new PrinterInfo.Builder(printerId, "办公室打印机("+targetPrinterDns+")", PrinterInfo.STATUS_IDLE);
    // 绑定DNS地址,后续打印时直接调用
    printerBuilder.setAddress(targetPrinterDns);
    // 添加支持的打印规格,比如A4纸、PDF格式
    printerBuilder.addMediaSize(MediaSize.ISO_A4);
    printerBuilder.addContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT);
    
    printers.add(printerBuilder.build());
    // 更新系统的打印机发现列表
    addPrinters(printers);
}

这里的关键是用generatePrinterId(targetPrinterDns)把DNS作为打印机的唯一标识,让系统能精准区分不同DNS的设备。

2. 验证DNS打印机的在线状态

用户选择打印机前,系统会调用onValidatePrinters,你可以在这里检查DNS对应的打印机是否在线:

@Override
public void onValidatePrinters(@NonNull List<PrinterId> printerIds) {
    List<PrinterInfo> validatedPrinters = new ArrayList<>();
    for (PrinterId id : printerIds) {
        // 从PrinterId中取出之前存入的DNS名称
        String dnsName = id.getLocalId();
        boolean isReachable = false;
        
        // 异步检查DNS可达性(必须在子线程执行,避免阻塞主线程)
        new Thread(() -> {
            try {
                InetAddress address = InetAddress.getByName(dnsName);
                isReachable = address.isReachable(3000); // 3秒超时判断
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            // 更新打印机状态并通知系统
            PrinterInfo existingInfo = getPrinterInfo(id);
            if (existingInfo != null) {
                PrinterInfo.Builder builder = new PrinterInfo.Builder(existingInfo);
                builder.setStatus(isReachable ? PrinterInfo.STATUS_IDLE : PrinterInfo.STATUS_UNAVAILABLE);
                validatedPrinters.add(builder.build());
                
                // 回到主线程更新状态
                runOnUiThread(() -> addPrinters(validatedPrinters));
            }
        }).start();
    }
}

这一步能让用户直观看到打印机的在线状态,避免无效操作。

3. 处理打印任务时连接指定DNS打印机

当用户选择你的DNS打印机并提交任务后,onPrintJobQueued会被触发,这里你要通过DNS地址建立打印连接(比如用IPP协议):

@Override
public void onPrintJobQueued(@NonNull PrintJob printJob) {
    PrinterId printerId = printJob.getInfo().getPrinterId();
    String targetDns = printerId.getLocalId();
    
    // 示例:通过DNS初始化IPP打印机连接
    IppPrinter ippPrinter = new IppPrinter("http://"+targetDns+"/ipp/print");
    
    // 获取待打印文档并处理
    PrintDocument document = printJob.getDocument();
    // 读取文档内容、转换格式并发送到打印机的逻辑
    // ...
    
    // 更新打印任务状态
    printJob.setState(PrintJob.STATE_COMPLETED);
    printJob.complete();
}

几个关键注意事项

  • 所有网络操作必须放在异步线程,否则会触发ANR错误。
  • 记得在Manifest中申请INTERNET权限,用于DNS解析和网络打印机通信。
  • 如果打印机使用特定协议(比如JetDirect、蓝牙),需要适配对应的客户端逻辑。

这样一套流程下来,就能实现通过指定DNS名称选择并打印到目标打印机了。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:31:04