Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.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 如何通过蓝牙同时读取所有字节?_Java_Android_Stream_Bluetooth_Bytearray - Fatal编程技术网

Java 如何通过蓝牙同时读取所有字节?

Java 如何通过蓝牙同时读取所有字节?,java,android,stream,bluetooth,bytearray,Java,Android,Stream,Bluetooth,Bytearray,我有一个应用程序,它使用蓝牙从其他设备接收一些数据(字节)。一切都进行得很顺利,但我有一个小问题,接收字节一起。在收到字节后,我在祝酒词上显示它们只是为了测试它们。当另一个设备同时发送10个字节时(例如:“ABCDEFGHIJ”),程序将只获取第一个字节“A”并在Toast上显示,然后转到第二次迭代并读取其他9个字节并在Toast上显示“BCDEFGHIJ”。这是我的密码: byte[] buffer = new byte[1024]; // Read 1K character at a tim

我有一个应用程序,它使用蓝牙从其他设备接收一些数据(字节)。一切都进行得很顺利,但我有一个小问题,接收字节一起。在收到字节后,我在祝酒词上显示它们只是为了测试它们。当另一个设备同时发送10个字节时(例如:“ABCDEFGHIJ”),程序将只获取第一个字节“A”并在Toast上显示,然后转到第二次迭代并读取其他9个字节并在Toast上显示“BCDEFGHIJ”。这是我的密码:

byte[] buffer = new byte[1024]; // Read 1K character at a time.
int bytes = 0; // Number of bytes.

while(true)
{
    try
    {
        // Read from the InputStream.
        bytes = bInStream.read(buffer);

        // Send the obtained bytes to the MainActivity.
        mainActivityHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
    }
    catch(IOException e)
    {
        connectionLost();
        break;
    }
}
在主要活动中,我有:

// The Handler that gets information back from the BluetoothManager.
private final Handler handler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        switch(msg.what)
        {
            case MESSAGE_READ:
                byte[] readBuf = (byte[]) msg.obj;

                // construct a string from the valid bytes in the buffer.
                String readMessage = new String(readBuf, 0, msg.arg1);
                Toast.makeText(MainActivity.this, readMessage, Toast.LENGTH_SHORT).show();
                break;

            // ...
        }
    }
};

我怎样才能同时接收所有字节

嗯,最有可能的罪魁祸首是你发送信息的方式。您的receive没有问题,它将接收写入的字节数(最多1024个)

如果您无法控制消息的发送方式,则可以一次读取一个字节,然后在点击预定义的终止符时向您发送处理程序消息。例如:“ABCDEFGHIJ#”其中#是终结者

String msg = "";
byte ch;
while((ch=mInStream.read())!='#') {
    bytes++;
    msg+=ch;
}

蓝牙连接是基于流的,而不是基于数据包的。无法保证或试图保持包装化。因此,任何数量的写入都可能导致任何数量的读取,只需保证字节流是正确的。如果需要检测数据包,则需要提供自己的数据包结构来包装数据。例如,在每个数据包之前添加一个长度字段,以便您可以在接收端重建。

处理长于缓冲区的消息的一种方法(可能很危险,因为如果从未清除,可能会占用您的内存)是分块处理它们:

String inString = "";
byte[] buffer = new byte[1024];  // buffer store for the stream
int bytes; // bytes returned from read()

while (true) {
    try {
        bytes = mmInStream.read(buffer);
        String chunk = new String(buffer, 0, bytes);
        if(chunk.contains(";"))
        {
            inString += chunk.substring(0,chunk.indexOf(';'));
            Message msg = new Message();
            msg.obj  = inString;
            handler.sendMessage(msg);
            inString =  chunk.substring(chunk.indexOf(';'));
        }
        else
        {
            inString += chunk;
        }
    } catch (IOException e) {
        break;
    }
}

来自@fouldy的公认答案是正确的。但是,如果数据本身包含“#”,则可能很难获取数据。因此,根据我的说法,最好的方法是在向Android应用程序发送数据的设备中添加“\n”,后跟“\r”(或任何其他不可能作为数据的字符)。它只是作为换行符并标记数据的结束

