您好,欢迎来到尔游网。
搜索
您的当前位置:首页蓝牙 hid

蓝牙 hid

来源:尔游网
Android USB Host与HID通讯 (一)

去年9月份来到现在的公司,接到新公司的第一个项目就是Android USB Host与HID通讯,当时也什么都不懂,就拿着google的api 开发指南

(http://developer.android.com/guide/topics/connectivity/usb/host.html)反复的阅读反复的实验,网上的资料也只能发现 / 枚举到U盘等设备,进行HID通讯、数据传输的资料很少,当时老大给我的时间是整整一个月,听到这我说:我尽量… 因为当时发了一两篇博文(Android USB Host 与 HID 通讯方法),最近有些Android开发攻城师在我的博客问,说具体要怎么做,如何处理?但最近手上有一大堆TabletSystem Bug,下班后再也不想继续,就一直没怎么回复,今天周六公司调班,想干点别的,就跟大家一起交流交流Android USB Host与HID 通讯。

首先,大家如果想了解啥是USB Host,那大家还是自己去学习学习吧,多看些一手的资料,别总是穿二手鞋(这是前辈对我的忠告)。跟我之前一样完全不知道Android USB Host的可以反复阅读下上面提到的google api 开发指南,我是反复的看了一遍又一遍,中文的英文的(英文有点戳),除了Host外,还有个Accessory,感兴趣的都可以了解下。。 其次,当时公司给我的HID设备既有需要驱动的也有无驱的,而公司给我的板子没有相应的驱动。只能发现无驱HID,若要发现有驱动的HID设备则需要另加上相应的设备驱动,否则你将无法发现你的HID设备。至于,怎么添加相应的驱动,这就需要请教写驱动的攻城师同胞,暂时还未向这方面发展,以后有机会可以横向发展下。

先看看AndroidManifest.xml文件,对于刚接触最好从简单入手,在AndroidManifest.xml中加上intent-filter过滤器,可以先不做请求权限的处理,因为intent-filter方式可以自动请求权限。 1) 添加USB HOST权限

2)添加意图过滤器,并配置自己的资源文件指定USB设备的属性,而资源文件为一个xml文件,如:device_filter.xml

android:name=\"android.hardware.usb.action.USB_DEVICE_ATTACHED\" android:resource=\"@xml/device_filter\"/>

3)对于资源文件device_filter.xml,需要配置设备的product-id 和vendor-id,如下:

接下来就是java代码,主要包括:枚举设备->找到设备的接口->连接设备->分配相应的端点->在IN端点进行读操作,在OUT端点进行写操作。在此可以不做请求权限处理,因为意图过滤器已经帮我们做了,若要进行动态请求权限的可以在此基础上再做扩展。

1)获取USB管理器,若获取失败,return。

mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); if(mUsbManager == null) { return; }

