您的位置:首页 > 移动开发 > Android开发

UsbAccessory

2015-10-14 16:55 435 查看
最近搞的开发慢慢接近底层了,各种usb打印机,usb串口通信,蓝牙通信,搞得头挺晕,不过也学到了挺多,今天抽点时间总结下。

UsbAccessory 使用帮助类

//User must modify the below package with their package name
package com.UARTLoopback;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;

/******************************FT311 GPIO interface class******************************************/
public class FT311UARTInterface
{

private static final String ACTION_USB_PERMISSION =    "com.UARTLoopback.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor = null;
public FileInputStream inputstream = null;
public FileOutputStream outputstream = null;
public boolean mPermissionRequestPending = false;
public read_thread readThread;

private byte [] usbdata;
private byte []	writeusbdata;
private byte  [] readBuffer; /*circular buffer*/
private int readcount;
private int totalBytes;
private int writeIndex;
private int readIndex;
private byte status;
final int  maxnumbytes = 65536;

public boolean datareceived = false;
public boolean READ_ENABLE = false;
public boolean accessory_attached = false;

public Context global_context;

public static String ManufacturerString = "mManufacturer=FTDI";
public static String ModelString1 = "mModel=FTDIUARTDemo";
public static String ModelString2 = "mModel=Android Accessory FT312D";
public static String VersionString = "mVersion=1.0";

/*constructor*/
public FT311UARTInterface(Context context){
super();
global_context = context;
/*shall we start a thread here or what*/
usbdata = new byte[1024];
writeusbdata = new byte[256];
/*128(make it 256, but looks like bytes should be enough)*/
readBuffer = new byte [maxnumbytes];

readIndex = 0;
writeIndex = 0;
/***********************USB handling******************************************/

usbmanager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
context.registerReceiver(mUsbReceiver, filter);

inputstream = null;
outputstream = null;

}

public void SetConfig(int baud, byte dataBits, byte stopBits,
byte parity, byte flowControl)
{
/*prepare the baud rate buffer*/
writeusbdata[0] = (byte)baud;
writeusbdata[1] = (byte)(baud >> 8);
writeusbdata[2] = (byte)(baud >> 16);
writeusbdata[3] = (byte)(baud >> 24);

/*data bits*/
writeusbdata[4] = dataBits;
/*stop bits*/
writeusbdata[5] = stopBits;
/*parity*/
writeusbdata[6] = parity;
/*flow control*/
writeusbdata[7] = flowControl;

/*send the UART configuration packet*/
SendPacket((int)8);
}

/*write data*/
public byte SendData(int numBytes, byte[] buffer)
{
status = 0x00; /*success by default*/
/*
* if num bytes are more than maximum limit
*/
if(numBytes < 1){
/*return the status with the error in the command*/
return status;
}

/*check for maximum limit*/
if(numBytes > 256){
numBytes = 256;
}

/*prepare the packet to be sent*/
for(int count = 0;count<numBytes;count++)
{
writeusbdata[count] = buffer[count];
}

if(numBytes != 64)
{
SendPacket(numBytes);
}
else
{
byte temp = writeusbdata[63];
SendPacket(63);
writeusbdata[0] = temp;
SendPacket(1);
}

return status;
}

/*read data*/
public byte ReadData(int numBytes,byte[] buffer, int [] actualNumBytes)
{
status = 0x00; /*success by default*/

/*should be at least one byte to read*/
if((numBytes < 1) || (totalBytes == 0)){
actualNumBytes[0] = 0;
status = 0x01;
return status;
}

/*check for max limit*/
if(numBytes > totalBytes)
numBytes = totalBytes;

/*update the number of bytes available*/
totalBytes -= numBytes;

actualNumBytes[0] = numBytes;

/*copy to the user buffer*/
for(int count = 0; count<numBytes;count++)
{
buffer[count] = readBuffer[readIndex];
readIndex++;
/*shouldnt read more than what is there in the buffer,
* 	so no need to check the overflow
*/
readIndex %= maxnumbytes;
}
return status;
}

/*method to send on USB*/
private void SendPacket(int numBytes)
{
try {
if(outputstream != null){
outputstream.write(writeusbdata, 0,numBytes);
}
} catch (IOException e) {
e.printStackTrace();
}
}

/*resume accessory*/
public int ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return 1;
}
//获取accessory列表
UsbAccessory[] accessories = usbmanager.getAccessoryList();
if(accessories != null)
{
Toast.makeText(global_context, "Accessory Attached", Toast.LENGTH_SHORT).show();
}
else
{
accessory_attached = false;
return 2;
}
//这里取第一个accessory,因为一般手机设备只能有一个.这里不考虑多个的情况,
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
Toast.makeText(global_context, "getDescription"+accessory, Toast.LENGTH_LONG).show();
if( -1 == accessory.toString().indexOf(ManufacturerString))
{
Toast.makeText(global_context, "Manufacturer is not matched!", Toast.LENGTH_SHORT).show();
return 1;
}

if( -1 == accessory.toString().indexOf(ModelString1) && -1 == accessory.toString().indexOf(ModelString2))
{
Toast.makeText(global_context, "Model is not matched!", Toast.LENGTH_SHORT).show();
return 1;
}

