Обмен данными Bluetooth

Пример обмена данными Bluetooth

Продолжаем предыдущую статью о работе с Bluetooth в Android Studio. В этой статье рассмотрим обмен данными Bluetooth, через SPP профиль.

Профиль SPP (Serial Port Profile) – предназначен для обмена данными по Bluetooth. SPP профиль дает возможность, соединить два устройства Bluetooth на транспортном уровне. При таком соединении одно из устройств станет мастером, а второе ведомым. На самом деле нам это не так важно, так как все тонкости скрыты разработчиками классов java. Единственное что нам надо запомнить, это то, что SPP профиль, основан на базовом профиле RFCOM.

SPP профиль Bluetooth

После того как мы обнаружили наше устройство и произвели сопряжение. Нам необходимо создать и открыть сокет.

Для создания сокета воспользуемся следующей командой:

device.createInsecureRfcommSocketToServiceRecord(MY_UUID);

device — это наше устройство Bluetooth.

MY_UUID – uuid SPP профиля.

Внимание!
UUID профиля «00001101-0000-1000-8000-00805f9b34fb»

После создания сокета нам необходимо создать подключение командой connect:

mySocket.connect();

Внимание!
Будьте внимательны при использовании метода connect, он блокирует программу, пока не будет установлено соединение или пока не закончится таймаут. Рекомендуется использовать отдельный поток.

Обмен данными Bluetooth: InputStream

Входящим потоком данных в java является InputStream.  В java есть два типа потоков, символьный и байтовый потоки. Что бы инициализировать байтовый поток Input, необходимо применить метод сокета:

mySocket.getOutputStream()

Обмен данными Bluetooth: OutputStream

Исходящим потоком данных в java является OutputStream.  Что бы инициализировать байтовый поток Otput, необходимо применить метод сокета:

mySocket.getOutputStream()

Android studio: пример обмена по bluetooth

Создадим новый класс для обмена данными по Bluetooth. Класс наследуем от класса реализующего потоки.

private class ConnectThread extends Thread
{
    private BluetoothSocket mmSocket = null;
    private boolean isUpdateDate = false;
    private final Activity mmActivity;
    private BluetoothAdapter mmAdapter = null;
    private OutputStream outData = null;
    private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");


    public ConnectThread(BluetoothDevice device, BluetoothAdapter adapter, Activity activity) {
        BluetoothSocket tmp = null;
        mmAdapter = adapter;
        mmActivity = activity;
        try {
            if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            //device.getUuids()[0].getUuid()
            tmp = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
            Log.e("TODO", "Сокет создан");
        } catch (IOException e) {
            Log.e("TODO", "Ошибка созадания сокета");
        }
        mmSocket = tmp;
    }

    public void setIsUpdate(Boolean data) {
        isUpdateDate = data;
    }

    public void run()
    {
        while (isUpdateDate) {
            if (mServiceBound)
            {
                 sendData(latitudeToSend + " " + longitudeToSend);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void connectSSP() {
        if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        mmAdapter.cancelDiscovery();
        Log.e("TODO", "Завершил поиск даже если небыл включен");
        try {
            Log.e("TODO", "Включаю сокет");
            mmSocket.connect();
            outData = mmSocket.getOutputStream();

            InputStream inData = mmSocket.getInputStream();

            AlertDialog dialog = DialogView.getDialog(mmActivity, DialogView.IDD_INFO_CONNECT);
            dialog.show();
        } catch (IOException connectException) {
            Log.e("TODO", "Не могу подключить SPP", connectException);
            try {
                mmSocket.close();
            } catch (IOException closeException) {
                Log.e("TAG", "Не могу закрыть сокет", closeException);
            }
        }
    }

    public void sendData(String dataStr) {

        if (isUpdateDate) {
            try {
                outData = mmSocket.getOutputStream();
            } catch (IOException e) {
                Log.d("Error", "SSP OUT", e);
            }
            byte[] msgBuf = dataStr.getBytes();
            try {
                outData.write(msgBuf);
            } catch (IOException e) {
                Log.d("Error", "SSP OUT", e);
            }
        }
    }

    public void cancel() {
        try {
            if (mmSocket != null) {
                if (mmSocket.isConnected())
                    mmSocket.close();
            }
        } catch (IOException e) {
            Log.e("TAG", "Не могу закрыть сокет", e);
        }
	//Закрываем поток
        ConnectThread.interrupted();
    }
}

Пояснения к коду обмена данными по Bluetooth

При инициализации класса в конструктор класса необходимо передать наше устройство Bluetooth (устройство с которым будем обмениваться данными) и наш Bluetooth adapter (физический блютуз).

Метод класса setIsUpdate, позволяет установить флаг, для старта передачи данных, если флаг не установлен, то передача не идет.

Метод connectSSP реализует соединение с устройством Bluetooth через профиль SPP. После установки соединения пользователь получит диалоговое сообщение о успешном соединении.

sendData метод класса, который принимает на вход строку для отправки другому устройству. Затем эта строка конвертируется в массив байт и отправляется на передачу.

Последний метод cancel. Данный метод необходимо применять, когда мы завершаем работу с сокетом.

Чтобы начать работу с классом, необходимо из основного активити создать объект класса и вызвать метод Start.

ConnectThread  connectBLE = new ConnectThread(btConnectDevice, mAdapter, MainActivity.this);
connectBLE.start();
5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии