Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/199.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/119.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
Android上蓝牙从InputStream读取数据时出错_Android_Bluetooth_Inputstream - Fatal编程技术网

Android上蓝牙从InputStream读取数据时出错

Android上蓝牙从InputStream读取数据时出错,android,bluetooth,inputstream,Android,Bluetooth,Inputstream,我正在开发一个Android应用程序,它使用蓝牙连接在我的Android智能手机和非Android蓝牙模块之间传输数据,使用SPP配置文件。我使用了Android开发者网站上的蓝牙聊天示例作为参考 我已经成功地使两个设备相互连接,并将简单的字符串从智能手机发送到蓝牙模块。但是我在读取模块返回的数据时出错了。我使用了以下代码,与蓝牙聊天示例中的代码完全相同,用于从InputStream读取数据 while (true) { try { // Read from the In

我正在开发一个Android应用程序,它使用蓝牙连接在我的Android智能手机和非Android蓝牙模块之间传输数据,使用SPP配置文件。我使用了Android开发者网站上的蓝牙聊天示例作为参考

我已经成功地使两个设备相互连接,并将简单的字符串从智能手机发送到蓝牙模块。但是我在读取模块返回的数据时出错了。我使用了以下代码,与蓝牙聊天示例中的代码完全相同,用于从InputStream读取数据

while (true) {
    try {
        // Read from the InputStream
        bytes = mmInStream.read(buffer);
        String str = new String(buffer);
        Log.i(TAG, "mmInStream - " + str);
        // Send the obtained bytes to the UI Activity
        mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
                .sendToTarget();
    } catch (IOException e) {
        Log.e(TAG, "disconnected", e);
        connectionLost();
        break;
    }
}
当我的蓝牙模块向手机发送一个简单的字符串时,该字符串未被正确接收。它以随机的方式被分成几个部分。例如,如果我向手机发送“1234567890abcdef1234567890abcdef0123456789”三次,Eclipse上的Logcat将记录以下内容:

mmInstream - 12345678910abcdef��������(continuing null)
mmInstream - 1��������(continuing null)
mmInstream - 2345678910abcdef0123456789��������(continuing null)
这是第一次。在第二次和第三次发送数据时,以不同的方式接收数据:

mmInstream - 1234567891�������(continuing null)
mmInstream - 0abcdef012�������(continuing null)
mmInstream - 3456789���������(continuing null)

mmInstream - 1234567891����������������(continuing null)
mmInstream - 0abcdef0123456789������������(continuing null)
我不知道为什么会发生这种情况以及如何解决这个问题。如果数据是以这样的任意方式接收的,我就无法获得必要的数据进行处理。我怎样才能把它一件一件地拿出来

任何帮助都将不胜感激


非常感谢。

我注意到您的代码有两件事:

  • 首先,向你的应用程序发送一个对你读取的缓冲区的引用并不总是一个好的解决方案:如果在此期间缓冲区被覆盖了呢? 您可以通过复制从蓝牙读取的数据(例如使用buffer.clone())来绕过此问题,或者如果您不喜欢使用太多内存,可以将读取缓冲区设置为循环缓冲区

  • 您应该能够重新编译数据,即使它是在单独的数据包中接收的(但数据包是在短时间内接收的)。例如,您可以设置开始/停止标志。Ofc它仍然取决于通过蓝牙发送的对象类型

如果前面的两个警告无效,现在可能的解决方案是:

与调用.read(阻塞调用)的无限循环不同,您可以执行以下操作:

while(true) {
     if mmInStream.getAvailable()>0 { 
          -your read code here-
     }
     else SystemClock.sleep(100);
}
这是一种黑客行为,有时它可能仍然只阅读信息的一部分,但这将是非常罕见的


如果有用,请投票支持/更正

拉杜的修复效果非常好!。我自己已经在这个问题上工作了相当长的一段时间,现在使用蓝牙聊天示例代码。下面是我用来捕获和显示遥感器温度读数的内容:

  // Keep listening to the InputStream while connected
        while (true) {

             try {
                 byte[] buffer = new byte[128];
                 String readMessage;
                 int bytes;
                if (mmInStream.available()>2) { 
                    try {
                       // Read from the InputStream
                        bytes = mmInStream.read(buffer); 
                        readMessage = new String(buffer, 0, bytes);

                       }catch (IOException e) {
                        Log.e(TAG, "disconnected", e);
                        break;
                    }
                     // Send the obtained bytes to the UI Activity
                     mHandler.obtainMessage(HomeBlueRemote.MESSAGE_READ, bytes, -1, readMessage)
                          .sendToTarget();
        }
        else {
            SystemClock.sleep(100);
               }
            } catch (IOException e) {

                e.printStackTrace();
            }

       }

    }

如您所见,我将(buffer.available()>0)修改为>2。这是因为my micro controller正在发送2个字节的温度。在此之前,字节计数的inputstream会有所不同,有时只捕获1个字节,这会扰乱Android应用程序中的温度显示读数。再一次,在网络上的所有建议中,Radu为android inputstream bug提供了最好的解决方法。

我有一个问题,我已经解决了这个问题� 这样

public void run() {        
    int bytes; // bytes returned from read()
    int availableBytes = 0;        
    // Keep listening to the InputStream until an exception occurs
    while (needRun) {
        try {
            availableBytes = mmInStream.available();
            if(availableBytes > 0){
                byte[] buffer = new byte[availableBytes];  // buffer store for the stream
                // Read from the InputStream


                bytes = mmInStream.read(buffer);
                Log.d("mmInStream.read(buffer);", new String(buffer));
                if( bytes > 0 ){                        
                    // Send the obtained bytes to the UI activity
                    mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();                     
                }                                   
            }
        } catch (IOException e) {
            Log.d("Error reading", e.getMessage());
            e.printStackTrace();
            break;
        }
    }
}
试试这个:

public void run() {
        byte[] buffer;
        ArrayList<Integer> arr_byte = new ArrayList<Integer>();
        while (true) {
            try {
                int data = mmInStream.read();
                if(mmInStream.available()>0) {
                    arr_byte.add(data);
                } else {
                    arr_byte.add(data);
                    buffer = new byte[arr_byte.size()];
                    for(int i = 0 ; i < arr_byte.size() ; i++) {
                        buffer[i] = arr_byte.get(i).byteValue();
                    }
                    Log.e("INPUT",new String(buffer));
                    mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                            .sendToTarget();
                    arr_byte = new ArrayList<Integer>();
                }
            } catch (IOException e) {
                break;
            }
        }
    }
public void run(){
字节[]缓冲区;
ArrayList arr_byte=新的ArrayList();
while(true){
试一试{
int data=mmInStream.read();
如果(mmInStream.available()>0){
arr_byte.add(数据);
}否则{
arr_byte.add(数据);
缓冲区=新字节[arr_byte.size()];
对于(int i=0;i
我也有这个问题。现在一切正常。没有� 字符。

我找到了

您必须重置缓冲区:

buffer = new byte [1024];
在此之前:

bytes = mmInStream.read(buffer); 

至少它对我有效,而且不需要睡眠命令。

我认为有很多好的答案。我的贡献是在每个数字进入蓝牙输入流时一次处理一个数字,如下所示。这样做的价值在于确保每一组数据的长度都是一个值(作为字符串),通过将每个新值(包含在主活动处理程序的readMessage字符串中)放入一个列表中,可以非常轻松地对其进行处理。这样,您就可以使用List(String)(编辑器不允许我使用的)对象通过提取via将数据处理回实数

Integer.valueOf(此处传递的列表(字符串)对象)

//连接时继续收听InputStream while(true){


我的方法:我在MainActivity中构建一个id为txtReceive的textView

@Override
public void run() {
    byte[] buffer=new byte[1024];
    int bytes;
    while(true) {
        try {
            bytes = inputStream.read(buffer);
            final String strReceived = new String(buffer, 0, bytes);
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    txtReceive.append(strReceived);
                }
            });
        } catch (Exception e) {
            Log.d(TAG, "loi ");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    txtReceive.setText("Error");
                }
            });
        }
    }
}

