Как разделить данные, полученные через Bluetooth в Android

Я изменил пример кода BluetoothChat для подключения к универсальному приемопередатчику Bluetooth, который я подключил к UART на плате разработки TI MSP430. Я установил связь и могу отправлять и получать одну строку и отображать значение в TextView. Ниже приведен код C, который я использую для отправки 1-3-значного значения давления, температуры 1 и температуры 2. Это довольно просто, и я работаю, как задумано.

  for(int i = 0; i <= 2; i++)     // send pressure value
  {
    UCA0TXBUF = pressureString[i];
    while(!(IFG2 & UCA0TXIFG));
  }
  for(int i = 0; i <= 2; i++)     // send temp1 value
  {
    UCA0TXBUF = tempOneString[i];
    while(!(IFG2 & UCA0TXIFG));
  }
  for(int i = 0; i <= 2; i++)     // send temp2 value
  {
    UCA0TXBUF = tempTwoString[i];
    while(!(IFG2 & UCA0TXIFG));
  }

Теперь я хочу отправить несколько фрагментов данных на устройство Android и отобразить их в соответствии с их типом данных в отдельном TextView для каждого значения. На данный момент я измеряю два датчика температуры и датчик давления. Я без проблем отправил все данные на устройство Android, но все значения просто перезаписывают друг друга в TextView, так что отображается только последняя отправленная строка.

Это часть кода, которая запускается при подключении к удаленному устройству:

/**
 * This thread runs during a connection with a remote device.
 * It handles all incoming and outgoing transmissions.
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "create ConnectedThread");
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the BluetoothSocket input and output streams
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) {
            Log.e(TAG, "temp sockets not created", e);
        }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];
        int bytes;

        // Keep listening to the InputStream while connected
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);

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

Это код, который читает сообщение и отображает его в TextView:

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);
                mTextView.setText(readMessage);                         //added by AMJ in attempt to display variable in textview
                break;

Кажется, я не могу понять, как запрограммировать приложение для Android, чтобы иметь возможность определять разницу между строками, чтобы, когда я получаю строку Temp1, она переходила в Temp1TextView, а строка Temp2 — в Temp2TextView и т. д. Должен ли я добавить специальный символ в качестве первого бита, отправленного с MSP430, и указать ссылку на этот бит в Android, чтобы определить, куда он должен идти? Просто мысль.

Любая помощь очень ценится.

EDIT: я решил, что могу попытаться преобразовать int в строку, затем использовать токенизатор, чтобы разделить его, а затем преобразовать обратно в int. Однако теперь приложение вылетает при получении данных по bluetooth. Вот код, который я использую для его преобразования. Любая идея, почему это может привести к сбою?

bytes = mmInStream.read(buffer);

                byteString = String.valueOf(bytes);

                StringTokenizer tokens = new StringTokenizer(byteString, ":");
                String first = tokens.nextToken();      // this will contain exhaust temp
                String second = tokens.nextToken();     // this will contain damper position

                separatebytes1 = Integer.valueOf(first);
                    separatebytes2 = Integer.valueOf(second);

                // Read from the InputStream
              //  bytes = mmInStream.read(buffer);

                // Send the obtained bytes to the UI Activity
           //     mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)
           //             .sendToTarget();

                mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, separatebytes1, -1, buffer)
                .sendToTarget();

Это логарифм после аварии:

W/dalvikvm(24850): threadid=11: thread exiting with uncaught exception (group=0x
411ae300)
E/AndroidRuntime(24850): FATAL EXCEPTION: Thread-1286
E/AndroidRuntime(24850): java.util.NoSuchElementException
E/AndroidRuntime(24850):        at java.util.StringTokenizer.nextToken(StringTok
enizer.java:208)
E/AndroidRuntime(24850):        at com.example.android.BluetoothChat.BluetoothCh
atService$ConnectedThread.run(BluetoothChatService.java:411)
W/ActivityManager(  270):   Force finishing activity com.example.android.Bluetoo
thChat/.BluetoothChat

person Alex Trebek    schedule 05.03.2013    source источник
comment
Добро пожаловать в СО. В общем, полезно включать фрагменты кода в свой вопрос, поскольку это помогает изолировать проблемы и даже может облегчить понимание вашего вопроса. Попробуйте отформатировать свой вопрос, где это возможно, используя блоки кода, акцентирование текста на важных примечаниях и т. д.   -  person pestrella    schedule 05.03.2013
comment
Спасибо за совет. Я добавил части кода, которые, по моему мнению, имеют отношение к вопросу. Я старался держать его в разумных пределах и не добавлять слишком много.   -  person Alex Trebek    schedule 05.03.2013
comment
@AlexTrebek Пожалуйста, опубликуйте исключение, которое также отображается при сбое. Подсказка: я трачу на это неоплаченное время. ;)   -  person class stacker    schedule 06.03.2013
comment
@ClassStacker Исключение было опубликовано. Это из логкэта. Я еще не занимался отладкой с Android, но я считаю, что это важная информация. Еще раз спасибо.   -  person Alex Trebek    schedule 06.03.2013
comment
@AlexTrebek Как видно из документации StringTokenizer, это исключение выдается, например. на nextToken(), что означает, что в вашей строке нет трех токенов. Как насчет сообщения журнала здесь и там и особенно вывода полученной строки байтов в журнал?   -  person class stacker    schedule 06.03.2013
comment
@ClassStacker Я положу туда несколько сообщений журнала и попытаюсь разобраться. Спасибо, что нашли время помочь n00b.   -  person Alex Trebek    schedule 06.03.2013


Ответы (2)


У вас либо есть одно сообщение с несколькими значениями в заранее определенном порядке, либо вам придется сообщить получателю (приложению), какое значение будет отправлено дальше, более или менее так, как вы предложили.

person class stacker    schedule 05.03.2013
comment
Спасибо за быстрый ответ. В идеале MSP430 не будет постоянно отправлять один и тот же код. Сейчас данные о температуре отправляются каждые 30 секунд, а о давлении только при его изменении. Я могу изменить код C, чтобы обновить все одновременно, тогда я смогу заранее определить порядок, но было бы наиболее полезно, если бы я мог отправить какой-то идентификатор, предшествующий самим данным, чтобы приложение знало где разместить. - person Alex Trebek; 05.03.2013
comment
Как вы предложили, я пытаюсь отправить одно сообщение, разделенное : , а затем используя токенизатор, чтобы разделить его на двоеточие. Но сейчас я разбиваюсь. Я разместил код выше. Любая идея, что может быть причиной аварии? Спасибо. - person Alex Trebek; 06.03.2013

Сбой (относительно вашего отредактированного вопроса), вероятно, происходит из-за того, что byteString не содержит «:». Если это так, ваш String second = tokens.nextToken() выдаст именно то фатальное исключение, которое вы разместили.

Итак, прежде чем разделить строку с помощью tokens.nextToken(), проверьте, сколько токенов находится в байтовой строке с помощью: tokens.countTokens

person julthedroid    schedule 11.03.2013
comment
Спасибо, что в основном повторили то, что я уже написал в комментарии. ;) - person class stacker; 11.03.2013
comment
о, я совсем забыл посмотреть, есть ли комментарии, я просто посмотрел на один ответ, а комментарии ниже ответа, а не вопроса, в следующий раз уделю больше внимания ... - person julthedroid; 11.03.2013