2)枚举Host上所有的HID设备,存入一个列表,若列表不为空,枚举到设备,可以用getVendorId()和getProductId()方法获取到设备的VendorId和ProductId,可继续找设备的UsbInterface;若列表为空,未枚举到设备。 HashMap deviceList = mUsbManager.getDeviceList(); if (!deviceList.isEmpty()) {

for (UsbDevice device : deviceList.values()) {

if(device.getVendorId() == VendorID && device.getProductId()==ProductID) { mUsbDevice = device;

// 找到Device接口并分配相应端点 findIntfAndEpt(); } else {

Toast.makeText(context, \"NotFind VID and PID\ } } } else {

new AlertDialog.Builder(context).setTitle(\"未枚举到设备!\") .setMessage(\"请先连接设备,再重启程序。。\") .setCancelable(false)

.setNeutralButton(\"确定\ new DialogInterface.OnClickListener() { public voidonClick(DialogInterface dialog, int which) { //finish(); } }).show(); }

到此为止,就可以发现你的HID外设,后面的我抽时间尽快补上,主要流程还是:枚举设备->找到设备的接口->连接设备->分配相应的端点->在IN端点进行读操作,在OUT端点进行写操作。

Android USB Host与HID通讯 (二)

不好意思,从上一篇到现在确实比较忙,中间又外出了一段时间,虽然也上LOFTER,或者看到一些朋友QQ上加我,给我发信息询问,有些看到了有些可能没看到,偶尔回复了一两个,也不咋的详细,在此我想说,一方面原因在我,不应该叫大家加Q,然后各位朋友都直接QQ信息发过来,结果就变成,要么没看到,要么看到当时没回,后来想回的时候又找不到各位问的是什么,如果要找聊天记录又有几位朋友还找得到给我发的问题记录?另一方面,我们的生活中有一种东西叫Email,它真的很好用,不信大家可以试试。。请直接文后留言或者Email,ok? 【差满多乃几sina邮箱:han21912@sina.cn】 接上一篇:Android USB Host与HID通讯 (一)

从上篇已经可以枚举到HID设备,接下来看看寻找设备的接口和通信端点,即上篇中的findIntfAndEpt()方法; // find interface and assign end point private void findIntfAndEpt() { if (mUsbDevice == null) { return; }

// find the device interface

for (int i = 0; i < mUsbDevice.getInterfaceCount();) {

// 获取设备接口,一般都是一个接口,你可以打印getInterfaceCount()方法查看接

// 口的个数,在这个接口上有两个端点,OUT 和 IN UsbInterface intf = mUsbDevice.getInterface(i); Log.d(TAG, i + \" \" + intf);

if (intf.getInterfaceClass() == 8 && intf.getInterfaceSubclass() == 6 && // intf.getInterfaceProtocol() == 80) { //HID设备的相关信息 mInterface = intf; } break; }

if (mInterface != null) {

UsbDeviceConnection connection = null; // 判断是否有权限

if(mUsbManager.hasPermission(mUsbDevice)) {

// 打开设备,获取 UsbDeviceConnection 对象,连接设备,用于后面的通讯 connection = mUsbManager.openDevice(mUsbDevice); if (connection == null) { return; }

if (connection.claimInterface(mInterface, true)) { mDeviceConnection = connection; } else {

connection.close(); } } else {

Toast.makeText(context, \"没有权限\ } } }

上面主要用到UsbDevice.getInterface()方法和UsbManager.openDevice()方法,在连接上设备后,用UsbDeviceConnection 与 UsbInterface 进行端点设置和通讯,如下:

private void getEndpoint(UsbDeviceConnection connection, UsbInterface intf) { if (intf.getEndpoint(1) != null) { epOut = intf.getEndpoint(1); }

if (intf.getEndpoint(0) != null) { epIn = intf.getEndpoint(0); } }

在此我们获得了通讯的OUT和IN端点,也就是我们常说的输入输出,查看api可知一般1为OUT端点,0为IN端点,接下来的任务就是通讯了,而最终需要的就是connection,OUT/IN 端点,在加上你要发送的指令,打成命令包进行发送,若命令发送成功会返回相应的数据信息,当然不同的设备发送/接收命令模式不同,同一设备不同的命令也需具体处理,这就需要根据自己手上的设备而定,好好研究研究自己的HID,掌握它的命令发送/接收方式,我的设备发送/接收模式为:发送命令out(发送预发送命令+发送命令+接收发送成功信息);接收数据in(发送预接收命令+接收数据+接收数据成功信息)。

所以到这,主要的工作就是设备的通讯模式和bulkTransfer()方法的参数配置,如下是我的设备进行通讯的一个发送包,从下面可以看出,仅仅发送一个命令到HID设备,其实际进行了三次命令的发送接收,两OUT一IN,总共调用了三次bulkTransfer()方法;

// 发送包操作,发送OUT + 发送COM + 接收IN private void sendPackage(byte[] command) { int ret = -100;

int len = command.length; // 组织准备命令

byte[] sendOut = Commands.OUT_S; sendOut[8] = (byte) (len & 0xff); sendOut[9] = (byte) ((len >> 8) & 0xff); sendOut[10] = (byte) ((len >> 16) & 0xff); sendOut[11] = (byte) ((len >> 24) & 0xff); // 1,发送准备命令

ret = mDeviceConnection.bulkTransfer(epOut, sendOut, 31, 10000); if(ret != 31) { return; }

// 2,发送COM

ret = mDeviceConnection.bulkTransfer(epOut, command, len, 10000); if(ret != len) { return; }

// 3,接收发送成功信息

ret = mDeviceConnection.bulkTransfer(epIn, Commands.IN, 13, 10000); if(ret != 13) { return; } }

可以看出调用一次bulkTransfer()方法,若通讯成功,返回的应该是发送命令或返回信息的数据长度,一开始我的bulkTransfer()方法总是返回-1,一直处于通讯失败,这时我们应该做的事情,第一,好好的组织bulkTransfer()方法中的参数,endpoint为OUT还是IN,buffer,也就是我们要发送的命令,对此不太理解的可以反复查阅:① google开发指南,穿一手的鞋: http://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html ② 我之前发的一篇关于HID通讯方法的文章: Android USB Host 与 HID 之通讯方法 ;第二,重点还是你自己的HID设备,如何通讯,通讯方式等等。

简单Demo下载:http://www.oschina.net/code/snippet_811255_21652

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- axer.cn 版权所有 湘ICP备2023022495号-12

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务