【蓝牙】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;
}

需要自定义类型 ManagedObjectList 和 InterfaceList:

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接口实现

相关推荐
女神下凡14 分钟前
芯参谋(95):嵌入式文件系统_开发指南
linux·服务器·arm开发·驱动开发·设计规范
好的佩奇4 小时前
蓝牙之经典蓝牙
android·flutter·蓝牙
且从容.4 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道4 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
且从容.7 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落9 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨9 小时前
WSL2的安装与使用
linux·wsl
微小的鱼9 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng9 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮10 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频