x86下 linux qt检测U盘插拔(一)------- HAL 与UDISKS

    利用qt检测U盘插拔,思路有用qt的qdbus,dbus接收HAL的消息,或者是接收udisks的消息,这两种方法在x86平台上是可行的,但到板子里就不行。板子里不一定有HAL的,而HAL往板子里移植网上么有半点资料。udisk也没有移植的资料。更要命的是,不管hal也好udisks也好,他们得到的消息都是udev发过来的。而udev需要sysfs文件系统的支持,但现在arm板子上大多数都是yaffs或yaffs2文件系统的支持。尽管有udev移植的资料,但往yaffs、yaffs2文件系统移植,是移植不了的。最后一步配置的时候,配置不了。

     洒家最终要在tiny210开发板上实现此功能,难道走投无路了么??发火非也,参考我的上篇博客,linux整个处理usb的消息机制是这样的:内核----hotplug机制----udev---------HAL/UDISKS--------dbus.尽管网上很多人说hotplug淘汰了,但貌似现在开发板上用的都是hotplug。因此如果要用qt实现检测arm上U盘插拔的话,hotplug才是正道,不要贪了qt封装好的几个QDBUS接口的函数!

这篇文章就先谈一下,pc机上用qt自带的qdbus类,得到hal或udisks消息,来实现检测U盘插拔。咱废话多不说,请看程序:

1,widget.h里面添加:

#include <QtDBus/QDBusInterface>
#include <QtDBus/QDBusConnection>    //QDBusConnection

 

#define  DBUS_HAL_SERVICE          "org.freedesktop.Hal"
#define DBUS_HAL_PATH              "/org/freedesktop/Hal/Manager"
#define DBUS_HAL_INTERFACE         "org.freedesktop.Hal.Manager"
#define DBUS_HAL_DEVICE_PATH       "/org/freedesktop/Hal/devices"
#define DBUS_HAL_DEVICE_INTERFACE  "org.freedesktop.Hal.Device"


 private slots:
 void slotDeviceAdded(QString udi);
 void slotDeviceRemoved(QString udi);

2,widget.cpp里面添加

       QDBusInterface *dBusInterface = new QDBusInterface(DBUS_HAL_SERVICE,
                                                          DBUS_HAL_PATH,
                                                        DBUS_HAL_INTERFACE,
                                                      QDBusConnection::systemBus(),
                                                       this);

           if(!dBusInterface->isValid())
           qDebug()<<tc->toUnicode("初始化错误,找不到QDBusInterface!")<<QDBusConnection::systemBus().lastError().message();
      connect(dBusInterface, SIGNAL(DeviceAdded(QString)), this, SLOT(slotDeviceAdded(QString)));
       connect(dBusInterface, SIGNAL(DeviceRemoved(QString)), this, SLOT(slotDeviceRemoved(QString)));

然后就是两个槽函数:

void Widget::slotDeviceAdded(QString udi)
{
    static int num = 0;
    QDBusInterface *device = new QDBusInterface(DBUS_HAL_SERVICE, udi, DBUS_HAL_DEVICE_INTERFACE, QDBusConnection::systemBus(), this);

    if(!device->isValid())
        qDebug()<<tc->toUnicode("创建device失败!");
    else
        num++;
    QString devicePath = device->path();
    qDebug()<<tc->toUnicode("正在识别usb_device")<<num<<tc->toUnicode("号----路径:")<<devicePath;
    if(devicePath.contains("volume"))
    {
        qDebug()<<tc->toUnicode("恭喜您,U盘找到了。name:")<<udi;
        currentUDI = udi;
      }
    else
        qDebug()<<tc->toUnicode("识别结果:不是USB存储设备!");

}

