USB线插拔检测使用UEventObserver检测uevent事件的分析

说实话这玩样儿的代码量真的很少,大家如果能耐得住性子啃一会儿也就能撸懂了。

在这之前研究USB线插拔的时候就知道了有这么个东西,当时也就看了看,但没做什么笔记。最近想用起来,却发现就只有个名字在记忆中了。

 

好了,又扯了这么多,来回到正题。

 

首先按照技术博客一贯的作风,得先有个入口点,这里我就先从怎么使用这个UEventObserver开始一步步分析。

 

首先这玩样儿是java代码,所以你就别想着c++什么用了。

 

这里我举例了USB线插拔来分析,代码地址如下:


frameworks/base/services/java/com/android/server/usb/UsbDeviceManager.java

 

   /*

    * Listens for uevent messages from the kernel to monitor the USB state

    */

   private final UEventObserver mUEventObserver = new UEventObserver() {

       @Override

       public void onUEvent(UEventObserver.UEvent event) {

           if (DEBUG) Slog.v(TAG, "USB UEVENT: " + event.toString());

 

           String state =event.get("USB_STATE");

           String accessory = event.get("ACCESSORY");

           if (state != null) {

                mHandler.updateState(state);

           } else if ("START".equals(accessory)) {

                if (DEBUG) Slog.d(TAG,"got accessory start");

                startAccessoryMode();

           }

       }

   };


这里我们可以看到使用前必须先初始化一个新的UEventObserver类来处理事件,即函数onUEvent,这是一个回调函数,之后我们会看到他是怎么被调用的。这里这个回调函数根据处理的事件消息来判断是否要更新USB的状态,继而触发通知栏显示。

 

初始化完UEventObserver之后,我们还需要使用这个类,接下来的代码做了这个事。

 

   private static final String USB_STATE_MATCH =

           "DEVPATH=/devices/virtual/android_usb/android0";

 

       public UsbHandler(Looper looper) {

           super(looper);

                // Watch for USB configurationchanges

               mUEventObserver.startObserving(USB_STATE_MATCH);





从中我们看出他直接调用了UEventObserver的startObserving函数,并且指定了参数,即一段字符串。

 

接下来我们看下startObserving到底做了什么事。

    p
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C语言程序,用于检测USB设备的热插拔事件: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <linux/netlink.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #define UEVENT_BUFFER_SIZE 2048 int init_hotplug_sock() { const int buffersize = 1024; int ret; struct sockaddr_nl snl; bzero(&snl, sizeof(struct sockaddr_nl)); snl.nl_family = AF_NETLINK; snl.nl_pid = getpid(); snl.nl_groups = 1; int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); if (ret < 0) { perror("bind"); close(s); return -1; } return s; } int main(int argc, char* argv[]) { int hotplug_sock = init_hotplug_sock(); if (hotplug_sock < 0) return -1; char buffer[UEVENT_BUFFER_SIZE * 2] = {0}; while (1) { fd_set fds; FD_ZERO(&fds); FD_SET(hotplug_sock, &fds); int ret = select(hotplug_sock + 1, &fds, NULL, NULL, NULL); if (ret < 0) { perror("select"); continue; } if (FD_ISSET(hotplug_sock, &fds)) { memset(buffer, 0, sizeof(buffer)); ret = recv(hotplug_sock, &buffer, sizeof(buffer), MSG_DONTWAIT); if (ret > 0) { printf("Received %d bytes: %s\n", ret, buffer); } } } return 0; } ``` 这个程序创建了一个基于Netlink协议的socket,用于监听内核发出的UEVENT事件。当一个USB设备插入或拔出时,内核会发出一个UEVENT事件,这个程序就可以通过socket接收到这个事件,并进行相应的处理。 注意:这个程序只是一个简单的示例,实际的应用中可能需要根据具体的需求进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值