java中实现与USB硬件通信

目前在网络上查询java与usb的设备通信资源都非常的少大多都来自一个05年的文章,本人也摘取了网上的例子,例子中直接运行也出现了一些问题,经过debug还是可以直接在windows上直接使用java向usb设备发送指令并接受返回值的.接下来贴出代码供大家参考

import java.util.List;

import javax.usb.UsbConfiguration;
import javax.usb.UsbDevice;
import javax.usb.UsbDeviceDescriptor;
import javax.usb.UsbEndpoint;
import javax.usb.UsbHostManager;
import javax.usb.UsbHub;
import javax.usb.UsbInterface;
import javax.usb.UsbInterfacePolicy;
import javax.usb.UsbPipe;

public class UsbTest {
    //下边两个参数为系统中usb设备的VID和PID 需要自行配置
    private static short idVendor = (short)0xFFFF;
    private static short idProduct = (short)0x0001;

    public static void main(String[] args) {
        try {
            UsbPipe sendUsbPipe = new UsbTest().useUsb();
            //本人测试时 是使用公司的一个读卡器主要对银行卡和身份证进行读取写等相关操作
            //下边为发送的指令,目前大多usb硬件设备都是接受HEX 16进制指令
            //那么如下指令为:363600028000000280 的16进制指令 注意2位为一组16进制字符
            buff[0] = (byte)0x36;
            buff[1] = (byte)0x36;
            buff[2] = (byte)0x00;
            buff[3] = (byte)0x02;
            buff[4] = (byte)0x80;
            buff[5] = (byte)0x00;
            buff[6] = (byte)0x00;
            buff[7] = (byte)0x02;
            buff[8] = (byte)0x80;
            sendMassge(sendUsbPipe, buff);
 }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

public UsbPipe useUsb() throws Exception{
        UsbInterface iface = linkDevice();
        if (iface == null) {
            return null;
        }
        UsbEndpoint receivedUsbEndpoint,sendUsbEndpoint;

        sendUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(0);
        if (!sendUsbEndpoint.getUsbEndpointDescriptor().toString().contains("OUT")) {
            receivedUsbEndpoint = sendUsbEndpoint;
            sendUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(1);
        } else {
            receivedUsbEndpoint = (UsbEndpoint)iface.getUsbEndpoints().get(1);
        }

        //发送:
        UsbPipe sendUsbPipe =  sendUsbEndpoint.getUsbPipe();
        sendUsbPipe.open();

        //接收
        final UsbPipe receivedUsbPipe =  receivedUsbEndpoint.getUsbPipe();
        receivedUsbPipe.open();

        new Thread(new Runnable() {
            public void run() {
                try {
                    receivedMassge(receivedUsbPipe);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
        return sendUsbPipe;
    }

public UsbInterface linkDevice() throws Exception{

        UsbDevice device = null;
        if (device == null) {
            device = findDevice(UsbHostManager.getUsbServices()
                    .getRootUsbHub());
        }
        if (device == null) {
            System.out.println("设备未找到!");
            return null;
        }
        UsbConfiguration configuration = device.getActiveUsbConfiguration();
        UsbInterface iface = null;
        if (configuration.getUsbInterfaces().size() > 0) {
            //此处需要注意 本人在这个地方的时候是进行了debug来看设备到底在map中的key是多少
            //各位如果在此处获取不到设备请自行进行debug看map中存储的设备key到底是多少
            iface = configuration.getUsbInterface((byte) 0);
        } else {
            return null;
        }
        iface.claim(new UsbInterfacePolicy()
        {
            @Override
            public boolean forceClaim(UsbInterface usbInterface)
            {
                return true;
            }
        });
        return iface;
    }

public void receivedMassge(UsbPipe usbPipe) throws Exception{
        StringBuffer all = new StringBuffer();
        byte[] b = new byte[64];
        int length;
        while (true) {
            length = usbPipe.syncSubmit(b);//阻塞
            System.out.println("接收长度:" + length);
            for (int i = 0; i < length; i++) {
                //此处会打印所有的返回值 注意返回值全部也都是16进制的
                //比如读取卡号或者身份证号时需要自行转换回10进制
                //并进行补0操作,比如01转换为10进制会变成1需要补0 变成01
                //不然得到的10进制返回值会有问题
                System.out.print(Byte.toUnsignedInt(b[i])+" ");
                all.append(Byte.toUnsignedInt(b[i])+" ");
            }
        }
    }

public static void sendMassge(UsbPipe usbPipe,byte[] buff)  throws Exception{
        //此处为阻塞和非阻塞  非常好理解和多线程一个道理不再解释
        usbPipe.syncSubmit(buff);//阻塞
        //usbPipe.asyncSubmit(buff);//非阻塞
    }

public UsbDevice findDevice(UsbHub hub)
    {
        UsbDevice device = null;
        List list = (List) hub.getAttachedUsbDevices();
        for (int i = 0;i<list.size();i++)
        {
            device = (UsbDevice)list.get(i);
            UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
            System.out.println(i+"___"+desc.idVendor()+"___"+desc.idProduct());
            if (desc.idVendor() == idVendor && desc.idProduct() == idProduct) {return device;}
            if (device.isUsbHub()){
                device = findDevice((UsbHub) device);
                if (device != null) return device;
            }
        }
        return null;
    }
}

PID和VIP如下图: 0458为VID    003A为PID

另外还需要在resources文件夹中添加配置文件 名称为:javax.usb.properties

配置文件中内容为:

javax.usb.services = org.usb4java.javax.Services

保险起见pom中添加如下配置:

<dependency>
    <groupId>org.usb4java</groupId>
    <artifactId>usb4java-javax</artifactId>
    <version>1.2.0</version>
</dependency>
    <dependency>
        <groupId>javax.usb</groupId>
        <artifactId>usb-api</artifactId>
        <version>1.0.2</version>
    </dependency>
    <dependency>
        <groupId>javax.usb</groupId>
        <artifactId>usb-api</artifactId>
        <version>1.0.2</version>
        <classifier>sources</classifier>
    </dependency>

PS:这个java端的usb方法非常的老支持的usb2.0版本虽然现在的3.0版本也能用但是会发生插拔了之后不能使用,这方面我尝试了很久进行重连但是都失败了,所以非万不得已还是尽量不要使用这个在生产使用好一些,可以用C#来做很容易避免这样的问题java真的很不友好

在java端如果想做成插件可以使用servlet做一个启动类打一个jar包放入到jre中,之后我们在写一个bat脚本就可以实现javausb插件在windows中使用了

### 回答1: 硬件通讯协议接口是指用于实现硬件设备与Java程序之间进行通讯的一种协议接口。在Java,可以通过使用不同的协议接口来实现硬件设备之间的数据交互。 常用的硬件通讯协议接口包括串口通信USB通信、网络通信等。这些协议接口可以通过Java的相关库或者第三方库进行实现和调用。 在具体的实现过程,我们可以通过Java的串口通信库(例如RXTX)来实现硬件设备之间的数据交互。通过串口通信接口,我们可以打开、关闭串口、设置串口参数,以及读取、发送数据。通过这些操作,我们可以与串口设备(如传感器、测量仪器等)进行数据的收发和控制。 此外,JavaUSB通信库(例如javax.usb)也可以用于与支持USB接口的硬件设备进行通讯。通过USB接口,我们可以枚举、打开和关闭USB设备,读取和发送数据等操作,实现硬件设备的数据交互。 另外,通过网络通信接口,我们可以使用Java的Socket或者其他网络相关的类库,与支持网络通信硬件设备进行数据交互。特别是在物联网领域,通过网络通信接口可以实现与远程硬件设备的连接和数据交互。 综上所述,硬件通讯协议接口是实现硬件设备与Java程序之间通信的一种协议接口,通过不同的协议接口实现,我们可以与硬件设备进行数据收发和控制操作,从而实现硬件设备的交互。 ### 回答2: 在Java硬件通讯协议接口是通过Java提供的各种API和库来实现的。Java提供了多种方式来与硬件通讯协议进行交互,例如使用串口通信USB通信、以太网通信等。 在Java,可以使用JavaComm API来实现串口通信JavaComm API提供了一组类和方法,可以方便地打开、读取、写入和关闭串口。通过这些API,可以与硬件设备进行双向通信实现硬件设备的控制和数据的传输。 另外,Java也提供了一些库,如RXTX库、JSSC库等,用于处理串口通信。这些库提供了更加简单和易用的API,可以帮助开发者在Java更方便地实现串口通信。 除了串口通信Java还提供了一些其他的API和库,用于实现USB通信和以太网通信。例如,通过使用javax.usb库,可以在Java实现USB通信,通过使用java.net包的类,可以在Java实现Socket通信,与远程设备进行通信。 总之,硬件通讯协议接口在Java可以通过JavaComm API、RXTX库、JSSC库等实现。通过这些工具,开发者可以方便地与硬件设备进行通信,控制设备并传输数据。无论是串口通信USB通信还是以太网通信Java都提供了相应的工具和库来支持。 ### 回答3: 硬件通讯协议接口是指在Java编程语言用于与硬件设备进行通信的一种接口。Java作为一种跨平台的编程语言,通过硬件通讯协议接口,可以实现与不同硬件设备的交互。 Java提供了一些常见的硬件通讯协议接口,如串口通讯USB接口通讯、网络通讯等。这些接口可以帮助开发者实现Java硬件设备之间的数据传输和通讯。 例如,通过串口通讯接口,可以使用Java程序与串口设备进行数据的发送和接收,实现与串口设备的通信。开发者可以通过Java提供的串口通讯API,设置串口的参数,如波特率、数据位、停止位和校验位等,并通过读取串口的输入流和写入串口的输出流,实现与串口设备的数据交互。 与此类似,通过USB接口通讯接口,可以实现JavaUSB设备的数据传输。开发者可以利用Java提供的USB通讯API,连接到USB设备,读取和写入USB数据。 此外,Java还提供了网络通讯接口,可以实现Java程序与远程设备或其他计算机之间的数据传输。通过套接字(Socket)的方式,可以建立与其他设备的网络连接,并进行数据的发送和接收。 总之,硬件通讯协议接口使得Java程序能够与硬件设备进行通信实现数据的传输和交互。开发者可以根据具体的硬件设备和通讯协议选择合适的接口,进行相应的编程和应用开发。
评论 168
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值