Привет! Данная статья является продолжением серии статей, посвященных разработке под мобильную платформу Sailfish OS. На этот раз мы поговорим об использовании Bluetooth для установления соединения между двумя устройствами и передачи данных.
Bluetooth
Технология Bluetooth позволяет создать беспроводное соединение, благодаря которому можно передавать абсолютно любые данные.Существует ряд задач, для которых Bluetooth является распространенным решением, например, передача файлов с одного устройства на другое, подключение к Bluetooth-гарнитурам или удаленное управление сканерами и принтерами.
Пример приложения
Мы рассмотрим использование технологии Bluetooth на примере реализации приложения для обмена строк.Давай позвоним ему Bluetooth-мессенджер .
Приложение будет работать в двух режимах: серверном и клиентском.
Сервер зарегистрирует службу Bluetooth и ответит на клиентское соединение.
Клиент будет искать созданный сервис, подключаться к нему и передавать данные.
В результате вам понадобятся два устройства под управлением ОС Sailfish.
|
|
- Клиент ищет сервер с зарегистрированным сервисом.
- Отправляет строку на найденный сервер.
- Сервер получает строку и отображает ее на экране.
- Полученная строка расширяется и отправляется обратно клиенту.
- Клиент отображает расширенную строку на экране и отключается от сервера.
|
|
Предоставление повышенных привилегий приложению
Для взаимодействия с Bluetooth приложению иногда требуются повышенные привилегии (на поиск сервисов, изменение настроек видимости, сопряжение устройств).Если у вас нет повышенных привилегий, некоторые функции будут недоступны, поэтому мы рекомендуем предоставить их приложению, работающему с Bluetooth. Для отладки вам необходимо запустить приложение, используя девел-су с флагом -п .
Это позволяет приложению запускаться с повышенными привилегиями, а выходные данные отладки будут доступны в консоли.
Для того, чтобы запустить приложение с повышенными привилегиями по клику на иконку, необходимо внести некоторые настройки в исходные файлы проекта.devel-su -p /usr/bin/bluetooth-messenger
Во-первых, исполняемый файл приложения необходимо запустить с помощью вызывающий .
вызывающий находит основную функцию приложения и запускает ее с переданными ей аргументами.
Это настраивается в .
рабочий стол файл проекта со следующей строкой: Exec=invoker --type=silica-qt5 -s /usr/bin/bluetooth-messenger
Во-вторых, вам необходимо создать в каталоге файл с именем, соответствующим имени исполняемого файла.
/usr/share/maplauncherd/privileges.d/ и поместите туда строку: /usr/bin/bluetooth-messenger,
Запятая в конце строки обязательна.
Таким образом, при нажатии на значок приложения пользователь запустит его с повышенными привилегиями.
Управление статусом Bluetooth
Для начала нужно понять, как можно контролировать состояние Bluetooth. Для этого воспользуемся системой D-Bus, взаимодействие с которой было описано в одна из предыдущих статей .С помощью этой системы у нас есть возможность включать и выключать питание Bluetooth, а также настраивать видимость для других устройств.
Для включения Bluetooth необходимо воспользоваться услугой net.connman .
Об интерфейсе net.connman в пути /net/connman/технология/Bluetooth есть метод Установитьсвойство , с помощью которого можно задать значение свойства Работает , который отвечает за то, включен ли Bluetooth или нет. Свойство установлено следующим образом: QDBusInterface bluetoothInterface("net.connman", "/net/connman/technology/bluetooth",
"net.connman.Technology", QDBusConnection::systemBus(), this);
bluetoothInterface.call("SetProperty", "Powered", QVariant::fromValue(QDBusVariant(true)));
Создать экземпляр QDBusИнтерфейс используя сервис, путь и интерфейс, перечисленные ранее.
Затем мы вызываем метод интерфейса Установитьсвойство с двумя аргументами: именем свойства и значением.
После включения Bluetooth будет полезно настроить видимость для других устройств.
Для этого мы используем сервис org.bluez .
Сначала вам нужно получить путь, соответствующий текущему устройству.
Для этого перейдите по корневому пути на интерфейсе org.bluez.Менеджер вызвать метод Адаптер по умолчанию , содержащий в выходных аргументах путь к текущему адаптеру, который мы позже будем использовать для установки видимости.
QDBusInterface adapterListInterface("org.bluez", "/", "org.bluez.Manager",
QDBusConnection::systemBus(), this);
QVariant adapterPath = adapterListInterface.call("DefaultAdapter").
arguments().
at(0);
После получения пути вам нужно использовать метод для установки видимости Установитьсвойство на интерфейсе org.bluez.Адаптер чтобы установить следующие свойства:
- Обнаруживаемыйтаймаут – время в секундах ( беззнаковое целое число ), в течение которого устройство будет доступно для обнаружения после включения обнаружения.
Если установлено значение 0, обнаружение начинается без таймера.
- Обнаруживаемый - в зависимости от стоимости истинный или ЛОЖЬ включает или выключает обнаружение.
QDBusInterface bluetoothAdapter("org.bluez", adapterPath.value<QDBusObjectPath>().
path(),
"org.bluez.Adapter", QDBusConnection::systemBus(), this);
bluetoothAdapter.call("SetProperty", "DiscoverableTimeout", QVariant::fromValue(QDBusVariant(0U)));
bluetoothAdapter.call("SetProperty", "Discoverable", QVariant::fromValue(QDBusVariant(true)));
Следует отметить, что для настройки параметров видимости приложение должно быть запущено с повышенными привилегиями.
Регистрация службы Bluetooth
Для начала нам нужно создать сервер и зарегистрировать на нем сервис.Этот сервис будет получать сообщения от клиентов и отвечать на них.
Для решения этой проблемы создадим класс Сервер сообщений , заголовочный файл которого будет содержать следующее: class MessengerServer : public QObject {
Q_OBJECT
public:
explicit MessengerServer(QObject *parent = 0);
~MessengerServer();
Q_INVOKABLE void startServer();
Q_INVOKABLE void stopServer();
signals:
void messageReceived(QString message);
private:
QBluetoothServer *bluetoothServer;
QBluetoothServiceInfo serviceInfo;
QBluetoothSocket *socket;
const QString SERVICE_UUID = "1f2d6c5b-6a86-4b30-8b4e-3990043d73f1";
private slots:
void clientConnected();
void clientDisconnected();
void readSocket();
};
Теперь давайте подробнее рассмотрим компоненты и содержание методов этого класса.
Устройство может уведомлять другие устройства, осуществляющие поиск через Bluetooth, зарегистрировав службу.
Для этого используется класс QBluetoothСервер .
С его помощью можно создать Bluetooth-сервер и зарегистрировать на нем сервис, который будет сообщать устройствам, что это такое.
QBluetoothСервер содержит набор методов для установки сервера на устройство и регистрации сервиса.
Особый интерес представляют:
- Конструктор QBluetoothServer(QBluetoothServiceInfo::Protocol serverType, родительский объект QObject*) – служит для инициализации сервера, принимает в качестве аргументов протокол и родителя QObject .
В нашем примере мы будем использовать протокол RFCOMM.
- Метод прослушивать (const QBluetoothAddress& адрес, порт quint16) – начинает прослушивать входящие соединения по переданному адресу и порту.
- Сигнал ошибка (QBluetoothServer::Ошибка ошибки) — вызывается при возникновении ошибок сервера (Bluetooth выключен, служба уже зарегистрирована и т. д.), где в качестве аргумента доступна сама ошибка.
- Сигнал новоеСоединение() – Вызывается при наличии нового запроса на соединение.
Они не так уж и интересны, и о них можно прочитать в официальной документации.
После того как мы подняли сервер, нам необходимо зарегистрировать сервис.
Служба — это описание службы, выполняющей определенные обязанности.
Описывает сервис, использующий объект QBluetoothServiceInfo путем установки атрибутов с использованием специальных методов.
Для решения поставленной выше задачи воспользуемся методом стартСервер() : bluetoothServer = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
connect(bluetoothServer, &QBluetoothServer::newConnection,
this, &MessengerServer::clientConnected);
QBluetoothAddress bluetoothAddress = QBluetoothLocalDevice().
address();
bluetoothServer->listen(bluetoothAddress);
Первая строка — создать сервер, использующий RFCOMM в качестве протокола.
Затем подключаем сигнал о новом подключении к слоту нашего класса.
После этого включаем прослушивание по нашему адресу, для чего создаём экземпляр текущего устройства, из которого извлекаем его адрес и передаем методу слушать() .
Вот так мы устанавливаем сервер.
Для регистрации сервиса требуется больше кода для указания всех параметров, необходимых для его работы: serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName, "BT message sender");
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceDescription,
"Example message sender");
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceProvider, "fruct.org");
serviceInfo.setServiceUuid(QBluetoothUuid(SERVICE_UUID));
Здесь мы задаем имя сервиса, описание, поставщика услуг (например, название компании) и уникальный идентификатор (в данном приложении он содержится в константе в виде строки и указывается в формате ххххххх-хххх-хххх-хххх-хххххххххх , Где Икс шестнадцатеричное число).
Первые три атрибута дают базовое представление о найденной службе, а четвертый может использоваться устройствами для поиска конкретной службы.
QBluetoothServiceInfo::Sequence classId;
classId << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));
serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList, classId);
classId.prepend(QVariant::fromValue(QBluetoothUuid(SERVICE_UUID)));
serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds, classId);
В конструкции такого типа используется последовательность ( QBluetoothServiceInfo::Sequence ), чтобы установить другие атрибуты.
В этом случае мы устанавливаем уникальный идентификатор сервиса.
Таким образом сервер сообщает вам, какие услуги он предоставляет. QBluetoothServiceInfo::Sequence publicBrowse;
publicBrowse << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList, publicBrowse);
С помощью этих строк мы устанавливаем публичную группу поиска, которая позволит устройствам свободно находить этот сервис.
В противном случае услуга не будет найдена.
QBluetoothServiceInfo::Sequence protocol;
QBluetoothServiceInfo::Sequence protocolDescriptorList;
protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
<< QVariant::fromValue(quint8(bluetoothServer->serverPort()));
protocolDescriptorList.append(QVariant::fromValue(protocol));
serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList);
Здесь для доступа к сервису устанавливаем протокол RFCOMM, аналогичный тому, который используется сервером.
serviceInfo.registerService(bluetoothAddress);
Наконец, мы регистрируем созданный сервис по адресу, полученному ранее и используемому сервером.
Теперь сервис будет виден при поиске по Bluetooth с другими устройствами.
Работа с входящими соединениями
Теперь, когда служба зарегистрирована и приложение готово принимать входящие соединения, ему необходимо их обработать.Как упоминалось ранее, сервер приложений должен принять строку от клиента, расширить ее и отправить обратно.
Когда клиент подключается к серверу, мы создаем сокет, представленный в виде экземпляра.
QBluetoothSocket , который можно получить, вызвав метод следующееPendingConnection() в экземпляре класса QBluetoothСервер .
Сокет имеет целый набор сигналов, позволяющих отслеживать его состояние, наиболее полезными из которых являются:
- связанный() – Вызывается при создании сокетного соединения.
- отключен() – вызывается при разрыве соединения.
- ошибка (ошибка QBluetoothSocket::SocketError) – вызывается при возникновении ошибки, ее тип передается в качестве аргумента.
- готовЧитать() – Вызывается, когда новые данные доступны для чтения в сокете.
Ранее мы прикрепили сигнал новоеСоединение() в слот клиентСоединенный() , рассмотрим его реализацию.
void MessengerServer::clientConnected() {
//.
socket = bluetoothServer->nextPendingConnection();
connect(socket, &QBluetoothSocket::readyRead, this, &MessengerServer::readSocket);
connect(socket, &QBluetoothSocket::disconnected, this, &MessengerServer::clientDisconnected);
}
Объект QBluetoothSocket является наследником QIOУстройство , в результате ему доступны методы чтения строки, символа, выбранного количества символов и т. д. Методы чтения (как и методы записи) используют QByteArray , который позволяет передавать не только строки, но и любые другие данные в виде набора байтов.
Таким образом можно передавать любые типы данных, независимо от их содержания.
В нашем примере для обработки входящих сообщений мы подключили сигнал готовЧитать() с методом чтениеСокет() , код которого выглядит следующим образом: void MessengerServer::readSocket() {
//.
const QString message = QString::fromUtf8(socket->readLine().
trimmed());
emit messageReceived(message);
QString reversedMessage;
for (int i = message.size() - 1; i >= 0; i--) {
reversedMessage.append(message.at(i));
}
socket->write(reversedMessage.toUtf8());
}
Для чтения данных в виде массива байтов мы используем метод читатьстроку() , после чего преобразуем прочитанную строку в строку, разворачиваем ее и отправляем обратно методом писать() , преобразуя обратно в массив байтов.
Таким образом, реализованный нами сервер способен принимать строку от любого другого устройства по Bluetooth и возвращать ее обратно в развернутом виде.
Поиск услуг
Теперь, когда сервер реализован, запущен и ожидает входящих подключений, вам необходимо к нему подключиться.Как найти устройство, предоставляющее необходимый сервис? Сначала нужно выполнить поиск сервисов, доступных на видимых Bluetooth-устройствах, и только потом подключаться к нему.
Заголовочный файл клиента имеет следующее содержимое: class MessengerClient : public QObject {
Q_OBJECT
public:
explicit MessengerClient(QObject *parent = 0);
~MessengerClient();
Q_INVOKABLE void startDiscovery(const QString &messageToSend);
Q_INVOKABLE void stopDiscovery();
private:
const QString SERVICE_UUID = "1f2d6c5b-6a86-4b30-8b4e-3990043d73f1";
QString message;
QBluetoothSocket *socket = NULL;
QBluetoothDeviceDiscoveryAgent* discoveryAgent;
QBluetoothDeviceInfo device;
QBluetoothLocalDevice localDevice;
void requestPairing(const QBluetoothAddress &address);
void startClient(const QBluetoothAddress &address);
void stopClient();
signals:
void messageReceived(QString message);
void clientStatusChanged(QString text);
private slots:
void deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo);
void pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
void pairingError(QBluetoothLocalDevice::Error error);
void socketConnected();
void deviceSearchFinished();
void readSocket();
};
Давайте рассмотрим компоненты, необходимые для реализации поиска сервиса и отправки сообщений.
Для поиска сервисов в библиотеке Qt предусмотрен класс QBluetoothServiceDiscoveryAgent .
Он позволяет автоматически проверять все устройства на наличие определенного сервиса, который мы ищем по UUID. В дальнейшем, когда сервис будет найден, объект этого класса инициирует соответствующий сигнал, с помощью которого мы можем обработать результат поиска.
Следует отметить, что для использования этого класса необходимо, чтобы приложение запускалось с повышенными привилегиями.
Класс содержит следующие интересующие нас методы:
- setUuidFilter (const QBluetoothUuid &uuid) – задает UUID того сервиса, с помощью которого вы хотите найти.
Существует также аналогичный метод установки нескольких UUID.
- setRemoteAddress (const QBluetoothAddress &адрес) – задает адрес устройства, на котором вы хотите найти услугу.
Можно использовать, если известен точный адрес устройства, которое необходимо найти.
- начинать() – запускает поиск услуг.
- останавливаться() – прекращает поиск услуг.
- обнаруженные услуги() – возвращает список найденных сервисов.
- прозрачный() – очищает список найденных сервисов.
- serviceDiscovered(const QBluetoothServiceInfo &info) – вызывается при обнаружении службы, информация о ней передается с аргументом.
- законченный() – вызывается, когда поиск завершен.
- ошибка (QBluetoothServiceDiscoveryAgent::Ошибка ошибки) – Вызывается при возникновении ошибок.
После этого при обнаружении нашего сервиса сработает сигнал сервисобнаружен() .
Экопировать QBluetoothServiceInfo содержит информацию о найденном сервисе (имя, UUID, информацию об устройстве, на котором он зарегистрирован и т. д.).
Мы будем использовать экземпляр этого класса для подключения к сервису, о котором будет упомянуто позже.
Конкретно в нашем примере мы рассмотрим еще один класс, не требующий повышенных привилегий — QBluetoothDeviceDiscoveryAgent .
Его можно использовать для поиска устройств, а не сервисов, и он не требует повышенных привилегий.
Для каждого найденного устройства мы будем смотреть зарегистрированные на устройстве сервисы, и если наш сервис есть в списке, то считаем сервис найденным и в дальнейшем будем подключаться к нему.
QBluetoothDeviceDiscoveryAgent состоит из небольшого количества методов поиска устройств.
Наиболее полезными являются следующие:
- начинать() – начинает поиск устройств.
- останавливаться() – прекращает поиск устройств.
- обнаруженные устройства() – возвращает список всех найденных устройств.
- ошибка() – возвращает тип последней ошибки, обнаруженной при поиске.
Существует также сигнал, который будет запущен сразу после возникновения ошибки с типом ошибки в качестве аргумента.
- ошибкаТекст() – возвращает текст последней произошедшей ошибки.
устройствоОбнаружено(const QBluetoothDeviceInfo &info) , который можно использовать для обработки результата.
Информация о найденных устройствах представлена в виде объекта QDeviceInfo .
Вы можете извлечь данные из этого объекта с помощью специальных методов.
Наиболее интересны следующие:
- адрес() – mac-адрес найденного устройства.
Используется при поиске любых устройств, кроме macOS и iOS.
- устройствоUuid() – уникальный идентификатор найденного устройства.
Используется только при поиске устройств на macOS и iOS.
- имя() – имя найденного устройства.
- сервисUuids() – список уникальных идентификаторов зарегистрированных сервисов.
В конструкторе инициализируем объект для поиска устройств: MessengerClient::MessengerClient(QObject *parent) : QObject(parent) {
//.
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(localDevice.address()); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &MessengerClient::deviceDiscovered); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &MessengerClient::deviceSearchFinished); //.
}
Сначала создайте экземпляр QBluetoothDeviceDiscoveryAgent , которому мы передаем в качестве аргумента адрес текущего устройства Bluetooth. Затем к нашему текущему присоединяем два объектных сигнала: устройствообнаружено() для обработки нового найденного устройства и законченный() для обработки завершения поиска.
Метод запуска поиска содержит следующие строки: void MessengerClient::startDiscovery(const QString &messageToSend) {
//.
this->message = messageToSend; discoveryAgent->start(); //.
}
Здесь сохраняем сообщение, которое необходимо передать и начинаем поиск устройств.
Слот используется для обработки найденных устройств устройствообнаружено() , к которому мы ранее подключили сигнал: void MessengerClient::deviceDiscovered(const QBluetoothDeviceInfo &deviceInfo) {
//.
if (deviceInfo.serviceUuids().
contains(QBluetoothUuid(SERVICE_UUID))) {
emit clientStatusChanged(QStringLiteral("Device found"));
discoveryAgent->stop();
requestPairing(deviceInfo.address());
}
}
Как говорилось ранее, мы смотрим на список уникальных идентификаторов сервисов, чтобы найти в нем свой зарегистрированный.
Когда найдено первое устройство, предоставляющее искомую нам услугу, мы завершаем поиск и вызываем метод для установления сопряжения между устройствами.
Сопряжение устройств
Сопряжение устройств — важный аспект связи устройств с помощью Bluetooth. Это означает, что два устройства устанавливают доверительные отношения друг с другом и имеют доступ к более широкому набору вариантов взаимодействия (например, удаленному управлению).Конкретно в нашем примере сопряжение не требуется, но мы его установим, чтобы посмотреть, как это делается в общем случае.
Для установления сопряжения требуются повышенные привилегии.
Класс используется для сопряжения устройств.
Мы уже использовали его ранее в серверном коде для получения адреса текущего устройства.
Он также используется для сопряжения устройств.
Нас интересуют методы:
- PairingStatus (const QBluetoothAddress &address) – позволяет получить статус сопряжения между текущим устройством и устройством по адресу.
Возвращает одно из следующих значений:
- requestPairing (const QBluetoothAddress &address, сопряжение) – запрашивает изменение статуса сопряжения с устройством (второй аргумент – Paired для установления сопряжения или Unpaired для разрыва).
- PairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing Pairing) – возвращается, когда статус сопряжения был успешно изменен.
- error(QBluetoothLocalDevice::Error error) – возвращается, если произошла ошибка при изменении статуса сопряжения (включая отмену предложения сопряжения на одном из устройств).
Теперь попробуем установить сопряжение между двумя устройствами.
Во-первых, давайте добавим сигнальное соединение в конструктор клиентского класса: connect(&localDevice, &QBluetoothLocalDevice::pairingFinished,
this, &MessengerClient::pairingFinished);
connect(&localDevice, &QBluetoothLocalDevice::error, this, &MessengerClient::pairingError);
Экопировать QBluetoothLocalDevice в данном случае это поле класса.
Слот спариваниеЗавершено() содержит строку, которая запускает клиент startClient (адрес) , А ошибка спаривания() – отладочный вывод.
Для установления спаривания мы реализовали метод запросСопряжение() со следующим содержанием: void MessengerClient::requestPairing(const QBluetoothAddress &address) {
//.
if (localDevice.pairingStatus(address) == QBluetoothLocalDevice::Paired) {
startClient(address);
} else {
localDevice.requestPairing(address, QBluetoothLocalDevice::Paired);
}
}
Если устройства уже сопряжены, то просто инициируем соединение с сервером, в противном случае запрашиваем сопряжение.
В результате, если сопряжение успешно установлено, также инициируется соединение с сервером, а в случае ошибки мы уведомляем пользователя о проблеме.
Подключение к серверу
Ээкземпляр класса QBluetoothDeviceInfo , соответствующий найденному устройству, содержит метод получения адреса, достаточного для подключения к сервису.Для этой цели используется QBluetoothSocket , достаточно с помощью конструктора создать экземпляр этого класса, передав ему протокол RFCOMM и вызвав метод ConnectToService() , которому в качестве аргументов передается адрес из экземпляра QBluetoothDeviceInfo и порт, на котором необходимо установить соединение.
Чтобы установить соединение с сервисом, необходимо указать порт 1. Теперь давайте рассмотрим процесс установления соединения, отправки и получения данных с помощью сокета.
Клиент использует то же самое QBluetoothSocket как на сервере, что позволяет нам использовать ранее рассмотренные сигналы для реализации обработчиков и методов записи данных в сокет. Метод стартКлиент() устанавливает соединение с устройством, предоставляющим услугу, с помощью сокета: void MessengerClient::startClient(const QBluetoothDeviceInfo &deviceInfo) {
//.
socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
connect(socket, &QBluetoothSocket::connected, this, &MessengerClient::socketConnected);
connect(socket, &QBluetoothSocket::readyRead, this, &MessengerClient::readSocket);
socket->connectToService(deviceInfo.address(), 1);
}
Мы создаем экземпляр сокета с протоколом RFCOMM и подключаем его сигналы к слотам нашего класса.
Затем вызов метода ConnectToService() подключиться к другому устройству.
Следует отметить, что если бы мы использовали класс QBluetoothServiceInfo , что позволяет получать информацию о найденных сервисах в виде экземпляров QBluetoothServiceInfo , то достаточно будет вызвать метод ConnectToService() с одним аргументом, принимающим информацию об услуге.
Метод сокетСоединенный() вызывается при установлении сокетного соединения, внутри него мы отправляем данные на сервер: void MessengerClient::socketConnected() {
//.
socket->write(message.toUtf8());
}
Здесь используется тот же класс сокета, что и на сервере, поэтому мы можем передавать любые данные в виде массива байтов.
Как мы помним, код сервера позволяет получить строку, раскрыть ее и вернуть нам; для обработки входящего сообщения мы подключили слот чтениеСокет() с сигналом готовЧитать() .
Этот слот выглядит следующим образом: void MessengerClient::readSocket() {
//.
QString receivedMessage = QString::fromUtf8(socket->readLine().
trimmed());
emit messageReceived(receivedMessage);
}
Результат
В результате мы рассмотрели большую часть функционала, необходимого для реализации сервера и клиента для передачи данных любого типа между ними.Мы также рассмотрели процедуру поиска устройства.
Упомянутого в статье материала достаточно для реализации передачи любых данных между двумя устройствами.
Пример кода приложения доступен по адресу GitHub .
Технические вопросы также можно обсудить по адресу канал русскоязычного сообщества Sailfish OS в Telegram или группа вконтакте .
Автор: Сергей Аверкиев Теги: #sailfish os #Qt #Bluetooth #Разработка мобильных приложений #Qt #Разработка для Sailfish OS
-
Алгоритмы И Структуры Данных – Шпаргалка
19 Oct, 24 -
Gdg Devfest Нижний Новгород 2015
19 Oct, 24 -
Простой Кеш В Памяти
19 Oct, 24