我使用了最后两个代码,它们工作得很好,但当连接丢失时,用户界面不会收到通知,因此状态不会更改为“无”。在我的情况下,我希望应用程序在连接丢失时尝试重新连接最后一个设备!!在尝试了多种方法后,我最终通过以下方式解决了问题:

  • 我创建了一个结束字符,这个字符我知道我永远不会使用,但只是在我发送的字符串的末尾。“”是我的字符串结束字符
  • 我创建了一个临时字符串tmp_msg
  • 每次接收到流时,都会从该流中创建第二个临时字符串“readMessage”
  • 在“readMessage”中搜索结束字符(“.”)
  • 如果未检测到结束字符,“readMessage”与tmp_msg关联。因此,当第一次、第二次和第三次未接收到结束字符时,tmp_msg=readMessage1+readMessage2+readMessage3
  • 当检测到结束字符“.”时,tmp_msg与最后一条readMessage关联,并由此构造字节“缓冲区”
  • 然后将“缓冲区”发送到
    @Override
    public void run() {
        byte[] buffer=new byte[1024];
        int bytes;
        while(true) {
            try {
                bytes = inputStream.read(buffer);
                final String strReceived = new String(buffer, 0, bytes);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        txtReceive.append(strReceived);
                    }
                });
            } catch (Exception e) {
                Log.d(TAG, "loi ");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        txtReceive.setText("Error");
                    }
                });
            }
        }
    }
    
    public void run() { 
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];
        int bytes;
        // Keep listening to the InputStream while connected
        String tmp_msg =""; 
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                String readMessage = new String(buffer, 0,bytes);
                if (readMessage.contains(".")){
                    tmp_msg+=readMessage;
                    byte[] buffer1 = tmp_msg.getBytes();
                    int bytes1=buffer1.length;
                    tmp_msg="";
                    // Send the obtained bytes to the UI Activity
                    mHandler.obtainMessage(BluetoothChat.MESSAGE_READ,bytes1,-1,buffer1).sendToTarget();
                }else{
                    tmp_msg+=readMessage;
                }
            } catch (IOException e) {
            //  Log.e(TAG, "disconnected", e);
                connectionLost();
                // Start the service over to restart listening mode
                BluetoothChatService.this.start();
                break;
            }
        }
    }
    
      public void run() {
            Log.i(TAG, "BEGIN mConnectedThread");
            byte[] buffer = new byte[1024];
            byte[] bufferRX = new byte[1024];
            int bytes;
    
            // Keep listening to the InputStream while connected
            while (mState == STATE_CONNECTED) {
                try {
                    // Read from the InputStream
                    bytes = mmInStream.read(buffer);
                    bufferRX = buffer.clone();
                    
                    // Send the obtained bytes to the UI Activity
                    mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, bufferRX)
                            .sendToTarget();
                } catch (IOException e) {
                    Log.e(TAG, "disconnected", e);
                    connectionLost();
                    break;
                }
            }
        }