블루투스 저에너지 스캐너
Bluetooth 저에너지 주변 장치의 콘텐츠를 검색하도록 설계된 애플리케이션입니다. 이 예는 모든 Qt Bluetooth 저에너지 클래스.
블루투스 저에너지 스캐너 예제는 블루투스 저에너지 애플리케이션을 개발하는 방법을 보여줍니다. Qt Bluetooth API. 이 애플리케이션은 저에너지 디바이스 스캔, 서비스 스캔, 서비스 특성 및 설명자 읽기를 다룹니다.
이 예제에서는 다음 Qt 클래스를 소개합니다:
이 예제는 임의의 블루투스 저에너지 주변 장치와 함께 사용할 수 있습니다. 모든 서비스, 특성 및 설명자의 스냅샷을 생성하여 사용자에게 제공합니다. 따라서 이 애플리케이션은 주변 장치에서 제공하는 콘텐츠를 쉽게 탐색할 수 있는 방법을 제공합니다.
예제 실행하기
에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.
블루투스 사용 권한 요청하기
특정 플랫폼에서는 블루투스 사용에 대한 권한을 명시적으로 부여해야 합니다. 이 예제에서는 BluetoothPermission
QML 개체를 사용하여 필요한 경우 권한을 확인하고 요청합니다:
BluetoothPermission { id: permission communicationModes: BluetoothPermission.Access onStatusChanged: { if (permission.status === Qt.PermissionStatus.Denied) Device.update = "Bluetooth permission required" else if (permission.status === Qt.PermissionStatus.Granted) devicesPage.toggleDiscovery() } }
권한 요청 대화 상자는 사용자가 장치 검색을 시작하려고 할 때 트리거되며 권한 상태는 Undetermined
입니다:
onButtonClick: { if (permission.status === Qt.PermissionStatus.Undetermined) permission.request() else if (permission.status === Qt.PermissionStatus.Granted) devicesPage.toggleDiscovery() }
사용자가 권한을 부여하면 장치 검색이 시작됩니다. 그렇지 않으면 애플리케이션이 작동하지 않습니다.
장치 검색
첫 번째 단계는 모든 주변 장치를 찾는 것입니다. 장치는 QBluetoothDeviceDiscoveryAgent 클래스를 사용하여 찾을 수 있습니다. 검색 프로세스는 start()를 사용하여 시작됩니다. 각각의 새 장치는 deviceDiscovered() 신호를 통해 알립니다:
discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this); discoveryAgent->setLowEnergyDiscoveryTimeout(25000); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &Device::addDevice); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::errorOccurred, this, &Device::deviceScanError); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this, &Device::deviceScanFinished); connect(discoveryAgent, &QBluetoothDeviceDiscoveryAgent::canceled, this, &Device::deviceScanFinished); discoveryAgent->start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod);
아래 addDevice()
슬롯은 새 디바이스 발견에 대한 반응으로 트리거됩니다. QBluetoothDeviceInfo::LowEnergyCoreConfiguration 플래그가 있는 검색된 모든 장치를 필터링하여 사용자에게 표시되는 목록에 추가합니다. deviceDiscovered () 신호는 더 많은 세부 정보가 발견되면 동일한 디바이스에 대해 여러 번 발신될 수 있습니다. 여기서는 이러한 디바이스 검색을 일치시켜 사용자가 개별 디바이스만 볼 수 있도록 합니다:
void Device::addDevice(const QBluetoothDeviceInfo &info) { if (info.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration) { auto devInfo = new DeviceInfo(info); auto it = std::find_if(devices.begin(), devices.end(), [devInfo](DeviceInfo *dev) { return devInfo->getAddress() == dev->getAddress(); }); if (it == devices.end()) { devices.append(devInfo); } else { auto oldDev = *it; *it = devInfo; delete oldDev; } emit devicesUpdated(); } }
디바이스 목록은 아래 이미지와 같이 표시될 수 있습니다.
참고: 원격 장치가 자신의 존재를 적극적으로 알리는 것이 전제 조건입니다.
서비스에 연결하기
사용자가 목록에서 장치를 선택하면 애플리케이션이 장치에 연결하여 모든 서비스를 검색합니다. QLowEnergyController 클래스는 장치에 연결하는 데 사용됩니다. QLowEnergyController::connectToDevice () 함수는 QLowEnergyController::connected() 신호가 수신되거나 오류가 발생할 때까지 지속되는 연결 프로세스를 트리거합니다:
if (!controller) { // Connecting signals and slots for connecting to LE services. controller = QLowEnergyController::createCentral(currentDevice.getDevice(), this); connect(controller, &QLowEnergyController::connected, this, &Device::deviceConnected); connect(controller, &QLowEnergyController::errorOccurred, this, &Device::errorReceived); connect(controller, &QLowEnergyController::disconnected, this, &Device::deviceDisconnected); connect(controller, &QLowEnergyController::serviceDiscovered, this, &Device::addLowEnergyService); connect(controller, &QLowEnergyController::discoveryFinished, this, &Device::serviceScanDone); } if (isRandomAddress()) controller->setRemoteAddressType(QLowEnergyController::RandomAddress); else controller->setRemoteAddressType(QLowEnergyController::PublicAddress); controller->connectToDevice();
connected() 신호에 의해 트리거된 슬롯은 즉시 QLowEnergyController::discoverServices()을 호출하여 연결된 주변 장치에서 서비스 검색을 시작합니다.
controller->discoverServices();
결과 목록이 사용자에게 표시되며, 아래 이미지는 센서태그 장치를 선택했을 때의 결과를 보여줍니다. 이 보기에는 기본 서비스인지 보조 서비스인지 여부에 관계없이 서비스 이름과 서비스 유형을 결정하는 UUID가 나열됩니다.
서비스를 선택하자마자 관련 QLowEnergyService 인스턴스가 생성되어 해당 서비스와의 상호 작용을 허용합니다:
QLowEnergyService *service = controller->createServiceObject(serviceUuid);if (!service) {... qWarning() << "Cannot create service for uuid"; return; }
서비스 객체는 서비스 세부 정보를 검색하고, 특성 및 설명자를 읽고 쓰고, 데이터 변경 알림을 수신하는 데 필요한 신호와 기능을 제공합니다. 변경 알림은 값 쓰기의 결과 또는 내부 로직에 의해 트리거될 수 있는 온디바이스 업데이트로 인해 트리거될 수 있습니다. 초기 세부 정보 검색 중에 서비스의 state()는 RemoteService 에서 RemoteServiceDiscovering 로 전환되고 결국 RemoteServiceDiscovered 로 끝납니다:
connect(service, &QLowEnergyService::stateChanged, this, &Device::serviceDetailsDiscovered); service->discoverDetails(); setUpdate(u"Back\n(Discovering details...)"_s);
서비스 데이터 읽기
서비스를 선택하면 서비스 세부 정보가 표시됩니다. 각 특성은 이름, UUID, 값, 핸들 및 속성과 함께 나열됩니다.
QLowEnergyService::characteristics()를 통해 서비스의 특성을 검색할 수 있으며, 각 설명자는 QLowEnergyCharacteristic::descriptors()를 통해 얻을 수 있습니다.
const QList<QLowEnergyCharacteristic> chars = service->characteristics(); for (const QLowEnergyCharacteristic &ch : chars) { auto cInfo = new CharacteristicInfo(ch); m_characteristics.append(cInfo); }
예제 애플리케이션에는 설명자가 표시되어 있지 않지만 UUID를 기준으로 이름을 알 수 없는 경우 설명자를 사용하여 개별 특성의 이름을 가져옵니다. 이름을 얻는 두 번째 방법은 QBluetoothUuid::DescriptorType::CharacteristicUserDescription 유형의 설명자가 있는 경우입니다. 아래 코드는 이를 수행하는 방법을 보여줍니다:
QString name = m_characteristic.name(); if (!name.isEmpty()) return name; // find descriptor with CharacteristicUserDescription const QList<QLowEnergyDescriptor> descriptors = m_characteristic.descriptors(); for (const QLowEnergyDescriptor &descriptor : descriptors) { if (descriptor.type() == QBluetoothUuid::DescriptorType::CharacteristicUserDescription) { name = descriptor.value(); break; } }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.