android Usb host通信

符李腾 发布于 2013/08/05 18:47
阅读 2K+
收藏 1

@auyang410 你好,想跟你请教个问题:能帮我看看是哪里不对吗,怎么收发都不

package com.hhd;

import java.nio.ByteBuffer;
import java.util.HashMap;
import android.hardware.input.InputManager;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.InputDevice;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class Test extends Activity {
    private  UsbManager mUsbManager;
    private  UsbDevice  mUsbDevice;
    private  UsbDeviceConnection mUsbConnection;
    private  InputManager inputManager;
    private  UsbEndpoint  epOut,epIn;  
    private  UsbInterface mUsbInterface;
    private  final   int VendorID=4400;//4400
    private  final   int ProductID=12594;//12594
    private  final String ACTION_USB_PERMISSION="com.hhd.USB_PERMISSION";
    private Button button;
	@Override
	protected void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button=(Button)findViewById(R.id.button1);
		mUiThread=Thread.currentThread();
		mUsbManager=(UsbManager)getSystemService(USB_SERVICE);
	    HashMap<String, UsbDevice> map=	mUsbManager.getDeviceList();
		for (UsbDevice device : map.values()){
		    if(device.getVendorId()==VendorID&&device.getProductId()==ProductID){
		        setDevice(device);
		 }
		}
		button.setOnClickListener(new MyButton());
		readThread=new ReadThread();
		readThread.start();
		
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	//检测到设备,并赋值
	private void setDevice(UsbDevice device){
		if(device==null)
			return ;
		if(mUsbDevice!=null)
			mUsbDevice=null;
		mUsbDevice=device;
		//获取设备接口,一般都是一个接口,可以打印getInterfaceCount()查看接口个数,在这个接口上有两个端点,OUT和IN
	    for (int i = 0; i < mUsbDevice.getInterfaceCount();) {  
            UsbInterface intf = mUsbDevice.getInterface(i);  
            Log.d("UsbInterface接口---->", i + ":intf= " + intf);  
            mUsbInterface = intf;  
            break;  
        }  
	}
	
	/**
	 * UsbInterface 
	 * 进行端点设置和通讯
	 * @param intf
	 */
    private void setEndpoint() {
    	if(mUsbInterface==null) 
    		return ;
    	//设置接收数据的端点
    	if (mUsbInterface.getEndpoint(0) != null){
            epIn = mUsbInterface.getEndpoint(0);
        }
    	
    	//当端点为2的时候
    	if(mUsbInterface.getEndpointCount()==2){
    		//设置发送数据的断点
     	    if (mUsbInterface.getEndpoint(1) != null) 
                 epOut = mUsbInterface.getEndpoint(1);
    	  }
        }
	
	/**
	 * 关闭连接,情况部分对象
	 * @param device
	 * @param usbInterface
	 */
	private void closeDevice(){
		if(mUsbConnection!=null){
			synchronized (mUsbConnection){
				mUsbConnection.releaseInterface(mUsbInterface);
				mUsbConnection.close();
				mUsbConnection=null;
				epOut=null;
				epIn=null;
			}
		}
	}
	/**
	 * 关闭连接,情况所有对象
	 * @return
	 */
	private  boolean closeAll(){
		if(mUsbConnection!=null){
			synchronized (mUsbConnection){
				mUsbConnection.releaseInterface(mUsbInterface);
				mUsbConnection.close();
				mUsbConnection=null;
				epOut=null;
				epIn=null;
				mUsbInterface=null;
				mUsbDevice=null;
				return true;
			}
		}
		return false;
	}
	/**
	 * 打开连接
	 * @param device
	 */
	private  boolean openDevice(){
		if(mUsbDevice==null)
		  return false;
		//closeDevice();
		if(mUsbDevice!=null&&mUsbManager.hasPermission(mUsbDevice)){
	    	mUsbConnection=mUsbManager.openDevice(mUsbDevice);
		if(mUsbConnection!=null){
			boolean b=mUsbConnection.claimInterface(mUsbInterface, true);
			Log.d("openDevice()--->", "b="+b);
			if(b)
			   setEndpoint();
			
			return b;
			}
		}
		return false;
	}
    /*-----------------------------------------------------------------------*/
	private ReadThread readThread;
	/**
	 * 开启一个线程来处理数据,或对权限的判断
	 * @author FLT-PC
	 */
	private class ReadThread extends Thread{
		@Override
		public void run() {
			super.run();
			while (!isInterrupted()){
		         final  byte []  buffer=receiveAndOpen();//接收数据
		         if(buffer!=null)
		        	 onDataReceived(buffer);//接到的数据进行处理,并回信(发送数据)
		         else{
		        	 if(mUsbInterface!=null&&mUsbConnection!=null)
		        	 mUsbConnection.claimInterface(mUsbInterface, false);}
			}
		}
	}
	/**
	 * 接收到的数据进行处理,并且执行发送数据
	 * @param buffer  传过来的数据
	 */
	private void onDataReceived(final byte [] buffer){
		runOnUiThread1(new Runnable() {
			@Override
			public void run() {
				System.out.println("来;了");
				for (int i = 0; i <buffer.length; i++) {
					Log.e("onDataReceived-->","这个数据是:"+buffer[i]);
				}
				 if(mUsbInterface!=null&&mUsbConnection!=null)
				 mUsbConnection.claimInterface(mUsbInterface, false);
				
			}
		});
	}
 
	/**
	 * 接收数据和打开连接处理的关键
	 * @return
	 */
	private byte[] receiveAndOpen(){
		//打开连接成功则进行通信
		if(openDevice()){
			Log.d("receiveAndOpen---->", "打开连接成功");
			//用bulkTransfer接收数据
		final   byte [] by=	controlTransferGetData();
			//controlTransferGetData();//controlTransfer
		return by;
		}
		return null;
	}
	 /*----------------------------------接收数据------------------------------------------*/
	/**
	 * 用 UsbConnection.bulkTransfer接收数据的测试
	 * @return
	 */
	private byte []  bulkTransferGetData(){
		  byte  [] buffer=new byte[epIn.getMaxPacketSize()];
		  int n= mUsbConnection.bulkTransfer(epIn, buffer, buffer.length, 0);
		  Log.d("bulkTransferGetData---->", "n="+n);
		  if(n>0)
			  return buffer;
		  return null;
	  }
	/**
	 * 用UsbRequest--异步通信来接收数据
	 * @return
	 */
	private byte [] usbrequestGetData(){
		byte [] by=null;
		ByteBuffer buffer=ByteBuffer.allocate(epIn.getMaxPacketSize());
		UsbRequest request=new UsbRequest();
		request.setClientData(this);
		request.initialize(mUsbConnection, epIn);
		request.queue(buffer, epIn.getMaxPacketSize());
		if(mUsbConnection.requestWait()==request){
			by=buffer.array();
			Log.d("数据有了,当不一定是拿到的---->", "by="+by);
		}else{
			Log.d("接收数据失败了了---->", "唉...");
		}
		Log.d("为什么的呢:", "by="+by);
		return by;
	}
	/**
	 * 
	 * @return
	 */
	private byte [] controlTransferGetData(){
		byte [] buffer=new byte[8];
		//改下面参数只有后3个参数确定,其他的参数不懂
		int n=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN , 0x5f, 0, 0, buffer, 8, 1000);
		Log.d("controlTransferGetData方法执行的结果", "n="+n);
		if(n>0)
			return buffer;
		return null;
		
	}
	  /*--------------------------发送数据-----------------------------------*/
	private void sendData(){
		byte [] bs=new byte[6];
		bs[0]=0x42;bs[1]=0x45; bs[2]=0x47;
		bs[3]=0x01;bs[4]=0x01; bs[5]=0x01;
		mUsbConnection.bulkTransfer(epOut, bs, bs.length, 0);
	}
	
	  
	  
	private Handler handler=new Handler();
	
	/**
	 * 单击发送数据按钮发送数据
	 * @author FLT-PC
	 */
	class MyButton implements OnClickListener{
		@Override
		public void onClick(View v) {
			try {
				readThread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(openDevice()){
				sendData();
				mUsbConnection.claimInterface(mUsbInterface, false);
			}
			notify();
		}
	}
    private Thread mUiThread;
	public final void runOnUiThread1(Runnable runnable){
		if(Thread.currentThread()!=mUiThread){
			handler.post(runnable);
		}else{
			runnable.run();}
	}

	
	//设备连接或移除的广播
		BroadcastReceiver receiver=new BroadcastReceiver() {
			@Override
			public void onReceive(Context context, Intent intent) {
				String action=intent.getAction();
				if(UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))/*连接*/{
					 UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE); //拿到连接的设备
					 inputManager=(InputManager)Test.this.getSystemService(INPUT_SERVICE);
					 int [] id_device=  inputManager.getInputDeviceIds();//获取所有的设备id
				     InputDevice inputDevice=inputManager.getInputDevice(id_device[id_device.length-1]);
					 System.out.println("挂载的设备是什么:"+inputDevice+"\t设备:"+mUsbDevice);
					 if(device.getVendorId()==VendorID&&device.getProductId()==ProductID){
						 closeAll();
					 setDevice(device);
					 }
				}else if(UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action))/*移除*/{
					 UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
					 if(device.getVendorId()==VendorID&&device.getProductId()==ProductID)
					 /*关闭连接*/ closeAll();
				}
			}
		};
	
	
	@Override
	protected void onStart() {
		super.onStart();
		IntentFilter filter=new IntentFilter();
		filter.addAction(ACTION_USB_PERMISSION);
		filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
		filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
		registerReceiver(receiver, filter);
	}

	@Override
	protected void onResume() {
		super.onResume();
		unregisterReceiver(receiver);
		IntentFilter filter=new IntentFilter();
		filter.addAction(ACTION_USB_PERMISSION);
		filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
		filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
		registerReceiver(receiver, filter);
		HashMap<String, UsbDevice> map=	mUsbManager.getDeviceList();
		mUiThread=Thread.currentThread();
		for (UsbDevice device : map.values()){
		    if(device.getVendorId()==VendorID&&device.getProductId()==ProductID){
		    closeAll();
		    setDevice(device);
			}
		}
	}
	@Override
	protected void onStop() {
		super.onStop();
		unregisterReceiver(receiver);
	}
    
	
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		closeAll();
	}

	/**
	 * 又一个接收数据的方法,
	 * @return
	 */
	private byte [] otherData(){
		byte[] buffer = new byte[8];
        mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN , 0x5f, 0, 0, buffer, 8, 1000);
        mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0xa1, 0, 0, null, 0, 1000);
        //baud rate
        int  baudRate = 4800;
        long factor = 1532620800 / baudRate;
        int divisor = 3;
        while((factor > 0xfff0) && (divisor > 0)) {
            factor >>=3;
            divisor--;
        }
        factor = 0x10000-factor;
        short a = (short) ((factor & 0xff00) | divisor);
        short b = (short)(factor & 0xff);
        int m=-100;
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0x9a, 0x1312, a, null, 0, 1000);
        Log.d("m1----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0x9a, 0x0f2c, b, null, 0, 1000);
        Log.d("m2----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_IN,   0x95, 0x2518, 0, buffer, 8, 1000);
        Log.d("m3----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0x9a, 0x0518, 0x0050, null, 0, 1000);
        Log.d("m4----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0xa1, 0x501f, 0xd90a, null, 0, 1000);
        Log.d("m5----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0x9a, 0x1312, a, null, 0, 1000);
        Log.d("m6----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0x9a, 0x0f2c, b, null, 0, 1000);
        Log.d("m7----->", "m="+m);
        m=  mUsbConnection.controlTransfer(UsbConstants.USB_TYPE_VENDOR | UsbConstants.USB_DIR_OUT , 0xa4, 0, 0,   null, 0, 1000);
        Log.d("m8----->", "m="+m);
        return buffer;
	}
    
}
正常

加载中
0
x
xinruizhi

你解决了么?我现在bulkTransfer返回的都是-1,

符李腾
符李腾
回复 @符李腾 : 或者用epOut.getDirection()这个确定是不是输出端点 值为0是输出,128是输入的
符李腾
符李腾
你电脑上用 bus hound测试下数据 看下是不是收发正常的, 还有的 UsbInterface.getEndpoint(0),你确认下这个是输出还是输入的端点 电脑上用这个工具就知道顺序了
0
hjr888
hjr888
你好,你这个代码能方便发到我邮箱吗234718172@qq.com,我用的是Nexus 7开发板,我试过好几个识别枚举的代码,都枚举不出我的audio设备出来。如果可以的话请加我Q234718172,我想跟你讨论下。谢谢!!
0
zjb1025
zjb1025
你好,我也碰到同样的问题,不知道这个是怎么回事?能一起讨论下嘛,加Q:525368252
返回顶部
顶部