if( -1 == accessory.toString().indexOf(VersionString))
{
Toast.makeText(global_context, "Version is not matched!", Toast.LENGTH_SHORT).show();
return 1;
}

Toast.makeText(global_context, "Manufacturer, Model & Version are matched!", Toast.LENGTH_SHORT).show();
accessory_attached = true;

if (usbmanager.hasPermission(accessory)) {
Toast.makeText(global_context, "usbmanager has permission", Toast.LENGTH_SHORT).show();
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
Toast.makeText(global_context, "Request USB Permission", Toast.LENGTH_SHORT).show();
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}

return 0;
}

/*destroy accessory*/
public void DestroyAccessory(boolean bConfiged){

Toast.makeText(global_context, "DestroyAccessory"+bConfiged, Toast.LENGTH_SHORT).show();
if(true == bConfiged){
READ_ENABLE = false;  // set false condition for handler_thread to exit waiting data loop
writeusbdata[0] = 0;  // send dummy data for instream.read going
SendPacket(1);
}
else
{
SetConfig(9600,(byte)1,(byte)8,(byte)0,(byte)0);  // send default setting data for config
try{Thread.sleep(10);}
catch(Exception e){}

READ_ENABLE = false;  // set false condition for handler_thread to exit waiting data loop
writeusbdata[0] = 0;  // send dummy data for instream.read going
SendPacket(1);
}

try{Thread.sleep(10);}
catch(Exception e){}
CloseAccessory();
}

/*********************helper routines*************************************************/

public void OpenAccessory(UsbAccessory accessory)
{
filedescriptor
4000
= usbmanager.openAccessory(accessory);
if(filedescriptor != null){
Toast.makeText(global_context, "filedescriptior!=null", Toast.LENGTH_SHORT).show();
usbaccessory = accessory;

FileDescriptor fd = filedescriptor.getFileDescriptor();

inputstream = new FileInputStream(fd);
outputstream = new FileOutputStream(fd);
/*check if any of them are null*/
if(inputstream == null || outputstream==null){
Toast.makeText(global_context, "connect fail", Toast.LENGTH_SHORT).show();
return;
}else
Toast.makeText(global_context, "connect success", Toast.LENGTH_SHORT).show();
if(READ_ENABLE == false){
Toast.makeText(global_context, "READ_ENABLE==false", Toast.LENGTH_SHORT).show();
READ_ENABLE = true;
readThread = new read_thread(inputstream);
readThread.start();
}
}else
Toast.makeText(global_context, "filedescriptior====null", Toast.LENGTH_SHORT).show();
}

private void CloseAccessory()
{
try{
if(filedescriptor != null)
filedescriptor.close();

}catch (IOException e){}

try {
if(inputstream != null)
inputstream.close();
} catch(IOException e){}

try {
if(outputstream != null)
outputstream.close();

}catch(IOException e){}
/*FIXME, add the notfication also to close the application*/

filedescriptor = null;
inputstream = null;
outputstream = null;
global_context.unregisterReceiver(mUsbReceiver);
System.exit(0);
}

/**
* 监听usb插入拔出的广播
* 以及请求获得usb权限的广播
*/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
//请求获得usb权限的广播
if (ACTION_USB_PERMISSION.equals(action))
{
synchronized (this)
{
UsbAccessory accessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false))
{
OpenAccessory(accessory);
}
else
{
Toast.makeText(global_context, "Deny USB Permission", Toast.LENGTH_SHORT).show();
Log.d("LED", "permission denied for accessory "+ accessory);

}

Toast.makeText(global_context, "BroadcastReceiver", Toast.LENGTH_SHORT).show();
mPermissionRequestPending = false;
}
}
//监听usb拔出的广播
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
DestroyAccessory(true);
}
}
};

/*usb input data handler*/
private class read_thread  extends Thread
{
FileInputStream instream;

read_thread(FileInputStream stream ){
instream = stream;
this.setPriority(Thread.MAX_PRIORITY);
}

public void run()
{
while(READ_ENABLE == true)
{
while(totalBytes > (maxnumbytes - 1024))
{
try
{
Thread.sleep(50);
}
catch (InterruptedException e) {e.printStackTrace();}
}

try
{
if(instream != null)
{
readcount = instream.read(usbdata,0,1024);
if(readcount > 0)
{
for(int count = 0;count<readcount;count++)
{
readBuffer[writeIndex] = usbdata[count];
writeIndex++;
writeIndex %= maxnumbytes;
}

if(writeIndex >= readIndex)
totalBytes = writeIndex-readIndex;
else
totalBytes = (maxnumbytes-readIndex)+writeIndex;

//					    		Log.e(">>@@","totalBytes:"+totalBytes);
}
}
}
catch (IOException e){e.printStackTrace();}
}
}
}
}
使用

<span style="white-space:pre">	</span>uartInterface.ResumeAccessory();
uartInterface.SetConfig(baudRate, dataBit, stopBit, parity, flowControl);


记得加上权限

<uses-feature android:name="android.hardware.usb.accessory"/>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  usb Android UsbAccessory