Bluetooth SPP может получить потерянный пакет или - PullRequest
4 голосов
/ 14 февраля 2012

Я использую пример кода Android для изменения.Только хочу получить пакет, но мой код только изменить здесь

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothChatService.STATE_CONNECTED:
                mTitle.setText(R.string.title_connected_to);
                mTitle.append(mConnectedDeviceName);
                mConversationArrayAdapter.clear();
                break;
            case BluetoothChatService.STATE_CONNECTING:
                mTitle.setText(R.string.title_connecting);
                break;
            case BluetoothChatService.STATE_LISTEN:
            case BluetoothChatService.STATE_NONE:
                mTitle.setText(R.string.title_not_connected);
                break;
            }
            break;
        case MESSAGE_WRITE:
            byte[] writeBuf = (byte[]) msg.obj;
            // construct a string from the buffer
            String writeMessage = new String(writeBuf);
            mConversationArrayAdapter.add(writeMessage);
            break;
        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);
            //String readMessage = BytesTrans_fill.bytesToHexString(readBuf);
            Log.d("read", BytesTrans.bytes2HexString(readBuf,msg.arg1));
            String readMessage = BytesTrans.bytes2HexString(readBuf,msg.arg1);
            ppV.setText(ppV.getText().toString() + readMessage + "★");
            break;
        case MESSAGE_DEVICE_NAME:
            // save the connected device's name
            mConnectedDeviceName = msg.getData().getString(
                    DEVICE_NAME);
            Toast.makeText(getApplicationContext(), "Connected to "
                           + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
            break;
        case MESSAGE_TOAST:
            Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
                           Toast.LENGTH_SHORT).show();
            break;
        }
    }
};

и BluetoothChatService

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

и добавить эту функцию

package com.example.android.BluetoothChat;

public class BytesTrans {
    public static String byte2HexString(byte b) {
        String ret = "";
            String hex = Integer.toHexString(b & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase()  + " ";
        return ret;
    }

    public static String bytes2HexString(byte[] b, int count) {
        String ret = "";
        for (int i = 0; i < count; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex.toUpperCase() + " ";
        }
        return ret;
    }
    /*public static String String2byte(String b)
    {
        String[] ttt;
        for (int i = 0; i < b.length(); i++)
        {
            for (int j= i; j<=i+1; j++)
            {
                ttt[i] = b;
            }

        }           

        String ttmp = "";
        String tmp = "";





        ret += tmp;
    }*/
    public static int hexToTen(String b) {
        int D2 = Integer.parseInt(b,16);


        return D2;
        }
    }

но эту программу, чтобы показатьиногда даже не в кадр моего посылаю пакет в

1011 * я посылаю пакет, как это: 1013 * aa07210820001202140934390000000000000000000000000000000000000000000297c0fe6b 1015 *, но когда-нибудь получить пакет: 1017 * aa000297c0fe6b02131452470000000000000000000000000000000000000000000297c0fe6b 1019* как я могу изменить свой код, чтобы получить полный кадр пакета

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Вы не указали код вашего интерфейса Bluetooth. Однако, если это в значительной степени основано на примере BluetoothChat, то существует простая проблема с примером BluetoothChat в его нынешнем виде: в основном, когда read() сделан из гнезда Bluetooth и помещен в байтовый массив, эта ссылка на массив отправлено в пользовательский интерфейс, используя Handler, как вы делаете. Фактическая проблема заключается в том, что если пример BluetoothChat используется для получения данных со скоростью, превышающей скорость набора, вы начинаете видеть пропажу или перепутывание символов, потому что последующий read() перезаписывает массив, в то время как пользовательский интерфейс все еще чтение массива, чтобы извлечь последнюю группу символов, полученных.

Итак, если ваш MESSAGE_WRITE объект содержит ссылку на массив, в который вы делаете сокет, в который read() обращается, то, возможно, именно поэтому вы теряете символы. Поэтому попробуйте отправить копию массива, используя Arrays.copyOf(), в Message. Или, возможно, есть круговая буферная схема, которую вы могли бы использовать.

У меня была именно эта проблема, когда я использовал пример BluetoothChat в качестве основы для своего проекта. Что я лично сделал, чтобы обойти эту проблему (и устранить необходимость в копировании буферов и т. Д.), Так это реализовать механизм, посредством которого я сообщал бы поток соединения Bluetooth (поток, содержащий сокет блокировки .read()), с помощью от вызова метода, сколько байтов я ожидаю, что ответ будет (к счастью, протокол, с которым я имею дело, позволяет знать длину ответа). Затем поток соединения отправляет Message только после получения полного ответа, вместо отправки нескольких Message с фрагментами ответа в пользовательский интерфейс.

0 голосов
/ 01 октября 2015

Вот мое решение, используя пример кода Android-чата. Это только возможное решение. Я получаю сообщения, оканчивающиеся на \n. Я использую эту ветку для чтения сообщений от Arduino, подключенного по Bluetooth. На Arduino я могу убедиться, что каждое сообщение заканчивается на \n, используя Serial.println( buffer );.

Все, что я получил, добавляется к существующей строке (queue переменная). Когда у меня есть целая строка в этой большой строке, я отправляю ее в действие и удаляю ее из переменной queue.

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = new byte[1024];
        int bytes, pos;
        StringBuilder queue = new StringBuilder("");
        String temp;
        // Keep listening to the InputStream while connected
        while (true) {
            try {
                bytes = mmInStream.read(buffer);
                if (bytes > 0) {
                    String readMessage = new String(buffer, 0, bytes);
                    queue.append(readMessage);
                    pos = queue.indexOf("\n");
                    while (pos >= 0) {
                        // Log.d("Temperatura", "indexOf() #" + pos);
                        temp = queue.substring(0, pos - 1);
                        queue.delete(0, pos + 1);
                        mHandler.obtainMessage(Constants.MESSAGE_READ, 0, 0, temp).sendToTarget();
                        pos = queue.indexOf("\n");
                    }
                }
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                // Start the service over to restart listening mode
                BluetoothChatService.this.start();
                break;
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...