Android USB Host 通信程序
换到了一家新公司,于是就有了新的项目。这次的项目 要用Android SDK与USB HID设备进行通信。第一次接触Android SDK,以及USB,记录下源程序、开发过程以及一些心得。
首先,要感谢网上“先行者”们的无私帮助,使得开始的工作进展比较顺利。这里提及两个非常好的网址,我的源码借鉴了这两个网址很多:
http://blog.csdn.net/tianruxishui/article/details/38338087
http://www.android-doc.com/guide/topics/connectivity/usb/host.html
以下是程序源码(目前只开发到探测部分,具体通信部分有待完善):
USB_Access.java:
- package com.example.vrgate_usb;
- import android.os.Bundle;
- import android.app.Service;
- import android.app.Activity;
- import android.content.Intent;
- import android.hardware.usb.*;
- import java.util.HashMap;
- import java.util.Hashtable;
- import java.util.Iterator;
- import android.widget.Toast;
- import android.content.Context;
- import android.widget.TextView;
- import android.content.BroadcastReceiver;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.app.PendingIntent;
- import android.os.Handler;
- public class USBAccess extends Activity {
- TextView View1 = null;
- TextView View2 = null;
- TextView View3 = null;
- TextView View4 = null;
- TextView View5 = null;
- TextView View6 = null;
- TextView View7 = null;
- TextView View8 = null;
- TextView View9 = null;
- TextView View10 = null;
- TextView View11 = null;
- UsbManager myUsbManager;
- UsbDevice myUsbDevice;
- UsbInterface Interface[];
- UsbDeviceConnection myDeviceConnection;
- UsbEndpoint epBulkOut, epBulkIn;
- UsbEndpoint epControl;
- UsbEndpoint epIntOut, epIntIn;
- int VendorID;
- int ProductID;
- //private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
- private static int TIMEOUT = 300;
- int ret = -1;
- byte[] recvBuffer = new byte[256];
- usb_hid usbHid;
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.usb_access);
- /*
- //usbHid = new usb_hid(this);
- usbHid = usb_hid.getInstance(this);
- if (usbHid.getUsbDevice() == 0)
- {
- this.setTitle("已连接0设备");
- }
- else if(usbHid.getUsbDevice() == -1)
- {
- this.setTitle("已连接-1设备");
- }
- else if(usbHid.getUsbDevice() == -2)
- {
- this.setTitle("已连接-2设备");
- }
- else if(usbHid.getUsbDevice() == -3)
- {
- this.setTitle("已连接-3设备");
- }
- else
- {
- this.setTitle("已连接-9设备");
- }*/
- View1 = (TextView) findViewById(R.id.Vendor_ID);
- View2 = (TextView) findViewById(R.id.Product_ID);
- View3 = (TextView) findViewById(R.id.Count);
- View4 = (TextView) findViewById(R.id.Interface_ID);
- View5 = (TextView) findViewById(R.id.Control_Endpoint);
- View6 = (TextView) findViewById(R.id.BulkIn_Endpoint);
- View7 = (TextView) findViewById(R.id.BulkOut_Endpoint);
- View8 = (TextView) findViewById(R.id.InterruptIn_Endpoint);
- View9 = (TextView) findViewById(R.id.InterruptOut_Endpoint);
- View10 = (TextView) findViewById(R.id.Serial_Number);
- View11 = (TextView) findViewById(R.id.Recv_Data);
- // 获取UsbManager
- myUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
- // 枚举设备
- enumerateDevice(myUsbManager);
- // 查找设备接口
- ret = getDeviceInterface();
- // 获取设备endpoint
- if(ret == 0)
- assignEndpoint(Interface[0]);
- // 打开conn连接通道
- if(ret == 0)
- {
- ret = openDevice(Interface[0]);
- }
- // 开始USB数据收发
- if(ret == 0)
- {
- UsbReadThread thread = new UsbReadThread();
- thread.start();
- final Handler handler= new Handler();
- final Runnable runnable = new Runnable() {
- public void run() {
- View11.setText("data 0:" + recvBuffer[0] + '\n'
- + "data 1:" + recvBuffer[1] + '\n'
- + "data 2:" + recvBuffer[2] + '\n'
- + "data 3:" + recvBuffer[3] + '\n');
- }
- };
- final Thread t = new Thread() {
- @Override
- public void run() {
- while(true)
- {
- handler.post(runnable); //加入到消息队列 这样没有启动新的线程,虽然没有报异常。但仍然阻塞ProgressDialog的显示
- try
- {
- sleep(10); //直接调用
- }
- catch (InterruptedException e)
- {
- return;
- }
- }
- }
- };
- t.start();
- }
- }
- public class UsbReadThread extends Thread {
- @Override
- public void run()
- {
- byte[] data = new byte[256];
- while(true)
- {
- receiveMessageFromEndpoint();
- //sendMessageToEndpoint(data);
- }
- }
- }
- @Override
- public void onResume() {
- super.onResume();
- }
- // 枚举设备函数
- private void enumerateDevice(UsbManager mUsbManager)
- {
- System.out.println("开始进行枚举设备!\n");
- if (mUsbManager == null)
- {
- System.out.println("创建UsbManager失败,请重新启动应用!");
- Context context = getApplicationContext();
- Toast.makeText(context, "创建UsbManager失败,请重新启动应用!", Toast.LENGTH_SHORT).show();
- return;
- }
- else
- {
- HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
- if (!(deviceList.isEmpty()))
- {
- // deviceList不为空
- System.out.println("已连接USB设备至PAD!\n");
- System.out.println("deviceList is not null!");
- Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
- while (deviceIterator.hasNext())
- {
- UsbDevice device = deviceIterator.next();
- // 输出设备信息
- //Log.i(TAG, "DeviceInfo: " + device.getVendorId() + " , " + device.getProductId());
- System.out.println("DeviceInfo:" + device.getVendorId() + " , " + device.getProductId());
- // 保存设备VID和PID
- VendorID = device.getVendorId();
- ProductID = device.getProductId();
- View1.setText("制造商 ID:" + VendorID); //东芝U盘:2352; VrGate Hid: 1155
- View2.setText("产品ID:" + ProductID); //东芝U盘:25924; VrGate Hid: 22352
- // 保存匹配到的设备
- if (VendorID == 1155 && ProductID == 22352) {
- //if (VendorID == 2352 && ProductID == 25924) {
- myUsbDevice = device; // 获取USBDevice
- System.out.println("发现待匹配设备:" + device.getVendorId() + "," + device.getProductId());
- Context context = getApplicationContext();
- Toast.makeText(context, "发现待匹配设备。", Toast.LENGTH_SHORT).show();
- }
- }
- }
- else
- {
- System.out.println("请连接USB设备至PAD!");
- Context context = getApplicationContext();
- Toast.makeText(context, "请连接USB设备至PAD!", Toast.LENGTH_SHORT).show();
- }
- }
- }
- // 寻找设备接口
- private int getDeviceInterface()
- {
- if (myUsbDevice != null)
- {
- int count = -1;
- //Log.d(TAG, "interfaceCounts : " + myUsbDevice.getInterfaceCount());
- count = myUsbDevice.getInterfaceCount();
- System.out.println("设备接口数:" + count);
- View3.setText("设备接口数:" + count);
- if (count <= 0)
- return -2;
- Interface = new UsbInterface[count];
- for (int i = 0; i < myUsbDevice.getInterfaceCount(); i++)
- {
- //UsbInterface intf = myUsbDevice.getInterface(i);
- Interface[i] = myUsbDevice.getInterface(i); // 保存设备接口
- System.out.println("成功获得设备接口:" + Interface[i].getId());
- View4.setText("接口号:" + Interface[i].getId());
- View1.setText("制造商 ID:" + VendorID + ";" + myUsbDevice.getInterfaceCount() + ";" + Interface[i].getInterfaceClass() + ";" + Interface[i].getInterfaceSubclass() + ";" + Interface[i].getInterfaceProtocol());
- }
- return 0;
- }
- else
- {
- System.out.println("设备为空!");
- return -1;
- }
- }
- // 分配端点,IN | OUT,即输入输出;可以通过判断
- private void assignEndpoint(UsbInterface mInterface)
- {
- if ((myUsbDevice != null) && (mInterface != null))
- {
- for (int i = 0; i < mInterface.getEndpointCount(); i++)
- {
- UsbEndpoint ep = mInterface.getEndpoint(i);
- int type = ep.getType();
- int direction = ep.getDirection();
- // look for bulk endpoint
- if (type == UsbConstants.USB_ENDPOINT_XFER_BULK)
- {
- if (direction == UsbConstants.USB_DIR_OUT)
- {
- epBulkOut = ep;
- System.out.println("Find the BulkEndpointOut," + "index:" + i + "," + "使用端点号:" + epBulkOut.getEndpointNumber());
- View7.setText("Find the BulkEndpointOut," + "index:" + i + "," + "使用端点号:" + epBulkOut.getEndpointNumber());
- }
- else
- {
- epBulkIn = ep;
- System.out.println("Find the BulkEndpointIn:" + "index:" + i + "," + "使用端点号:" + epBulkIn.getEndpointNumber());
- View6.setText("Find the BulkEndpointIn:" + "index:" + i + "," + "使用端点号:" + epBulkIn.getEndpointNumber());
- }
- }
- // look for control endpoint
- else if (type == UsbConstants.USB_ENDPOINT_XFER_CONTROL)
- {
- epControl = ep;
- System.out.println("find the ControlEndPoint:" + "index:" + i + "," + "使用端点号:" + epControl.getEndpointNumber());
- View5.setText("find the ControlEndPoint:" + "index:" + i + "," + "使用端点号:" + epControl.getEndpointNumber());
- }
- // look for interrupt endpoint
- else if (type == UsbConstants.USB_ENDPOINT_XFER_INT)
- {
- if (direction == UsbConstants.USB_DIR_OUT)
- {
- epIntOut = ep;
- System.out.println("find the InterruptEndpointOut:" + "index:" + i + "," + "使用端点号:" + epIntOut.getEndpointNumber());
- View9.setText("find the InterruptEndpointOut:" + "index:" + i + "," + "使用端点号:" + epIntOut.getEndpointNumber());
- }
- else
- {
- epIntIn = ep;
- System.out.println("find the InterruptEndpointIn:" + "index:" + i + "," + "使用端点号:" + epIntIn.getEndpointNumber());
- View8.setText("find the InterruptEndpointIn:" + "index:" + i + "," + "使用端点号:" + epIntIn.getEndpointNumber());
- }
- }
- }
- if (epBulkOut == null && epBulkIn == null && epControl == null && epIntOut == null && epIntIn == null)
- {
- throw new IllegalArgumentException("not endpoint is founded!");
- }
- }
- }
- // 打开设备
- public int openDevice(UsbInterface mInterface)
- {
- if (mInterface != null)
- {
- UsbDeviceConnection conn = null;
- Context context = getApplicationContext();
- // 在open前判断是否有连接权限;对于连接权限可以静态分配,也可以动态分配权限
- if (myUsbManager.hasPermission(myUsbDevice))
- {
- conn = myUsbManager.openDevice(myUsbDevice); //此处与device_filter.xml中的值密切相关!
- if (conn == null)
- {
- Toast.makeText(context, "打开设备失败,未找到该设备!", Toast.LENGTH_SHORT).show();
- return -2;
- }
- }
- else
- {
- Toast.makeText(context, "打开设备失败,无连接权限!", Toast.LENGTH_SHORT).show();
- return -3;
- }
- if (conn.claimInterface(mInterface, true))
- {
- myDeviceConnection = conn;
- //if (myDeviceConnection != null)// 到此你的android设备已经连上zigbee设备
- {
- System.out.println("open设备成功!");
- Toast.makeText(context, "打开设备成功!", Toast.LENGTH_SHORT).show();
- }
- final String mySerial = myDeviceConnection.getSerial();
- System.out.println("设备serial number:" + mySerial);
- View10.setText("设备序列号:" + mySerial);
- //View10.setText("端点数:" + mInterface.getEndpointCount());
- return 0;
- }
- else
- {
- System.out.println("无法打开连接通道。");
- Toast.makeText(context, "无法打开连接通道。", Toast.LENGTH_SHORT).show();
- conn.close();
- return -4;
- }
- }
- return -1;
- }
- // 发送数据
- private void sendMessageToEndpoint(byte[] buffer)
- {
- //if (buffer == null)
- // return;
- if(epIntOut != null)
- {
- // interruptOut传输
- if (myDeviceConnection.bulkTransfer(epIntOut, buffer, buffer.length, 0) < 0)
- {
- System.out.println("interruptOut返回输出为 负数!\n");
- recvBuffer[1] = -1;
- recvBuffer[2] = -5;
- return;
- }
- recvBuffer[1] = 4;
- recvBuffer[2] = 6;
- //System.out.println("Send Message Succeed.");
- }
- else if(epBulkOut != null)
- {
- // bulkOut传输
- if (myDeviceConnection.bulkTransfer(epBulkOut, buffer, buffer.length, 0) < 0)
- {
- recvBuffer[1] = -7;
- recvBuffer[2] = -5;
- System.out.println("bulkOut返回输出为 负数!\n");
- return;
- }
- recvBuffer[1] = 6;
- recvBuffer[2] = 4;
- //System.out.println("Send Message Succeed.");
- }
- }
- // 从设备接收数据bulkIn
- private byte[] receiveMessageFromEndpoint()
- {
- if(epIntIn != null)
- {
- if (myDeviceConnection.bulkTransfer(epIntIn, recvBuffer, 64, 0) < 0)
- {
- System.out.println("interruptIn返回输出为负数!\n");
- recvBuffer[0] = -3;
- recvBuffer[3] = -9;
- return null;
- }
- //System.out.println("Receive Message Succeed!" + "数据返回" + myDeviceConnection.bulkTransfer(epBulkIn, recvBuffer, recvBuffer.length, 3000));
- }
- else if(epBulkIn != null)
- {
- recvBuffer[0] = 3;
- recvBuffer[3] = 3;
- if (myDeviceConnection.bulkTransfer(epBulkIn, recvBuffer, recvBuffer.length, 0) < 0)
- {
- recvBuffer[0] = -2;
- recvBuffer[3] = -7;
- System.out.println("BulkIn返回输出为 负数!\n");
- return null;
- }
- //System.out.println("Receive Message Succeed!" + "数据返回" + myDeviceConnection.bulkTransfer(epBulkIn, recvBuffer, recvBuffer.length, 3000));
- }
- return recvBuffer;
- }
- }
Android USB Host 通信程序的更多相关文章
- Android USB Host 与 Hid 设备通信bulkTransfer()返回-1问题的原因
近期一直在做Android USB Host 与USB Hid设备(STM32FXXX)的通信,遇到了很多问题.项目源码以及所遇到的其他问题可以见本博客其他相关文章,这里重点讲一下bulkTransf ...
- Android USB Host与HID通讯
前端时间捣鼓一个HID的硬件, 需要和android通信, 网上搜索了一圈,收获不小. 比较好的文章是: Android USB Host与HID通讯 Android Service创建US ...
- 翻译Android USB HOST API
翻译Android USB HOST API 源代码地址:http://developer.android.com/guide/topics/connectivity/usb/host.html 译者 ...
- Android USB Host与HID通讯 (二)
不好意思,从上一篇到现在确实比较忙,中间又外出了一段时间,虽然也上LOFTER,或者看到一些朋友QQ上加我,给我发信息询问,有些看到了有些可能没看到,偶尔回复了一两个,也不咋的详细,在此我想说,一方面 ...
- Android USB Host与HID通讯 (一)
去年9月份来到现在的公司,接到新公司的第一个项目就是Android USB Host与HID通讯,当时也什么都不懂,就拿着google的api 开发指南 (http://developer.andro ...
- Android USB Host 与 HID 之通讯方法(bulkTransfer()与controlTransfer()方法使用)
转载地址:差满多乃几 Android USB Host与HID通讯,就目前Google Developer提供的方法有bulkTransfer()与controlTransfer(),看是简简单单的两 ...
- Android USB Host 与 HID 之通讯方法
Android USB Host与HID通讯,就目前Google Developer提供的方法有bulkTransfer()与controlTransfer(),看是简简单单的两个方法,要实现真正的通 ...
- 【转】Android Service创建USB HOST通信
之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...
- Android Service创建USB HOST通信
之前做了一个关于Android USB通信的Case,通过Android的USB总线给Zigbee供电,和板载的Zigbee(基于Zigbee的自组网)进行通信.要使用Android的USB Host ...
随机推荐
- ASP 生成带日期的随机数
<% Function getRnd() '**************************************** '返回值:如getRnd(),即输出2008082415534646 ...
- 0708_Java如何设置输入流
1.Java如何设置输入流:?(以解决看下面实例代码) 2.Java如何设置全局变量:(以解决public static即可) 3.Java为什么在做那种机试题目的时候都要设置成静态的:(以解决,因为 ...
- sql的游标使用(转)
游标是邪恶的! 在关系数据库中,我们对于查询的思考是面向集合的.而游标打破了这一规则,游标使得我们思考方式变为逐行进行.对于类C的开发人员来着,这样的思考方式会更加舒服. 正常面向集合的思维方式是: ...
- 备份BinLog并压缩 全备份
Rem Backup Mysql Binlog Rem Backup Yesterday and RAR Rem Backup every day 00:01 begin backup yesterd ...
- Jquery Ajax Get示例
$.ajax({ type: "GET", url:"ajax_url.php", cache: false, data:{'action':'ABC',' ...
- 06_init()和destroy()方法
[工程截图] [HelloWorld.java] package com.HigginCui; public class HelloWorld { public HelloWorld(){ Syste ...
- LevelDb原理剖析
在说LevelDb之前,先认识两位大牛,Jeff Dean和Sanjay Ghemawat,这两位是Google公司重量级的工程师,为数甚少的Google Fellow之二. Jeff Dean其人: ...
- MyBatis入门教程(基于Mybatis3.2)
MyBatis和Hibernate一样都是基于ORM的关系型数据库框架 ORM工具的基本思想: 1.从配置文件(通常是XML配置文件中)得到 sessionfactory. 2. 由sessionfa ...
- IE10访问Apache2.4卡死的问题
windows环境下,使用IE10访问Apache2.4时,服务器经常卡死 找到EnableSendfile on,在下一行添加如下配置解决: AcceptFilter http none Accep ...
- 【HeadFirst设计模式】12.复合模式
定义: 复合模式结合两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题. 要点: MVC模式是复合模式,结合了观察者模式.策略模式和组合模式. 模型使用了观察者模式,以便观察者更新,同时保存 ...