例如:ABCDEFGH\n\r\n

那么您的代码可以是这样的:

byte[] buffer = new byte[1024];
 while (true) {

         // Read from the InputStream
          buffer[bytes] = (byte) mmInStream.read();                 
         // Send the obtained bytes to the UI Activity
 if ((buffer[bytes] == '\n')||(buffer[bytes]=='\r'))
 {
   mHandler.obtainMessage(MainActivity.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
   bytes=0;
 }
 else
 bytes++;
}
希望能有帮助
关于

要一起读取所有字节,您需要在代码中用“\n”或“\r”或“\r\n”分隔数据

例如:如果您想通过蓝牙将数据从Arduino发送到Android应用程序:

(Arduino代码):

下面是:(在onCreate()方法中):


以上所有答案对我都不起作用。Thread.sleep(1000)为我提供了解决方案

我可以看看你是如何发送消息的吗?你是在做类似bOutStream.write(“ABCDEFGHIJ.getBytes())的事情,还是在一次只写一个字符?arduino上连接了一个蓝牙模块,所以我使用arduino软件的串行监视器来发送消息。+1很好的解决方案。我将使用此解决方案,直到找到另一种解决问题的方法。谢谢如果我传输二进制数据呢?如何确保终止符不是数据流的一部分?代码假定为“;”是消息分隔符。该代码是一个示例实现,并且不是通用的-您不能复制粘贴它并期望在不进行修改的情况下工作,但它背后显示了一个概念。它读取所有信息。到达消息结尾后,handler.sendMessage(msg);调用以处理完整消息,并继续处理缓冲区。您必须实现处理程序来处理/读取消息。这就是问题所在concept@TJD那么我如何知道长度字段的长度呢?@TJD您是否有任何证据/文档证明Android无法保留数据包化,或重新形成数据包本身?只是问一下,在我目前正在开发的一个应用程序中,它有时会,有时不会,所以只是想找出原因!明亮的这解决了我的问题,没有在Arduino端添加额外的
字符。我只是跳过了检查
\r
(我只检查
\n
),它就像一个符咒。
    int count =0;
    int sensorPin = 0;

    void setup()
    {
      Serial.begin(9600);
    }

    void loop()
    {
    int val= analogRead(sensorPin);
      if(val<threshold){ 
         a++; 
      }
      else{
        delay(2);
        count = count + 1;
        Serial.print(count);
        Serial.print("\n");
          }
 private class ConnectedThread extends Thread {
        private final InputStream mmInStream;

        public ConnectedThread(BluetoothSocket socket) {
            InputStream tmpIn = null;

            // Get the input streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream(); // opens the input stream in order to retrieve InputStream objects
            } catch (IOException e) {
            }

            mmInStream = tmpIn;
        }

     public void run() {
        int bytes; // bytes returned from read()
        int availableBytes = 0;

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                availableBytes = mmInStream.available();
                if(availableBytes>0){
                    byte[] buffer = new byte[availableBytes];  // buffer store for the stream
                    // Read from InputStream
                    bytes = mmInStream.read(buffer); // Get number of bytes and message in "buffer"
                    if (bytes>0){
                        h.obtainMessage(RECEIVE_MESSAGE, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
                    }
                   }
                } catch (IOException e) {
                break;
                        }
        }
    }
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
// The Handler that gets information back
 h = new Handler() { // Handler-->used to communicate b/w UI & BG Thread
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case RECEIVE_MESSAGE:// if receive message
                        byte[] readBuf = (byte[]) msg.obj;
                       String strIncom = new String(readBuf, 0, msg.arg1); // create string from bytes array

                        sb.append(strIncom);                                                // append string
                        int endOfLineIndex = sb.indexOf("\n");                            // determine the end-of-line
                        if (endOfLineIndex > 0) {                                            // if end-of-line,
                            String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                            sb.delete(0, sb.length());// and clear
                            Toast.makeText(ledControl.this,sbprint,Toast.LENGTH_SHORT).show();
                            footSteps.setText(sbprint);            // update TextView
                        }
                        break;
                }}};