I'm using QtBluetooth under Win10. Works fine.
However, as my app is deployed both on laptops (that may or may not have a BT adapter) and desktops (that are likely not to have an adapter), I'd like to programmatically check if the adapter is available or not (present and enabled).
Considering the documentation, I tested 4 functions:
bool isBluetoothAvailable1()
{
return !QBluetoothLocalDevice::allDevices().empty();
}
bool isBluetoothAvailable2()
{
QBluetoothLocalDevice localDevice;
return localDevice.isValid();
}
bool isBluetoothAvailable3()
{
std::shared_ptr<QLowEnergyController> created( QLowEnergyController::createPeripheral() );
if ( created )
{
if ( !created->localAddress().isNull() )
return true;
}
return false;
}
bool isBluetoothAvailable4()
{
std::shared_ptr<QLowEnergyController> created( QLowEnergyController::createCentral( QBluetoothDeviceInfo() ) );
if ( created )
{
if ( !created->localAddress().isNull() )
return true;
}
return false;
}
But when I run my code on a Win10 laptop, they all return false! Even if I can search an connect a remote device using the QBluetooth API.
What's the right method to know if a BLE adapter is available?
The correct solution would be to use isBluetoothAvailable1() because the call to allDevices() lists all connected Bluetooth adapters. However, this does not works on Windows.
I do not fully understand their reasoning, but there are 2 Windows implementations of this function in Qt.
https://code.qt.io/cgit/qt/qtconnectivity.git/tree/src/bluetooth/qbluetoothlocaldevice_win.cpp?h=5.15.2
https://code.qt.io/cgit/qt/qtconnectivity.git/tree/src/bluetooth/qbluetoothlocaldevice_winrt.cpp?h=5.15.2
And by default it uses the one that always returns empty list (qbluetoothlocaldevice_win.cpp).
QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
{
QList<QBluetoothHostInfo> localDevices;
return localDevices;
}
The simplest solution is to use the code from the other Windows implementation that works (qbluetoothlocaldevice_winrt.cpp)
#include <Windows.h>
#include <BluetoothAPIs.h>
QList<QBluetoothHostInfo> allDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS params;
::ZeroMemory(¶ms, sizeof(params));
params.dwSize = sizeof(params);
QList<QBluetoothHostInfo> foundAdapters;
HANDLE hRadio = nullptr;
if (const HBLUETOOTH_RADIO_FIND hSearch = ::BluetoothFindFirstRadio(¶ms, &hRadio)) {
for (;;) {
BLUETOOTH_RADIO_INFO radio;
::ZeroMemory(&radio, sizeof(radio));
radio.dwSize = sizeof(radio);
const DWORD retval = ::BluetoothGetRadioInfo(hRadio, &radio);
::CloseHandle(hRadio);
if (retval != ERROR_SUCCESS)
break;
QBluetoothHostInfo adapterInfo;
adapterInfo.setAddress(QBluetoothAddress(radio.address.ullLong));
adapterInfo.setName(QString::fromWCharArray(radio.szName));
foundAdapters << adapterInfo;
if (!::BluetoothFindNextRadio(hSearch, &hRadio))
break;
}
::BluetoothFindRadioClose(hSearch);
}
return foundAdapters;
}
Also you will need to link the necessary libraries Bthprops and ws2_32.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With