如何从Android设备(响应程序)生成自定义MTP事件,并在Windows(启动器)中捕获事件



我需要做的事情:

  • 从响应程序(运行Android的Beaglebone Black(生成自定义供应商扩展事件,并在启动器中获取事件通知

我正在使用的内容:

  • 启动器-Windows 7上的C#.Net应用程序,使用portabledeviceapilib.dll(COM互操作(库的托管包装
  • 测试响应程序1-微软MTP模拟器3.0
  • 测试响应程序2-Beaglebone黑色运行Android果冻豆4.1.1

到目前为止我所做的工作:

我在启动器和响应程序之间进行了成功的端到端通信。我可以发送MTP命令并获得MTP响应。我还成功地从响应程序获得了标准事件通知。

问题

我在来自Android的USB数据包中看不到MTP事件代码,即使事件被启动器成功触发并接收。当我将Android中的标准事件代码更改为自定义偶数代码时,我仍然会收到相应的事件消息(详细信息如下(。

到目前为止我做了什么

在响应方方面,当浏览Android源代码时,我发现/frameworks/av/media/MTP/MTP.h中定义的MTP事件代码。

以下是为添加/删除对象而定义的事件ID。

#define MTP_EVENT_OBJECT_ADDED                      0x4002
#define MTP_EVENT_OBJECT_REMOVED                    0x4003

这些事件代码在MTP规范中进行了定义。

对于订阅发起方的活动,我遵循Darene Lewis的文章中的指导方针。我使用这里定义的常量中的事件的GUID。

当向设备中添加文件或从设备中删除文件时,会触发MTP事件通知,启动器会收到将事件ID映射到其中一个常量的通知。据我所知,GUID的前4个字节对应于事件ID。

以下是文件添加和删除事件的GUID。

public static Guid WPD_EVENT_OBJECT_ADDED  = new Guid( 0xA726DA95, 0xE207, 0x4B02, 0x8D, 0x44, 0xBE, 0xF2, 0xE8, 0x6C, 0xBF, 0xFC  );        
public static Guid WPD_EVENT_OBJECT_REMOVED  = new Guid( 0xBE82AB88, 0xA52C, 0x4823, 0x96, 0xE5, 0xD0, 0x27, 0x26, 0x71, 0xFC, 0x38  );

我的测试包括从设备中添加/删除文件。

当使用模拟器时,启动器成功地获得了两个事件通知,并且它们映射到上面定义的正确的WPD事件。此外,我确认这些事件代码显示在USB数据包中。

当使用Android设备时,启动器成功地获得了两个事件通知,并且它们映射到上面定义的正确的WPD事件。然而,我在USB数据包中没有看到任何事件代码。

我不明白COM互操作库是如何成功地收到事件通知的,即使数据包没有显示MTP事件代码。

由于我看不到数据包中的事件代码,因此无法测试将自定义事件代码从设备发送到启动器。

我做了一个实验,将上面指定的Android MTP事件代码修改为供应商扩展事件代码(如MTP规范中所述,为0xC000-0xC7FF(,并更新设备上的libmtp以查看会发生什么。

我原以为启动器永远不会得到这些事件,但令人惊讶的是,即使在更改了事件代码之后,COM互操作库仍然接收到这些事件,并将它们映射到正确的GUID。

总之,当使用Android时,我没有在USB消息中看到MTP事件代码,尽管启动器以某种方式成功地获得了通知。使用MTP模拟器时,我do查看USB消息中的MTP事件代码。

我找到了解决方案。

似乎当您使用操作系统执行引发事件的操作(例如,使用Windows资源管理器从设备中添加/删除文件(时,事件会被驱动程序(WPD?USB?(吞噬,尽管事件确实会被触发。即使当我使用硬件USB数据包分析器时,我也看不到事件数据包。当我使用设备本身引发事件时(MTP模拟器,安卓版BeagleBone Black(,数据包清晰可见。我不知道为什么连硬件分析器都不显示事件包。

为了解决我的问题(生成事件(,我在/frameworks/av/media/mtp/MtpServer.cpp中创建了一个重写的函数,该函数基于sendEvent((函数,但使用了自定义事件代码,并且成功了!

最新更新