Android蓝牙输入流不读取完整数组

时间:2015-12-21 11:39:06

标签: android bluetooth inputstream

我正在创建一个应用程序,通过蓝牙串口读取字符串值。我的数据收到但分为两部分。如果我通过蓝牙发送$ F00,A,B,0,M#,它只会在第一部分读取$,在下一部分读取F00,A,B,0,M#。我在这里提供了我的代码。如果我错了,请纠正我。

InputStream inputStream=null;
    int avilableBytes=0;
    public ConnectedThread(BluetoothSocket socket){
        InputStream temp=null;
        try{
            temp=socket.getInputStream();
        }catch (IOException e){
            e.printStackTrace();
        }
        inputStream=temp;
    }

    public void run() {
        try{
            int bytes;
            while (true){
                try{
                    avilableBytes=inputStream.available();
                    if (avilableBytes>0){
                        byte[] buffer=new byte[avilableBytes];
                        bytes=inputStream.read(buffer);
                        final String readMessage=new String(buffer,0,bytes);
                        bt_handler.obtainMessage(handlerState,bytes,-1,readMessage).sendToTarget();
                        Log.d("PRAVEEN",readMessage);
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

1 个答案:

答案 0 :(得分:2)

数据类似于流字节,当它带有几个字节时无法立即处理。数据不会作为单个数据包同时出现。您必须使用另一个byte []缓冲区(MainBuffer),您将逐渐保存传入的字节并在该缓冲区中移动索引。然后,不时地(例如,在每秒一次的计时器中)从主缓冲器中取出数据并对其进行处理。默认情况下,您必须使用分隔符实现一些数据框(例如,数据*数据*数据* - 许多方法做得好或坏)。我通过Xamarin在.net中处理过这个问题,但作为一个例子,它可能会有所帮助:

更新示例,格式

在ConnectedThread中:

            public override void Run()
            {
                while (true)
                {
                    try
                    {
                        int readBytes = 0;
                        lock (InternaldataReadLock)
                        {
                            readBytes = clientSocketInStream.Read(InternaldataRead, 0, InternaldataRead.Length);
                            Array.Copy(InternaldataRead, TempdataRead, readBytes);
                        }
                        if (readBytes > 0)
                        {
                            lock (dataReadLock)
                            {
                                dataRead = new byte[readBytes];
                                for (int i = 0; i < readBytes; i++)
                                {
                                    dataRead[i] = TempdataRead[i];
                                }
                            }
                            Bundle dataBundle = new Bundle();
                            dataBundle.PutByteArray("Data", dataRead);
                            Message message = btlManager.sourceHandler.ObtainMessage();
                            message.What = 1;
                            message.Data = dataBundle;
                            btlManager.sourceHandler.SendMessage(message);
                        }
                    }
                    catch (System.Exception e)
                    {
                        btlManager.btlState = BTLService.BTLState.Nothing;                        
                    }
                }
            }

在BTLHandler中:

            public override void HandleMessage(Message msg)
            {
                switch (msg.What)
                {
                    case 1:
                    {
                        byte[] data = msg.Data != null ? msg.Data.GetByteArray("Data") : new byte[0];
                        btlService.BTLReceiveData(data);
                    }
                    break;
                }
            }

        public void BTLReceiveData(byte[] data)
        {
            lock (dataReadLock)
            {
                for (int i = 0; i < data.Length; i++)
                {
                    dataRead[dataReadWriteCursor] = data[i];
                    dataReadWriteCursor++;
                }
            }
        }

在计时器中

                    int tmpWriteCursor = dataReadWriteCursor;
                    int tmpReadCursor = dataReadReadCursor;
                    lock (dataReadLock)
                    {
                        int newBytes = dataReadWriteCursor - dataReadReadCursor;
                        for (int i = 0; i < newBytes; i++)
                        {
                            dataReadMain[dataReadReadCursor] = dataRead[dataReadReadCursor++];
                        }                        
                    }


                    bool odradkovani = false;
                    string tmpRadek = "";
                    int lastLineIndex = 0;
                    List<string> list = new List<string>();
                    for (int i = LastWriteLineIndex; i < tmpWriteCursor; i++)
                    {
                        if (dataReadMain[i] >= 32 && dataReadMain[i] <= 255)
                        {
                            tmpRadek += (char)dataReadMain[i];
                        }
                        else if (dataReadMain[i] == 13) odradkovani = true;
                        else if (dataReadMain[i] == 10)
                        {
                            if (odradkovani)
                            {
                                odradkovani = false;
                                list.Add(Utils.GetFormatedDateTime(DateTime.Now) + "   " + tmpRadek);
                                tmpRadek = "";
                                lastLineIndex = i + 1;
                            }
                        }
                        else
                        {
                            tmpRadek += "?" + dataReadMain[i].ToString() + "?";
                        }
                    }
                    WriteDataToLog(list);
                    LastWriteLineIndex = lastLineIndex;