Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从Android USB附件读取数据的更好方法_Java_Android_Usb_Accessory - Fatal编程技术网

Java 从Android USB附件读取数据的更好方法

Java 从Android USB附件读取数据的更好方法,java,android,usb,accessory,Java,Android,Usb,Accessory,我正在用Java编写一个Android应用程序,它使用Android附件API与USB附件进行通信 未给出实际读取和写入数据的示例,仅给出如何打开附件进行通信 它还陈述了两件事: 通信应该在后台线程中完成,而不是在UI线程上 读取缓冲区的长度应至少为16384字节,因为这是安卓开放附件协议的最大消息长度 我是这样读的: /** boiler plate from example docs: **/ fileDescriptor = usbManager.openAccessory(accesso

我正在用Java编写一个Android应用程序,它使用Android附件API与USB附件进行通信

未给出实际读取和写入数据的示例,仅给出如何打开附件进行通信

它还陈述了两件事:

  • 通信应该在后台线程中完成,而不是在UI线程上
  • 读取缓冲区的长度应至少为16384字节,因为这是安卓开放附件协议的最大消息长度
  • 我是这样读的:

    /** boiler plate from example docs: **/
    fileDescriptor = usbManager.openAccessory(accessory);
    
    if (fileDescriptor != null) {
        FileDescriptor fd = fileDescriptor.getFileDescriptor();
        inputStream = new FileInputStream(fd);
        readBuffer = new byte[16384];
        // ... some more code that is not relevant for reading data ... //
    }
    
    /** my code in separate thread: **/
    
    int read;
    
    while ((read = inputStream.read(readBuffer)) >= 0) {
        // ... parse message and do stuff with it ... //
    }
    
    这段代码有效,我从附件中获得了正确的数据,但它给我的应用程序逻辑带来了问题:

  • read函数可以无限期地阻塞以等待更多数据
  • 它有时会在缓冲区中背靠背返回多条消息,因此我不知道它何时或如何决定附件发送完毕,并应返回累积字节
  • 我还需要向附件发送数据,但从两个单独的线程读取和写入USB会导致错误
  • 我无法控制附件上运行的代码,它是一个封闭的产品,但我知道它的协议:它发送以2字节为前缀的消息,指示消息的大小

    所以,我试着:

    read = inputStream.read(readBuffer, 0, 2);
    
    if (read == 2) {
        int size = (readBuffer[0] & 0xff) + ((readBuffer[1] & 0xff) << 8);
        read = inputStream.read(readBuffer, 2, size);
    }
    
    read=inputStream.read(readBuffer,0,2);
    如果(读==2){
    
    int size=(readBuffer[0]&0xff)+(readBuffer[1]&0xff)您无法从同一
    InputStream
    中读取两次,因此第二次调用时出现错误。请将其放入
    BufferedInputStream
    中,或者找到重置流的方法(或者完全加载流,但我猜这不是您想要做的)@Fullslack.dev什么意思?我不能读取两次?为什么不能?你有文档参考吗?在循环中读取代码时,在流上没有其他操作,只要我为每次读取提供足够大的缓冲区。我无法重新加载此流,因为它由硬件设备(USB)支持,而不是磁盘上的文件。重置或重新加载它意味着关闭并重新打开USB连接,这是不可能的。下面是一些例子。我知道循环读取是有效的,但是在读取流大小的前2个字节后,您也提到了一个错误。这基本上是读取
    InputStream
    两次。您可以尝试将第二次读取更改为同样从0开始,在-2结束,但是我不太喜欢这种方法,因为如果输入发生更改,它可能会导致错误。@Fullslack.dev我现在明白你的意思了,但我想你误解了我的代码:我不再尝试读取相同的字节。在你链接的示例中,他们试图在不重置流的情况下重新读取数据,这将导致错误显然失败了,但我正在尝试在一个读取操作中读取部分可用数据,然后在另一个操作中读取其余尚未读取的数据。如果此流指向常规文件,则该操作将非常有效。@Fullslack.dev(第2部分,注释太长):请注意,第二次读取中的offset参数指定要将结果放入字节缓冲区中的何处,而不是要读取的流中的何处。感谢您的帮助,但我的问题似乎在别处。