12,796
回編集
(→使用例) |
|||
166行目: | 166行目: | ||
==== 使用例 ==== | ==== 使用例 ==== | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// BLEデバイスのスキャンを管理するクラス | |||
// BLEデバイスの検出と監視, 継続的なスキャンモード, デバイス情報の重複排除, 自動リカバリを行う | |||
#include <QObject> | #include <QObject> | ||
#include <QBluetoothDeviceDiscoveryAgent> | #include <QBluetoothDeviceDiscoveryAgent> | ||
#include <QBluetoothDeviceInfo> | #include <QBluetoothDeviceInfo> | ||
#include <QTimer> | #include <QTimer> | ||
#include <QDebug> | #include <QDebug> | ||
178行目: | 180行目: | ||
private: | private: | ||
QBluetoothDeviceDiscoveryAgent discoveryAgent; // BLEデバイス探索用エージェント | |||
QTimer rescanTimer; // 継続的スキャン用タイマ | |||
bool isContinuousScan = false; | bool isContinuousScan = false; // 継続的スキャンモードのフラグ | ||
QMap<QBluetoothAddress, QBluetoothDeviceInfo> knownDevices; // 既知デバイスのキャッシュ | |||
// デバイス探索エージェントとタイマーのシグナルを適切なスロットに接続 | |||
// デバイス発見時の処理, スキャン完了時の処理, エラー発生時の処理, 定期的な再スキャンの制御を行う | |||
void connectSignals() | void connectSignals() | ||
{ | { | ||
191行目: | 196行目: | ||
// 再スキャンタイマのシグナル接続 | // 再スキャンタイマのシグナル接続 | ||
connect(rescanTimer | connect(&rescanTimer, &QTimer::timeout, this, [this]() { | ||
if (isContinuousScan) { | if (isContinuousScan) { | ||
discoveryAgent | discoveryAgent.start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); | ||
} | } | ||
}); | }); | ||
} | } | ||
// エラーコード | |||
QString getErrorMessage(QBluetoothDeviceDiscoveryAgent::Error error) | QString getErrorMessage(QBluetoothDeviceDiscoveryAgent::Error error) | ||
{ | { | ||
208行目: | 214行目: | ||
case QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod: return "未対応の探索方法"; | case QBluetoothDeviceDiscoveryAgent::UnsupportedDiscoveryMethod: return "未対応の探索方法"; | ||
default: return "不明なエラー"; | default: return "不明なエラー"; | ||
} | |||
} | |||
// 発見されたデバイスの詳細情報をログに出力 | |||
// デバイス名, MACアドレス, 電波強度 (RSSI), 提供サービスのUUID, メーカー固有データを表示 | |||
void logDeviceInfo(const QBluetoothDeviceInfo& device) | |||
{ | |||
qDebug() << "BLEデバイスを発見:"; | |||
qDebug() << " 名前:" << device.name(); | |||
qDebug() << " アドレス:" << device.address().toString(); | |||
qDebug() << " RSSI:" << device.rssi(); | |||
// サービスUUIDのログ出力 | |||
const QList<QBluetoothUuid> serviceUuids = device.serviceUuids(); | |||
if (!serviceUuids.isEmpty()) { | |||
qDebug() << " 提供サービス:"; | |||
for (const QBluetoothUuid& uuid : serviceUuids) { | |||
qDebug() << " -" << uuid.toString(); | |||
} | |||
} | |||
// マニファクチャラーデータのログ出力 | |||
const QMap<quint16, QByteArray> manufacturerData = device.manufacturerData(); | |||
if (!manufacturerData.isEmpty()) { | |||
qDebug() << " マニファクチャラーデータ:"; | |||
QMap<quint16, QByteArray>::const_iterator i = manufacturerData.constBegin(); | |||
while (i != manufacturerData.constEnd()) { | |||
qDebug() << " ID: " << i.key() << "データ: " << i.value().toHex(); | |||
i++; | |||
} | |||
} | } | ||
} | } | ||
214行目: | 250行目: | ||
explicit BLEDeviceScanner(QObject* parent = nullptr) : QObject(parent) | explicit BLEDeviceScanner(QObject* parent = nullptr) : QObject(parent) | ||
{ | { | ||
// BLEデバイスのみをスキャンするように設定 | // BLEデバイスのみをスキャンするように設定 | ||
discoveryAgent | discoveryAgent.setLowEnergyDiscoveryTimeout(10000); // 10秒のタイムアウト | ||
// 自動再スキャンタイマの設定 | // 自動再スキャンタイマの設定 | ||
rescanTimer | rescanTimer.setInterval(30000); // 30秒間隔で再スキャン | ||
connectSignals(); | connectSignals(); | ||
} | } | ||
// | // BLEデバイスのスキャンを開始 | ||
void startScan(bool continuous = false) | void startScan(bool continuous = false) | ||
{ | { | ||
233行目: | 265行目: | ||
qDebug() << "BLEデバイススキャンを開始..."; | qDebug() << "BLEデバイススキャンを開始..."; | ||
isContinuousScan = continuous; | isContinuousScan = continuous; | ||
discoveryAgent | discoveryAgent.start(QBluetoothDeviceDiscoveryAgent::LowEnergyMethod); | ||
if (continuous) rescanTimer | if (continuous) rescanTimer.start(); | ||
emit scanStarted(); | emit scanStarted(); | ||
251行目: | 283行目: | ||
try { | try { | ||
qDebug() << "BLEデバイススキャンを停止..."; | qDebug() << "BLEデバイススキャンを停止..."; | ||
discoveryAgent | discoveryAgent.stop(); | ||
rescanTimer | rescanTimer.stop(); | ||
isContinuousScan = false; | isContinuousScan = false; | ||
emit scanStopped(); | emit scanStopped(); | ||
264行目: | 296行目: | ||
signals: | signals: | ||
void deviceDiscovered(const QBluetoothDeviceInfo& device); | void deviceDiscovered(const QBluetoothDeviceInfo& device); // 新規デバイス発見時 | ||
void scanStarted(); | void scanStarted(); // スキャン開始時 | ||
void scanStopped(); | void scanStopped(); // スキャン停止時 | ||
void scanFinished(); | void scanFinished(); // スキャン完了時 | ||
void errorOccurred(const QString& error); | void errorOccurred(const QString& error); // エラー発生時 | ||
private slots: | private slots: | ||
// デバイス発見時の処理 | |||
// BLEデバイスのフィルタリング, 重複デバイスの検出と更新, デバイス情報のログ出力, 新規 / 更新デバイスの通知 | |||
void onDeviceDiscovered(const QBluetoothDeviceInfo& device) | void onDeviceDiscovered(const QBluetoothDeviceInfo& device) | ||
{ | { | ||
// BLEデバイスのみを処理 | // BLEデバイスのみを処理 | ||
if (!(device.coreConfigurations() & QBluetoothDeviceInfo::LowEnergyCoreConfiguration)) { | |||
return; | |||
} | |||
// デバイスの重複確認 | |||
const QBluetoothAddress& address = device.address(); | |||
if (!knownDevices.contains(address) || knownDevices[address].rssi() != device.rssi()) { | |||
knownDevices[address] = device; | |||
// デバイス情報のログ出力と通知 | |||
logDeviceInfo(device); | |||
emit deviceDiscovered(device); | |||
} | |||
} | } | ||
// スキャン完了時の処理 | |||
// 完了通知の発行, 継続的スキャンモードの場合は1秒後に再スキャン | |||
void onScanFinished() | void onScanFinished() | ||
{ | { | ||
317行目: | 338行目: | ||
} | } | ||
// エラー発生時の処理 (エラーメッセージの生成とログ出力) | |||
// 継続的スキャンモードの場合は5秒後に自動再試行 | |||
void onError(QBluetoothDeviceDiscoveryAgent::Error error) | void onError(QBluetoothDeviceDiscoveryAgent::Error error) | ||
{ | { |