title: Sending and Receiving Data with Android and Arduino
body: <p>I am trying to write an Android application that can send and receive serial data to and from an Arduino board that is connected by an On-The-Go (OTG) adapter. I am using the <a href="http://code.google.com/p/usb-serial-for-android/" rel="nofollow">usb-serial-for-android</a> library.  I am setting the Arduino up so that if it receives the string "T" then it will send the string "T" back. The Android is set up so that it will do the same, although if the string variable dataToSend isn't empty then it will send the value of that along with the "T". I basically want these two to send data back and forth.  The Arduino side of this project is working perfectly, whenever it receives data it records everything to an SD card, and if it detects the "T" it will send a "T" back to tell the Android it can send again.</p>
  
  <p>Here is my code, sorry for the length but I feel that there could be multiple places that could be the problem:</p>
  
  <pre><code>public class MainActivity extends Activity {
  
  private boolean canSend;
  private boolean notInit; 
  private String dataToSend; 
  private UsbManager manager;
  private SerialInputOutputManager serialIoManager; 
  private static UsbSerialDriver sendDriver; 
  private static UsbSerialDriver recDriver; 
  private TextView outputText; 
  private ExecutorService mExecutor = Executors.newSingleThreadExecutor(); 
  private SerialInputOutputManager.Listener mListener = new    SerialInputOutputManager.Listener() {
  
      @Override
      public void onRunError(Exception e) {   }
  
      @Override
      public void onNewData(final byte[] data) {
  
          MainActivity.this.runOnUiThread(new Runnable() {
                      @Override
                      public void run() {
                          try {
  
                  MainActivity.this.updateReceivedData(data);
  
              } catch (IOException e) { e.printStackTrace(); }
                      }
                   });
  
      }
  }; 
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      dataToSend = ""; 
      notInit = true; 
      canSend = true; 
      outputText = (TextView) findViewById(R.id.textView1); 
  }
  
  @Override
      protected void onPause() {
      super.onPause();
      stopIoManager();
      if (recDriver != null) {
          try {
              recDriver.close();
          } catch (IOException e) {
              // Ignore.
          }
          recDriver = null;
      }
      finish();
  }
  
  @Override
  protected void onResume() {
      super.onResume();
  
          manager = (UsbManager) getSystemService(Context.USB_SERVICE);
          recDriver = UsbSerialProber.acquire(manager);
  
  
      if (recDriver == null) {
  
          } else {
                try {
                    recDriver.open();
                    recDriver.setBaudRate(9600); 
              } catch (IOException e) {
                    try {
                    recDriver.close();
                } catch (IOException e2) {
                      // Ignore.
                  }
                recDriver = null;
                return;
              }
              recDriver.getClass().getSimpleName());
          }
          onDeviceStateChange();
      }
  
   private void stopIoManager() {
  
      // Get UsbManager from Android.
      manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  
      // Find the first available driver.
      recDriver = UsbSerialProber.acquire(manager);
  
          if (serialIoManager != null) {
              Log.i("Device", "Stopping io manager ..");
              serialIoManager.stop();
              serialIoManager = null;
          } else {
  
              Log.d("Device", "recDriver NULL"); 
          }
      }
  
   private void startIoManager() {
          // Get UsbManager from Android.
          manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  
          // Find the first available driver.
          recDriver = UsbSerialProber.acquire(manager);
  
          if (recDriver != null) {
              Log.i("Device", "Starting io manager ..");
              serialIoManager = new SerialInputOutputManager(recDriver, mListener);
              mExecutor.submit(serialIoManager);
          } else {
  
              Log.d("Device", "recDriver NULL"); 
          }
      }
  
   private void onDeviceStateChange() {
          stopIoManager();
          startIoManager();
      }
  
  protected void updateReceivedData(byte[] data) throws IOException {
      //use the data
  
       Log.d("Device", "is updating"); 
  
       final String dataIn = HexDump.dumpHexString(data);
  
       outputText.setText(dataIn); 
  
       canSend = checkForSend(dataIn);
  
       if (canSend) {
  
           sendData(); 
       }
  }
  
  private boolean checkForSend (String in) {
  
      String cur; 
      int len = in.length(); 
  
      for (int i = 0; i &lt; len; i++) {
  
          cur = in.substring(i, i + 1); 
  
          if (cur.equals("T")) {
  
              return true; 
          } 
  
      }
      return false; 
  }
  
  static void show(Context context, UsbSerialDriver driver) {
      recDriver = driver;
      final Intent intent = new Intent(context, MainActivity.class);
      intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY);
      context.startActivity(intent);
  }
  
  @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;
  }
  
  public void requestSend(View v) {
  
      dataToSend = "9375644603\n"; 
  
      if (notInit) {
  
          try {
              sendData();
  
          } catch (IOException e) {
  
              e.printStackTrace();
          } 
      }
  
      notInit = false; 
  
  }
  
  private void sendData() throws IOException {
  
      // Get UsbManager from Android.
      manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  
      // Find the first available driver.
      sendDriver = UsbSerialProber.acquire(manager);
  
      if (sendDriver != null) {
          sendDriver.open();
          try {
              sendDriver.setBaudRate(9600);
  
                              dataToSend = "2345\n";   
              if (!dataToSend.equals("")) {
  
                  byte [] byteToSend = dataToSend.getBytes(); 
                  sendDriver.write(byteToSend, 1000); 
              }
  
              dataToSend = ""; 
  
              byte[] terminator = "T\n".getBytes();
              sendDriver.write(terminator, 1000);
  
          } catch (IOException e) {
              // Deal with error.
          } finally {
              sendDriver.close();
          } 
      }
  
      // Get UsbManager from Android.
      manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  
      // Find the first available driver.
      sendDriver = UsbSerialProber.acquire(manager);
  
  }
  
  
  }
  </code></pre>
  
  <p>Notice that I am trying to use two separate drivers with the same I/O manager. I am not sure if that should negatively affect it. I am able to send the data to the Arduino, and the Arduino's TX led comes on, so I know something is being sent. The onNewData method that is triggered when the SerialInputOutputManager listener detects incoming data is never being ran.  So I take it that the driver for the manager's listener is not getting initialized correctly or something.  </p>
  
  <p>If anyone has a better method of talking between the Android and the Arduino via two-way usb serial, please let me know what it is.  I have had a lot of trouble trying to get this to work.      </p>