Created
November 17, 2013 01:14
-
-
Save YuuichiAkagawa/7507698 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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