【蓝牙】Linux Qt4查看已经配对的蓝牙信息

在Linux系统中使用Qt4查看已配对的蓝牙设备信息,可以基于DBus与BlueZ(Linux下的蓝牙协议栈)进行交互。以下是一个实现方案:

1. 引入必要的库和头文件

确保项目中包含DBus相关的头文件,并链接QtDBus模块:

cpp

复制代码
#include <QDBusInterface>
#include <QDBusReply>
#include <QDBusObjectPath>
#include <QVariantMap>

2. 定义DBus常量

用于连接BlueZ服务的DBus接口、服务名和路径:

cpp

复制代码
#define BLUEZ_DBUS_SERVICE  "org.bluez"
#define BLUEZ_DBUS_PATH "/org/bluez/hci0"
#define BLUEZ_DBUS_IF "org.bluez.Adapter1"

3. 获取已管理对象(Managed Objects)

通过调用org.freedesktop.DBus.ObjectManager接口的GetManagedObjects方法,可以获取所有蓝牙设备的信息。

cpp

复制代码
QVariantMap getManagedObjects()
{
    QDBusInterface manager(BLUEZ_DBUS_SERVICE, "/",
                           "org.freedesktop.DBus.ObjectManager", QDBusConnection::systemBus());

    QDBusReply<ManagedObjectList> reply = manager.call("GetManagedObjects");

    if (!reply.isValid()) {
        qWarning() << "Failed to get managed objects:" << reply.error().message();
        return QVariantMap();
    }

    ManagedObjectList objects = reply.value();
    QVariantMap result;

    foreach (const QDBusObjectPath &path, objects.keys()) {
        InterfaceList interfaces = objects.value(path);
        foreach (const QString &interface, interfaces.keys()) {
            result[path.path()] = interfaces.value(interface);
        }
    }

    return result;
}

需要自定义类型 ManagedObjectListInterfaceList

cpp

复制代码
typedef QMap<QString, QVariantMap> InterfaceList;
typedef QMap<QDBusObjectPath, InterfaceList> ManagedObjectList;

Q_DECLARE_METATYPE(InterfaceList)
Q_DECLARE_METATYPE(ManagedObjectList)

4. 过滤已配对的蓝牙设备

遍历返回的对象,提取出org.bluez.Device1接口中的设备信息,并筛选出已配对的设备。

cpp

复制代码
void getPairedDevices(BluetoothDeviceList_t &deviceList)
{
    QVariantMap objects = getManagedObjects();
    QSet<QString> uniqueAddresses; // 去重

    foreach (const QString &path, objects.keys()) {
        QVariantMap deviceProps = objects[path].toMap();

        if (deviceProps.contains("Name") && deviceProps.contains("Address") &&
            deviceProps.contains("Paired")) {
            QString name = deviceProps["Name"].toString();
            QString address = deviceProps["Address"].toString();
            bool paired = deviceProps["Paired"].toBool();

            if (!name.isEmpty() && !uniqueAddresses.contains(address) && paired) {
                uniqueAddresses.insert(address);

                BluetoothDevice_t device;
                device.address = address;
                device.Name = name;
                device.Paired = paired;
                device.Connected = deviceProps["Connected"].toBool();
                device.Icon = deviceProps["Icon"].toString();

                deviceList << device;
            }
        }
    }
}

5. 数据结构定义

定义蓝牙设备的数据结构:

cpp

复制代码
struct BluetoothDevice_t {
    QString address;
    QString Name;
    QString Icon;
    QString Alias;
    bool Connected;
    bool Paired;
};

typedef QList<BluetoothDevice_t> BluetoothDeviceList_t;

6. 注册元类型

为了让Qt支持跨线程传递自定义结构体,需要注册元类型:

cpp

复制代码
qRegisterMetaType<BluetoothDevice_t>("BluetoothDevice_t");
qRegisterMetaType<InterfaceList>("InterfaceList");
qRegisterMetaType<ManagedObjectList>("ManagedObjectList");

7. 展示设备列表

将获取到的设备列表展示在QTableWidget中:

cpp

复制代码
void setPairedDeviceList(const BluetoothDeviceList_t &deviceList)
{
    int row_count = deviceList.count();
    if (row_count <= 0) return;

    ui->tableWidget->setRowCount(row_count);
    ui->tableWidget->setColumnCount(1);

    for (int row = 0; row < row_count; ++row) {
        const BluetoothDevice_t &device = deviceList.at(row);
        QTableWidgetItem *item = new QTableWidgetItem(device.Name);
        item->setData(Qt::UserRole, device.address);
        item->setData(Qt::UserRole + 1, device.Paired);
        item->setData(Qt::UserRole + 2, device.Connected);

        QBrush brush = QColor(0, 0, 0);
        if (device.Connected && device.Paired) {
            brush = QColor(0x00DC00); // 绿色
        } else if (device.Paired) {
            brush = QColor(0x3E81DA); // 蓝色
        }

        item->setForeground(brush);
        ui->tableWidget->setItem(row, 0, item);
    }

    ui->tableWidget->selectRow(0);
}

8. 完整流程

  • 初始化UI:设置表格样式、隐藏表头等。
  • 获取设备列表:调用getPairedDevices()
  • 设置设备列表:调用setPairedDeviceList()显示到界面上。

示例运行效果

该程序会列出所有已配对的蓝牙设备名称和地址,并根据是否连接显示不同的颜色。


如需进一步扩展功能,例如连接/断开设备发送文件等,可以通过调用BlueZ提供的DBus接口实现

相关推荐
小成202303202655 小时前
Linux高级02
linux·开发语言
mounter6255 小时前
【硬核前沿】CXL 深度解析:重塑数据中心架构的“高速公路”,Linux 内核如何应对挑战?-- CXL 协议详解与 LSF/MM 最新动态
linux·服务器·网络·架构·kernel
++==5 小时前
Linux 进程间通信与线程同步技术详解:IPC 机制、线程 API、同步工具与经典同步问题
linux
特长腿特长6 小时前
centos、ubantu系列机的用户和用户组的结构是什么?具体怎么配置?用户组权限怎么使用?这篇文章持续更新,帮助你复习linux的基础知识
linux·运维·centos
zzzyyy5386 小时前
Linux环境变量
linux·运维·服务器
pluvium276 小时前
记对 xonsh shell 的使用, 脚本编写, 迁移及调优
linux·python·shell·xonsh
无级程序员6 小时前
centos7 安装 llvm-toolset-7-clang出错的问题解决
linux·centos
CHHC18807 小时前
NetCore树莓派桌面应用程序
linux·运维·服务器
云栖梦泽8 小时前
Linux内核与驱动:9.Linux 驱动 API 封装
linux·c++
嵌入式小企鹅8 小时前
蓝牙学习系列(八):BLE L2CAP 协议详解
网络·学习·蓝牙·ble·协议栈·l2cap