USB点阵POS打印机使用UsbManager检测到设备但无法打印求助
我之前折腾过Bixolon SRP 275III这款USB打印机,刚好碰到过和你一模一样的问题——能检测到设备、数据传输没报错,但打印机就是纹丝不动。给你几个亲测有效的排查方向和解决方案:
排查与解决步骤
1. 先确认USB权限是否真的拿到手
虽然你能检测到设备,但Android的UsbManager需要明确获取独占访问权限后才能正常通信,很多时候问题就出在这一步:
- 先检查
AndroidManifest.xml里是否声明了USB Host权限:
<uses-feature android:name="android.hardware.usb.host" android:required="true" />
- 必须通过广播请求用户授权,并且在授权回调后再执行设备连接操作,不能直接检测到设备就发数据。示例代码:
// 定义权限请求的PendingIntent var usbPermissionIntent = PendingIntent.GetBroadcast(Application.Context, 0, new Intent("com.your.package.USB_PERMISSION"), PendingIntentFlags.UpdateCurrent); // 向目标设备请求权限 m_usbManager.RequestPermission(m_usbde, usbPermissionIntent);
- 还要注册广播接收器监听授权结果,只有用户点击允许后,再去打开设备、获取接口和端点。
2. 验证USB接口和端点是否选对了
Bixolon SRP 275III属于USB串口类设备,必须找到对应的**批量输出端点(BULK OUT)**才能正常发数据:
- 遍历设备的所有接口,过滤出
InterfaceClass为UsbConstants.UsbClassComm或UsbConstants.UsbClassPrinter的接口(这款机型通常用Comm类) - 在选中的接口里,找到方向为
UsbConstants.UsbDirOut、类型为UsbEndpointTypeBulk的端点,这才是真正的打印数据输出端口 - 确认你是用这个正确的端点执行
BulkTransfer操作,而不是随便选了一个端点。
3. 检查打印指令是否符合ESC/POS规范
即使数据发送成功,如果指令格式不对,打印机也会静默忽略:
- 打印前先发送初始化指令,比如
ESC @(十六进制0x1B 0x40)重置打印机状态 - 测试最简单的打印内容:比如发送
"Hello World\r\n",结尾一定要加换行或回车指令,不然打印机可能把数据存在缓冲区不输出 - 可以参考Bixolon官方的ESC/POS指令集,比如切纸需要发送
ESC i(0x1B 0x69)这类特定指令。
4. 确保数据传输完整并触发输出
有时候数据已经到了USB缓冲区,但打印机没收到“打印”的触发信号:
- 执行
BulkTransfer后,检查返回的发送字节数是否和你传入的字节数一致,确保数据全部发送成功 - 发送完内容后,额外发送一个
LF(换行,0x0A)或FF(换页,0x0C)指令,强制打印机输出缓冲区内容 - 把
BulkTransfer的超时时间设置长一点(比如1000ms以上),避免因超时导致数据未完全发送。
5. 排查兼容性和驱动问题
部分Android设备可能对这款打印机的USB协议支持不好:
- 换一台Android设备测试,排除当前设备的兼容性问题
- 查看Bixolon官方文档,确认SRP 275III是否支持Android USB Host模式,有没有需要额外安装的驱动或SDK依赖。
补充完整流程代码片段(补全你未贴完的部分)
private UsbDeviceConnection _usbConnection; private UsbEndpoint _printOutEndpoint; private UsbManager _usbManager; private async void printReceipt() { _usbManager = (UsbManager)Application.Context.GetSystemService(Context.UsbService); var deviceList = _usbManager.DeviceList; UsbTargetDevice = null; // 通过VendorId和ProductId精准定位Bixolon打印机(VendorId通常是0x04E8,ProductId查官方文档) foreach (var device in deviceList.Values) { if (device.VendorId == 0x04E8 && device.ProductId == 0xXXXX) { targetDevice = device; break; } } if (targetDevice == null) { Toast.MakeText(Application.Context, "未找到打印机", ToastLength.Short).Show(); return; } // 请求USB权限 var permissionIntent = PendingIntent.GetBroadcast(Application.Context, 0, new Intent("com.your.app.USB_PRINT_PERMISSION"), PendingIntentFlags.UpdateCurrent); _usbManager.RequestPermission(targetDevice, permissionIntent); // 注册广播接收器监听权限结果 var permissionReceiver = new UsbPermissionReceiver(); permissionReceiver.OnPermissionGranted += (isGranted, device) => { if (isGranted) { OpenPrinterConnection(device); // 发送打印数据 SendPrintCommand("测试打印内容\r\n"); // 发送切纸指令 SendPrintCommand(new byte[] { 0x1B, 0x69 }); } else { Toast.MakeText(Application.Context, "未获取USB权限", ToastLength.Short).Show(); } }; Application.Context.RegisterReceiver(permissionReceiver, new IntentFilter("com.your.app.USB_PRINT_PERMISSION")); } private void OpenPrinterConnection(UsbDevice device) { // 遍历找到正确的接口和端点 for (int i = 0; i < device.InterfaceCount; i++) { var usbInterface = device.GetInterface(i); if (usbInterface.InterfaceClass == UsbConstants.UsbClassComm) { _usbConnection = _usbManager.OpenDevice(device); if (_usbConnection != null && _usbConnection.ClaimInterface(usbInterface, true)) { for (int j = 0; j < usbInterface.EndpointCount; j++) { var endpoint = usbInterface.GetEndpoint(j); if (endpoint.Type == UsbConstants.UsbEndpointTypeBulk && endpoint.Direction == UsbConstants.UsbDirOut) { _printOutEndpoint = endpoint; break; } } break; } } } } private void SendPrintCommand(string content) { if (_usbConnection == null || _printOutEndpoint == null) return; byte[] data = Encoding.ASCII.GetBytes(content); int sentBytes = _usbConnection.BulkTransfer(_printOutEndpoint, data, data.Length, 1500); if (sentBytes != data.Length) { Toast.MakeText(Application.Context, "数据发送不完整", ToastLength.Short).Show(); } } private void SendPrintCommand(byte[] command) { if (_usbConnection == null || _printOutEndpoint == null) return; int sentBytes = _usbConnection.BulkTransfer(_printOutEndpoint, command, command.Length, 1500); if (sentBytes != command.Length) { Toast.MakeText(Application.Context, "指令发送失败", ToastLength.Short).Show(); } } // 自定义USB权限广播接收器 public class UsbPermissionReceiver : BroadcastReceiver { public Action<bool, UsbDevice> OnPermissionGranted; public override void OnReceive(Context context, Intent intent) { string action = intent.Action; if ("com.your.app.USB_PRINT_PERMISSION".Equals(action)) { UsbDevice device = intent.GetParcelableExtra(UsbManager.ExtraDevice) as UsbDevice; bool isGranted = intent.GetBooleanExtra(UsbManager.ExtraPermissionGranted, false); OnPermissionGranted?.Invoke(isGranted, device); } } }
内容的提问来源于stack exchange,提问作者Jesun Bicar
相关产品推荐
相关产品推荐

