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

系统 3429 0

  利用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得到消息,如下:  

 QDBusConnection                    ::  systemBus  (  ).  connect  (  
 "org.freedesktop.UDisks"  ,  
 "/org/freedesktop/UDisks"  ,  
 "org.freedesktop.UDisks"  ,  
 "DeviceAdded"  ,  
 this  , SLOT  (deviceAdded  (      QDBusObjectPath                    )  )  ;  
 
 void deviceAdded  (      QDBusObjectPath                   dev  )  {  
 
 qDebug  (  )  <<  "device added!"  <<dev.  path  (  )  ;  
 }

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

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

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



更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论