void Widget::slotDeviceRemoved(QString udi)
{

    if(udi == currentUDI || udi.contains("volume"))
    {
        qDebug()<<tc->toUnicode("您的U盘已弹出!")<<udi;
        currentUDI = "";
    }
    else
         qDebug()<<"usb_device="<<udi<<tc->toUnicode("已弹出---");
}

 

 这里的udi就是注册usb设备的路径!大家可以打印出来看看,注册的时候大概注册了七个,拔出U盘的时候也是打印了7个消息。如果没有前面头文件的.h里的define,可以在widget.CPP文件里new QDBusInterface时候直接写上。这里我推荐用这种先声明一个变量,然后连接槽函数的方法。网上有人做法如下:

    //   // QDBusConnection::systemBus().connect(DBUS_HAL_SERVICE,
    //                                         DBUS_HAL_PATH,
    //                                         DBUS_HAL_INTERFACE,
    //                                         "DeviceAdded",
    //                                         this,
    //                                         SLOT(slotDeviceAdded(QString )));

    //    QDBusConnection::systemBus().connect(DBUS_HAL_SERVICE,
    //                                         DBUS_HAL_PATH,
    //                                         DBUS_HAL_INTERFACE,
    //                                         "DeviceRemoved",
    //                                         this,
    //                                         SLOT(slotDeviceRemoved(QString )));

也是可以的!

最坑爹的是有些人只说DBUS_HAL_SERVICE、DBUS_HAL_PATH不交代前面的宏定义!

另外就是,如果不想通过hal得到消息,可以通过udisks得到消息,如下:

  1. QDBusConnection ::systemBus().connect(
  2.                          "org.freedesktop.UDisks",
  3.                          "/org/freedesktop/UDisks",
  4.                          "org.freedesktop.UDisks",
  5.                          "DeviceAdded",
  6.                          this, SLOT(deviceAdded( QDBusObjectPath ));
  7.  
  8. void deviceAdded( QDBusObjectPath dev){
  9.  
  10.                          qDebug()<<"device added!"<<dev.path();
  11. }

这样就是通过udisks来检测,至于原理大家看我前面博文把。

网上有个公开的用此思路写的较为完整的源码:http://download.csdn.net/detail/yanzi1225627/4507716,具体能运行否我没试。

另外,老外的http://qt-project.org/forums/viewthread/8595这个比较好。

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
可以使用DBus来检测U盘的热插拔。DBus是Linux中一种常用的进程间通信机制,可以用于应用程序之间或者应用程序和系统之间的通信。 具体实现步骤如下: 1. 安装DBus库和开发包 ``` sudo apt-get install libdbus-1-dev libdbus-glib-1-dev ``` 2. 编写DBus服务 DBus服务是一个后台进程,用于监听系统事件。在这里,我们需要监听U盘的热插拔事件。 ```c++ #include <dbus/dbus-glib.h> #include <glib.h> #include <stdio.h> static void signal_handler(DBusGProxy *proxy, const char *sender_name, const char *object_path, const char *interface_name, const char *signal_name, GArray *args, gpointer user_data) { // 打印信号名和携带的参数 printf("Signal: %s, Args: %d\n", signal_name, args->len); } int main(int argc, char **argv) { DBusGConnection *connection; GError *error = NULL; // 初始化DBus连接 g_type_init(); connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); if (connection == NULL) { g_printerr("Failed to open connection to bus: %s\n", error->message); g_error_free(error); return 1; } // 注册监听U盘插拔事件的DBus服务 DBusGProxy *proxy = dbus_g_proxy_new_for_name(connection, "org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager"); if (proxy == NULL) { g_printerr("Failed to create proxy for org.freedesktop.Hal.Manager\n"); return 1; } dbus_g_proxy_add_signal(proxy, "DeviceAdded", G_TYPE_STRING, G_TYPE_INVALID); dbus_g_proxy_add_signal(proxy, "DeviceRemoved", G_TYPE_STRING, G_TYPE_INVALID); dbus_g_proxy_connect_signal(proxy, "DeviceAdded", G_CALLBACK(signal_handler), NULL, NULL); dbus_g_proxy_connect_signal(proxy, "DeviceRemoved", G_CALLBACK(signal_handler), NULL, NULL); // 运行DBus主循环 GMainLoop *loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); // 清理DBus连接 g_object_unref(proxy); dbus_g_connection_unref(connection); return 0; } ``` 3. 编译并运行DBus服务 ``` gcc -o dbus-service dbus-service.c `pkg-config --libs --cflags dbus-glib-1` ./dbus-service ``` 4. 测试DBus服务 插入或拔出U盘后,DBus服务会打印出相应的热插拔事件。 注意:DBus服务需要以root权限运行才能监听系统事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值