android - 通过 usb 从 Android 设备向热敏打印机发送数据

标签 android usb connectivity thermal-printer

我正在使用我的应用程序将数据发送到热敏打印机。我已经让它在网络上正常工作并且我的数据打印正确。现在有一个额外的要求,我们还必须能够通过 USB 进行打印。

这是我尝试过的:

    private UsbManager mUsbManager;
    private UsbDevice mDevice;
    private UsbDeviceConnection mConnection;
    private UsbInterface mInterface;
    private UsbEndpoint mEndPoint;
    private PendingIntent mPermissionIntent;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    private static Boolean forceCLaim = true;

    HashMap<String, UsbDevice> mDeviceList;
    Iterator<UsbDevice> mDeviceIterator;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        mDeviceList = mUsbManager.getDeviceList();    
        mDeviceIterator = mDeviceList.values().iterator();

        Button print = (Button)findViewById(R.id.print);

        Toast.makeText(this, "Device List Size: " + String.valueOf(mDeviceList.size()), Toast.LENGTH_SHORT).show();
        TextView textView = (TextView) findViewById(R.id.usbDevice);
        String usbDevice = "";
        //This is just testing what devices are connected
        while (mDeviceIterator.hasNext()) {
            UsbDevice usbDevice1 = mDeviceIterator.next();
            usbDevice += "\n" +
                    "DeviceID: " + usbDevice1.getDeviceId() + "\n" +
                    "DeviceName: " + usbDevice1.getDeviceName() + "\n" +
                    "DeviceClass: " + usbDevice1.getDeviceClass() + " - " + translateDeviceClass(usbDevice1.getDeviceClass()) + "\n" +
                    "DeviceSubClass: " + usbDevice1.getDeviceSubclass() + "\n" +
                    "VendorID: " + usbDevice1.getVendorId() + "\n" +
                    "ProductID: " + usbDevice1.getProductId() + "\n";

            int interfaceCount = usbDevice1.getInterfaceCount();
            Toast.makeText(this, "INTERFACE COUNT: " + String.valueOf(interfaceCount), Toast.LENGTH_SHORT).show();

            mDevice = usbDevice1;

            if (mDevice == null) {
                Toast.makeText(this, "mDevice is null", Toast.LENGTH_SHORT).show();
            }else{
                Toast.makeText(this, "mDevice is not null", Toast.LENGTH_SHORT).show();
            }
            textView.setText(usbDevice);
        }

        if (mDevice == null) {
            Toast.makeText(this, "mDevice is null", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this, "mDevice is not null", Toast.LENGTH_SHORT).show();
        }

        mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        registerReceiver(mUsbReceiver, filter);
        mUsbManager.requestPermission(mDevice, mPermissionIntent);

  print.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //setup();
                print(mConnection, mInterface);
            }
        });
}

   private String translateDeviceClass(int deviceClass){
        switch(deviceClass){
            case UsbConstants.USB_CLASS_APP_SPEC:
                return "Application specific USB class";
            case UsbConstants.USB_CLASS_AUDIO:
                return "USB class for audio devices";
            case UsbConstants.USB_CLASS_CDC_DATA:
                return "USB class for CDC devices (communications device class)";
            case UsbConstants.USB_CLASS_COMM:
                return "USB class for communication devices";
            case UsbConstants.USB_CLASS_CONTENT_SEC:
                return "USB class for content security devices";
            case UsbConstants.USB_CLASS_CSCID:
                return "USB class for content smart card devices";
            case UsbConstants.USB_CLASS_HID:
                return "USB class for human interface devices (for example, mice and keyboards)";
            case UsbConstants.USB_CLASS_HUB:
                return "USB class for USB hubs";
            case UsbConstants.USB_CLASS_MASS_STORAGE:
                return "USB class for mass storage devices";
            case UsbConstants.USB_CLASS_MISC:
                return "USB class for wireless miscellaneous devices";
            case UsbConstants.USB_CLASS_PER_INTERFACE:
                return "USB class indicating that the class is determined on a per-interface basis";
            case UsbConstants.USB_CLASS_PHYSICA:
                return "USB class for physical devices";
            case UsbConstants.USB_CLASS_PRINTER:
                return "USB class for printers";
            case UsbConstants.USB_CLASS_STILL_IMAGE:
                return "USB class for still image devices (digital cameras)";
            case UsbConstants.USB_CLASS_VENDOR_SPEC:
                return "Vendor specific USB class";
            case UsbConstants.USB_CLASS_VIDEO:
                return "USB class for video devices";
            case UsbConstants.USB_CLASS_WIRELESS_CONTROLLER:
                return "USB class for wireless controller devices";
            default: return "Unknown USB class!";
        }
//Broadcast receiver to obtain permission from user for connection
 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (ACTION_USB_PERMISSION.equals(action)) {
                synchronized (this) {
                    UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                        if(device != null){
                            //call method to set up device communication
                            mInterface = device.getInterface(0);
                            mEndPoint = mInterface.getEndpoint(0);
                            mConnection = mUsbManager.openDevice(device);

                            //setup();
                        }
                    }
                    else {
                        //Log.d("SUB", "permission denied for device " + device);
                        Toast.makeText(context, "PERMISSION DENIED FOR THIS DEVICE", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    };

 private void print(UsbDeviceConnection connection, UsbInterface intrface){

        String test = "THIS IS A PRINT TEST";
        byte [] testBytes = test.getBytes();

        if(intrface==null){
            Toast.makeText(this, "INTERFACE IS NULL", Toast.LENGTH_SHORT).show();
        }
        if(connection==null){
            Toast.makeText(this, "CONNECTION IS NULL", Toast.LENGTH_SHORT).show();
        }

        if(forceCLaim==null){
            Toast.makeText(this, "FORCE CLAIM IS NULL", Toast.LENGTH_SHORT).show();
        }   

        connection.claimInterface(intrface, forceCLaim);
        connection.bulkTransfer(mEndPoint, testBytes, testBytes.length, 0);

    }

所以设备连接到 USB 设备,但是当我尝试批量传输时没有任何反应,任何人都可以阐明这一点吗? USB 连接对我来说是一个新领域,因此欢迎任何提示

编辑

事实证明端点存在问题并且批量传输没有返回,但是,现在这些问题已解决并且它返回批量传输成功,但是它仍然没有打印。有人对此有任何想法吗??

最佳答案

@DJ-DOO,我试过同样的方法,但我是这样做的:

代替 String test = "THIS IS A PRINT TEST";

使用这个:String test = "THIS IS A PRINT TEST\r\n";

更多检查:What is the difference between \r and \n?

你的最后一行代码“connection.bulkTransfer(mEndPoint, testBytes, testBytes.length, 0);”应该在另一个线程中。

例如:

Thread thread = new Thread(new Runnable() {
   @Override
   public void run() {
   connection.bulkTransfer(mEndPoint, testBytes, testBytes.length, 0);
   }
});
thread.run(); //or thread.start(); -as you wish

奖励:用于 Papercut :byte[] cut_paper = {0x1D, 0x56, 0x41, 0x10}; 在这个字节数组之前,我建议发送一个带有上述 \n 的字符串。 在第一个之后放上与 cut_paper 字节数组相同的行就足够了:

Thread thread = new Thread(new Runnable() {
   @Override
   public void run() {
      connection.bulkTransfer(mEndPoint, testBytes, testBytes.length, 0);
      connection.bulkTransfer(mEndPoint, cut_paper, cut_paper.length, 0);
   }
});
thread.run();

也可寻求帮助:https://developer.android.com/guide/topics/connectivity/usb/host.html

希望对您有所帮助:)

关于android - 通过 usb 从 Android 设备向热敏打印机发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28066508/

相关文章:

C++ 数据库连接?

android - 如何在android中制作可滚动的按钮

android - 我们应该为 Rxjava3 使用哪个 rxjava3 改造适配器

Android Location getTime() 添加 1 天错误

android - 有没有办法找出连接的可能性?

c++ - 以编程方式检查我的机器是否可以访问互联网

java - 在同步块(synchronized block)内使用 wait()

python - 如何在 USB 闪存驱动器插入时运行 Python 脚本

c - 通过 USB 获取系统日期/时间

objective-c - 读取串行数据时 CPU 消耗和延迟较高