/** * code from the book Arduino + Android Projects for the Evil Genius * <br>Copyright 2011 Simon Monk * * <p>This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation (see COPYING). * * <p>This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ package org.simonmonk.duinodroid; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import com.android.future.usb.UsbAccessory; import com.android.future.usb.UsbManager; import android.app.Activity; import android.app.AlertDialog; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class OpenAccessoryTest extends Activity implements Runnable { private EditText mByteField; private EditText mResponseField; private Button mSendButton; private static final String ACTION_USB = "com.simonmonk.action.USB_ACTION"; private PendingIntent mPermissionIntent; private boolean mPermissionRequestPending; private UsbManager mUsbManager; private UsbAccessory mAccessory; private ParcelFileDescriptor mFileDescriptor; private FileInputStream mInputStream; private FileOutputStream mOutputStream; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mByteField = (EditText) findViewById(R.id.messagebyte); mResponseField = (EditText) findViewById(R.id.arduinoresponse); mSendButton = (Button) findViewById(R.id.sendButton); mSendButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { sendMessageToArduino(); } }); setupAccessory(); } @Override public Object onRetainNonConfigurationInstance() { if (mAccessory != null) { return mAccessory; } else { return super.onRetainNonConfigurationInstance(); } } @Override public void onResume() { log("Resuming"); super.onResume(); if (mInputStream != null && mOutputStream != null) { log("Resuming: streams were not null"); } else { log("Resuming: streams were null"); establishPermissionsAndOpenAccessory(); } } private void establishPermissionsAndOpenAccessory() { UsbAccessory[] accessories = mUsbManager.getAccessoryList(); UsbAccessory accessory = (accessories == null ? null : accessories[0]); if (accessory != null) { if (mUsbManager.hasPermission(accessory)) { openAccessory(accessory); } else { log("In establishPermissionsAndOpenAccessory: accessory didnt have permission"); synchronized (mUsbReceiver) { if (!mPermissionRequestPending) { mUsbManager.requestPermission(accessory, mPermissionIntent); mPermissionRequestPending = true; } } } } else { log("onResume:mAccessory is null"); } } @Override public void onPause() { log("Pausing"); super.onPause(); } @Override public void onDestroy() { log("Destroying"); unregisterReceiver(mUsbReceiver); super.onDestroy(); } Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { ValueMsg t = (ValueMsg) msg.obj; log("Arduino sent: " + t.getFlag() + " " + t.getReading()); } }; private void setupAccessory() { log("In setupAccessory"); mUsbManager = UsbManager.getInstance(this); mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent( ACTION_USB), 0); IntentFilter filter = new IntentFilter(ACTION_USB); filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED); registerReceiver(mUsbReceiver, filter); if (getLastNonConfigurationInstance() != null) { mAccessory = (UsbAccessory) getLastNonConfigurationInstance(); openAccessory(mAccessory); } } private void openAccessory(UsbAccessory accessory) { log("In openAccessory"); mFileDescriptor = mUsbManager.openAccessory(accessory); if (mFileDescriptor != null) { mAccessory = accessory; FileDescriptor fd = mFileDescriptor.getFileDescriptor(); mInputStream = new FileInputStream(fd); mOutputStream = new FileOutputStream(fd); Thread thread = new Thread(null, this, "OpenAccessoryTest"); thread.start(); alert("openAccessory: Accessory openned"); log("Attached"); } else { log("openAccessory: accessory open failed"); } } private void closeAccessory() { log("In closeAccessory"); try { if (mFileDescriptor != null) { mFileDescriptor.close(); } } catch (IOException e) { } finally { mFileDescriptor = null; mAccessory = null; mInputStream = null; // srm mOutputStream = null; // srm } } private int composeInt(byte hi, byte lo) { int val = (int) hi & 0xff; val *= 256; val += (int) lo & 0xff; return val; } public void run() { int ret = 0; byte[] buffer = new byte[16384]; int i; while (true) { // keep reading messages forever. There are probably lots // of messages in the buffer, each 4 bytes try { ret = mInputStream.read(buffer); } catch (IOException e) { break; } i = 0; while (i < ret) { int len = ret - i; if (len >= 2) { Message m = Message.obtain(mHandler); int value = composeInt(buffer[i], buffer[i + 1]); m.obj = new ValueMsg('a', value); mHandler.sendMessage(m); } i += 2; } } } public void sendMessageToArduino() { String valueStr = mByteField.getText().toString(); byte val; try { val = Byte.parseByte(valueStr); log("Sending to Arduino: " + val); sendCommand(val); } catch (NumberFormatException e) { // TODO Auto-generated catch block e.printStackTrace(); alert("The Byte should be a number between 0 and 255"); } } public void sendCommand(byte value) { byte[] buffer = new byte[1]; buffer[0] = (byte) value; if (mOutputStream != null) { try { mOutputStream.write(buffer); } catch (IOException e) { log("Send failed: " + e.getMessage()); } } else { log("Send failed: mOutStream was null"); } } private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) { UsbAccessory accessory = UsbManager.getAccessory(intent); if (accessory != null && accessory.equals(mAccessory)) { log("Detached"); closeAccessory(); } } } }; private void log(String string) { String contents = mResponseField.getText().toString(); mResponseField.setText(string + "\n" + contents); } public void alert(String message) { AlertDialog alertDialog = new AlertDialog.Builder(this).create(); alertDialog.setTitle("Alert"); alertDialog.setMessage(message); alertDialog.setButton("OK", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { return; } }); alertDialog.show(); } }