MainActivity で、OnCreate メソッドから USB アクセサリを開こうとします。
uartInterface = new FT311UARTInterface(this);
uartInterface.usbmanager.requestPermission(uartInterface.usbaccessory, uartInterface.mPermissionIntent);
アプリの USB アクセサリの使用許可を確認した後、ftdi FT311UARTInterface.java の OpenAcessory メソッドでクラッシュします。クラッシュする前に OpenAccessory メソッドを数回実行します (一度だけ呼び出す必要があると思います!) filedescriptio(最初の行) を初期化しようとした後にクラッシュするようです。
//User must modify the below package with their package name
package com.switchpanel;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
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.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.widget.Toast;
/******************************FT311 GPIO interface class******************************************/
public class FT311UARTInterface extends Activity
{
private static final String ACTION_USB_PERMISSION = "com.switchpanel.USB_PERMISSION";
public UsbManager usbmanager;
public UsbAccessory usbaccessory;
public PendingIntent mPermissionIntent;
public ParcelFileDescriptor filedescriptor;
public FileInputStream inputstream;
public FileOutputStream outputstream;
public boolean mPermissionRequestPending = true;
public handler_thread handlerThread;
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;
private byte maxnumbytes = (byte)64;
public boolean datareceived = false;
UsbDevice device;
/*constructor*/
public FT311UARTInterface(Context context){
super();
/*shall we start a thread here or what*/
usbdata = new byte[64];
writeusbdata = new byte[64];
/*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);
// Log.d("LED", "usbmanager" +usbmanager);
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);
// HashMap<String, UsbDevice> deviceList = usbmanager.getDeviceList();
// device = deviceList.get("<deviceName>");
/* if (device != null)
Toast.makeText(this, "Device Found", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Device NOT Found", Toast.LENGTH_LONG).show();*/
inputstream = null;
outputstream = null;
// usbmanager.requestPermission(usbaccessory, mPermissionIntent);
}
/*reset method*/
public void Reset()
{
/*create the packet*/
writeusbdata[0] = 0x49;
writeusbdata[1] = 0x00;
writeusbdata[2] = 0x00;
writeusbdata[3] = 0x00;
/*send the packet over the USB*/
SendPacket(4);
}
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(byte numBytes, char[] 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 > 64){
numBytes = 64;
}
/*prepare the packet to be sent*/
for(int count = 0;count<numBytes;count++)
{
writeusbdata[count] = (byte)buffer[count];
}
SendPacket((int)numBytes);
return status;
}
/*read data*/
public byte ReadData(byte numBytes,char[] buffer, byte [] actualNumBytes)
{
status = 0x00; /*success by default*/
/*should be at least one byte to read*/
if((numBytes < 1) || (totalBytes == 0)){
actualNumBytes[0] = 0x00;
return status;
}
/*check for max limit*/
if(numBytes > 64){
numBytes = 64;
}
if(numBytes > 64){
numBytes = 64;
}
if(numBytes > totalBytes)
numBytes = (byte)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] = (char)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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*resume accessory*/
public void ResumeAccessory()
{
// Intent intent = getIntent();
if (inputstream != null && outputstream != null) {
return;
}
UsbAccessory[] accessories = usbmanager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (usbmanager.hasPermission(accessory)) {
OpenAccessory(accessory);
}
else
{
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
usbmanager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {}
}
/*destroy accessory*/
public void DestroyAccessory(){
unregisterReceiver(mUsbReceiver);
CloseAccessory();
}
/*********************helper routines*************************************************/
public void OpenAccessory(UsbAccessory accessory)
{
filedescriptor = usbmanager.openAccessory(accessory);
if(filedescriptor != null){
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){
return;
}
}
handlerThread = new handler_thread(handler, inputstream);
handlerThread.start();
}
//private
public 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;
System.exit(0);
}
/***********USB broadcast receiver*******************************************/
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
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
{
Log.d("LED", "permission denied for accessory "+ accessory);
}
mPermissionRequestPending = false;
}
}
else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action))
{
UsbAccessory accessory = (UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
if (accessory != null )//&& accessory.equals(usbaccessory))
{
CloseAccessory();
}
}else
{
Log.d("LED", "....");
}
}
};
final Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
for(int count = 0;count<readcount;count++){
readBuffer[writeIndex] = usbdata[count];
/*move to the next write location*/
writeIndex++;
writeIndex %= maxnumbytes;
/*FIXME,check for overflow*/
//if(writeIndex == readIndex){
//}
}
/*caluclate the available bytes to read*/
if(writeIndex >= readIndex)
totalBytes = writeIndex-readIndex;
else
totalBytes = (maxnumbytes-readIndex)+writeIndex;
}
};
/*usb input data handler*/
private class handler_thread extends Thread {
Handler mHandler;
FileInputStream instream;
handler_thread(Handler h,FileInputStream stream ){
mHandler = h;
instream = stream;
}
public void run()
{
while(true)
{
Message msg = mHandler.obtainMessage();
try{
if(instream != null)
{
readcount = instream.read(usbdata,0,64);
if(readcount > 0)
{
datareceived = true;
msg.arg1 = usbdata[0];
msg.arg2 = usbdata[1];
}
mHandler.sendMessage(msg);
}
}catch (IOException e){}
}
}
}
ログキャットはこちら
02-13 18:09:34.398: D/AndroidRuntime(31211): Shutting down VM
02-13 18:09:34.398: W/dalvikvm(31211): threadid=1: thread exiting with uncaught exception (group=0x40a3e1f8)
02-13 18:09:34.418: E/AndroidRuntime(31211): FATAL EXCEPTION: main
02-13 18:09:34.418: E/AndroidRuntime(31211): java.lang.RuntimeException: Error receiving broadcast Intent { act=com.switchpanel.USB_PERMISSION flg=0x10 (has extras) } in com.switchpanel.FT311UARTInterface$1@410af418
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:737)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.os.Handler.handleCallback(Handler.java:605)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.os.Handler.dispatchMessage(Handler.java:92)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.os.Looper.loop(Looper.java:137)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.app.ActivityThread.main(ActivityThread.java:4424)
02-13 18:09:34.418: E/AndroidRuntime(31211): at java.lang.reflect.Method.invokeNative(Native Method)
02-13 18:09:34.418: E/AndroidRuntime(31211): at java.lang.reflect.Method.invoke(Method.java:511)
02-13 18:09:34.418: E/AndroidRuntime(31211): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
02-13 18:09:34.418: E/AndroidRuntime(31211): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
02-13 18:09:34.418: E/AndroidRuntime(31211): at dalvik.system.NativeStart.main(Native Method)
02-13 18:09:34.418: E/AndroidRuntime(31211): Caused by: java.lang.NullPointerException
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.os.Parcel.readException(Parcel.java:1333)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.os.Parcel.readException(Parcel.java:1281)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.hardware.usb.IUsbManager$Stub$Proxy.openAccessory(IUsbManager.java:395)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.hardware.usb.UsbManager.openAccessory(UsbManager.java:298)
02-13 18:09:34.418: E/AndroidRuntime(31211): at com.switchpanel.FT311UARTInterface.OpenAccessory(FT311UARTInterface.java:268)
02-13 18:09:34.418: E/AndroidRuntime(31211): at com.switchpanel.FT311UARTInterface$1.onReceive(FT311UARTInterface.java:329)
02-13 18:09:34.418: E/AndroidRuntime(31211): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728)
02-13 18:09:34.418: E/AndroidRuntime(31211): ... 9 more