Praveen Kumar
Praveen Kumar

Reputation: 567

Android Bluetooth input stream not reading full array

I'm creating an app to read string values over Bluetooth serial port. My data receiving but in two parts. If I send $F00,A,B,0,M# via bluetooth it only reads $ in first part and F00,A,B,0,M# in next part. I provided my code here. Please do correct me if I'm wrong.

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();
        }
    }

Upvotes: 4

Views: 1283

Answers (1)

Majkl
Majkl

Reputation: 763

Data are like stream bytes and can not be processed immediately when it comes with a few bytes. Data will not come all at once as a single packet. You have to use the other byte[] buffer (MainBuffer) in which you will gradually save incoming byte and move the index in that buffer. Then, from time to time (e.g. in the timer once per second) take data from the main buffer and processed it. By default you must implement some data frame with a separator (eg. Data * data * data * - Many ways to do it good or bad). I dealt with this in .net via Xamarin, but just as an example it may be helpfull :

update example, format

In 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;                        
                    }
                }
            }

In 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++;
                }
            }
        }

In Timer :

                    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;

Upvotes: 2

Related Questions