Skip to content

Instantly share code, notes, and snippets.

@YuuichiAkagawa
Created November 17, 2013 01:14
Show Gist options
  • Save YuuichiAkagawa/7507698 to your computer and use it in GitHub Desktop.
Save YuuichiAkagawa/7507698 to your computer and use it in GitHub Desktop.
package org.ammlab.android.usbmiditest;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.LinkedList;
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.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.view.Menu;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ToggleButton;
public class MainActivity extends Activity implements Runnable{
private static final String TAG = "MIDItest";
public static final int MAX_PAYLOAD = 64;
private UsbManager mUsbManager;
private UsbDevice mDevice;
private UsbDeviceConnection mConnection;
private UsbEndpoint mEPout;
private UsbEndpoint mEPin;
private ToggleButton mToggleButton;
private final ByteBuffer mDataBuffer;
// pool of requests for the OUT endpoint
private final LinkedList<UsbRequest> mOutRequestPool = new LinkedList<UsbRequest>();
// pool of requests for the IN endpoint
private final LinkedList<UsbRequest> mInRequestPool = new LinkedList<UsbRequest>();
public MainActivity(){
mDataBuffer = ByteBuffer.allocate(MAX_PAYLOAD);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToggleButton = (ToggleButton) findViewById(R.id.toggleButton1);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
// HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
// UsbDevice device = deviceList.get("deviceName");
for (UsbDevice device : mUsbManager.getDeviceList().values()) {
Log.i(TAG,"Devices : "+device.toString());
}
mToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
byte value = (byte) (isChecked ? 0x1 : 0x0);
sendCommand(value);
}
});
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onResume() {
super.onResume();
Intent intent = getIntent();
Log.d(TAG, "intent: " + intent);
String action = intent.getAction();
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
setDevice(device);
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
if (mDevice != null && mDevice.equals(device)) {
setDevice(null);
}
}
}
@Override
public void onDestroy() {
super.onDestroy();
}
private void setDevice(UsbDevice device) {
Log.d(TAG, "setDevice " + device);
Log.d(TAG, " getInterfaceCount()=" + device.getInterfaceCount());
if (device.getInterfaceCount() != 2) {
Log.e(TAG, "could not find interface");
return;
}
UsbInterface intf = device.getInterface(1);
// device should have one endpoint
Log.d(TAG, " getEndpointCount()=" + intf.getEndpointCount());
if (intf.getEndpointCount() != 2) {
Log.e(TAG, "could not find endpoint");
return;
}
UsbEndpoint epOut = null;
UsbEndpoint epIn = null;
// look for our bulk endpoints
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
epOut = ep;
} else {
epIn = ep;
}
}
}
if (epOut == null || epIn == null) {
throw new IllegalArgumentException("not all endpoints found");
}
mEPout = epOut;
mEPin = epIn;
mDevice = device;
if (device != null) {
UsbDeviceConnection connection = mUsbManager.openDevice(device);
if (connection != null && connection.claimInterface(intf, true)) {
Log.d(TAG, "open SUCCESS");
mConnection = connection;
Thread thread = new Thread(this);
thread.start();
} else {
Log.d(TAG, "open FAIL");
mConnection = null;
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void sendCommand(byte value) {
synchronized (this) {
if (mConnection != null) {
if (value == 0){
byte[] message = new byte[4];
message[0] = (byte)(0x08 & 0xff);
message[1] = (byte)(0x80 & 0xff);
message[2] = (byte)(0x3c & 0xff);
message[3] = (byte)(0x7f & 0xff);
// Send command via a control request on endpoint zero
mConnection.bulkTransfer(mEPout, message, message.length, 0);
}else{
byte[] message = new byte[4];
message[0] = (byte)(0x09 & 0xff);
message[1] = (byte)(0x90 & 0xff);
message[2] = (byte)(0x3c & 0xff);
message[3] = (byte)(0x7f & 0xff);
// Send command via a control request on endpoint zero
mConnection.bulkTransfer(mEPout, message, message.length, 0);
}
}
}
}
// get an OUT request from our pool
public UsbRequest getOutRequest() {
synchronized(mOutRequestPool) {
if (mOutRequestPool.isEmpty()) {
UsbRequest request = new UsbRequest();
request.initialize(mConnection, mEPout);
return request;
} else {
return mOutRequestPool.removeFirst();
}
}
}
// return an OUT request to the pool
public void releaseOutRequest(UsbRequest request) {
synchronized (mOutRequestPool) {
mOutRequestPool.add(request);
}
}
// get an IN request from the pool
public UsbRequest getInRequest() {
synchronized(mInRequestPool) {
if (mInRequestPool.isEmpty()) {
UsbRequest request = new UsbRequest();
request.initialize(mConnection, mEPin);
return request;
} else {
return mInRequestPool.removeFirst();
}
}
}
@Override
public void run() {
while (true) {
UsbRequest request = mConnection.requestWait();
if (request == null) {
break;
}
// put request back into the appropriate pool
if (request.getEndpoint() == mEPout) {
releaseOutRequest(request);
} else {
synchronized (mInRequestPool) {
mInRequestPool.add(request);
}
}
}
}
public boolean write() {
// synchronized (device) {
UsbRequest request = getOutRequest();
// request.setClientData(mDataBuffer);
if (request.queue(mDataBuffer, 4)) {
return true;
} else {
releaseOutRequest(request);
return false;
}
// }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment