Как сбросить последовательную связь в виде файла через Android Bluetooth serial RFCOMM

Мое приложение для Android получает последовательную связь через Bluetooth от настольного приложения. Я не могу контролировать то, что делает это настольное приложение.

Использование примера кода Google BluetoothChat (https://github.com/googlesamples/android-BluetoothChat) . Мне удается заставить его работать, и в какой-то степени я могу просто взять байты, поступающие в мое приложение для Android, и записать файл.

Однако функция кода выглядит примерно так

1 - Android слушать

2 - ПК отправляет данные, Android принимает данные о соединении, читает данные и записывает в файл

3 - Во время чтения Android сталкивается с исключением (клиент закрывает соединение?) и закрывает соединение

4 - Вернуться к одному и слушать следующие несколько байтов

Моя проблема в том, что мне нужно знать, когда этот процесс заканчивается, чтобы обработать файл и отобразить результат в пользовательском интерфейсе.

Код это один файл

https://github.com/googlesamples/android-BluetoothChat/blob/master/Application/src/main/java/com/example/android/bluetoothchat/BluetoothChatService.java

Конкретно

    public void run() {
        Log.i(TAG, "BEGIN mConnectedThread");
        byte[] buffer = 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);

                // ==> This is where I wrote to file
                // ==> Standard Android Java code to write 
                // ==> to output file stream

                // Send the obtained bytes to the UI Activity
                // ==> Commented out because this can not be done here
                // ==> NEED TO BE DONE WHEN ALL DATA IS READ
                // mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
                //      .sendToTarget();
            } catch (IOException e) {
                Log.e(TAG, "disconnected", e);
                connectionLost();
                break;
            }
        }
    }

Ожидается, что в Android RFCOMM или связи Bluetooth должен быть способ обозначить, что клиент уже завершил отправку всех сообщений.

Раньше я пытался использовать IoException как место, чтобы сообщить пользовательскому интерфейсу, что чтение данных с ПК завершено. Это катастрофа, потому что по какой-то причине исключение происходит только в начале связи. И я понятия не имею, почему мои коды продолжают записывать в файл помимо этого.

Я собираюсь повторить, что у меня нет никакого контроля над приложением для ПК/рабочего стола. Поэтому, пожалуйста, не предлагайте ничего, что связано с изменением работы настольного приложения или отправки данных.

Нужно обрабатывать это на стороне Android.


person Haris Hashim    schedule 26.03.2019    source источник


Ответы (1)


Вы никогда не можете быть уверены, что дальний конец завершил отправку данных, которые он хотел отправить, если только у вас нет правил и/или какого-либо протокола и вы не начнете анализировать полученные данные на своей стороне.

Добавьте/создайте простой протокол с заголовком и полем длины, которые позволят вам получать и, более того, знать, чего ожидать в вашем цикле приема.

Как правило большого пальца; никогда не думайте, что вы получите весь пакет за одно чтение. Вместо этого буферизируйте полученные данные и разрешите многократное чтение, прежде чем вы в конечном итоге сможете их обработать и извлечь полные «пакеты», соответствующие вашей спецификации.

person Markus Millfjord    schedule 26.03.2019
comment
К сожалению, я не контролирую это. Согласно моему предыдущему вопросу. У меня нет никакого контроля над приложением для ПК / рабочего стола. Но ваш ответ великолепен, поскольку он заставляет меня задуматься о возможности тщательного изучения полученных байтов, чтобы проверить наличие маркера для концов данных / файлов! Спасибо! - person Haris Hashim; 27.03.2019
comment
@HarisHashim, извините, я пропустил эту часть вашего первоначального вопроса. Но, тем не менее, как вы сказали, возможно, вы можете найти какой-то другой маркер/правило для конкретного контента, чтобы вы знали, когда блок данных полностью отправлен. Удачи! - person Markus Millfjord; 27.03.2019