title: Reading a Bluetooth data stream from an Arduino with Android
body: <h2>The Situation</h2>
  
  <p>I'm trying to write an application that does one very simple task: when an <a href="http://en.wikipedia.org/wiki/Near_field_communication" rel="nofollow">NFC</a> tag is detected with the appropriate AAR and URI it launches the application, uses data in the tag to connect to a specified Bluetooth radio (specified by the NFC tag) and waits to accept a data stream, which it converts to a string and displays on the screen.</p>
  
  <p>When I run the application currently it simply exits immediately with three runtime exceptions. I would like it to wait passively instead of closing, and I do not understand the runtime exceptions.</p>
  
  <h2>The Exceptions</h2>
  
  <ol>
  <li>Unable to resume activity; NullPointerException</li>
  <li>ParseTag(); exception line 127</li>
  <li>onResume(); exception line 83</li>
  </ol>
  
  <h2>The Code</h2>
  
  <pre><code>public class BlueNF extends Activity {
  
      private BluetoothDevice mBluetoothDevice = null;
      private BluetoothAdapter mBluetoothAdapter = null;
      private BluetoothSocket mBluetoothSocket = null;
  
      private NfcAdapter mNfcAdapter = null;
  
      private NdefMessage dashTag = null;
  
      private static final int REQUEST_ENABLE_BT = 3;
      private static final UUID SerialPortServiceClass_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
  
      private InputStream iStream = null;
  
      public static String iValue = null;
      public final static String EXTRA_MESSAGE = "com.yogafarts.hackpsuproject.BlueNF.iValue";
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          //Set the content view
          setContentView(R.layout.activity_blue_nf);
          //Check for NFC
          mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
          if (mNfcAdapter == null) {
              Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
              finish();
              return;
          }
  
          //Check for Bluetooth
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
          if (mBluetoothAdapter == null) {
              Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
              finish();
              return;
          }
      }
  
      @Override
      public void onStart() {
          super.onStart();
  
          if (!mBluetoothAdapter.isEnabled()) {
              Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
              startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
          }
      }
  
      public void onResume() {
          super.onResume();
          //IntentFilter ndefTag = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
  
          //Get the current intent
          Intent dashTagIntent = getIntent();
  
          //Read extra intent data into tag object (Really just reading the NdefMessage into the dashTag object
          dashTag = dashTagIntent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
  
          //Create a byte array of bluetooth hardware ID using ParseTag
          byte[] mBluetoothInfo = ParseTag(dashTag);
  
  
          //Create a bluetooth adapter object
          mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(mBluetoothInfo);//Should be 0013EF00061A
  
          try {
              mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(SerialPortServiceClass_UUID);
          }
          catch ( IOException e ) {
              Log.e( "Bluetooth Socket", "Bluetooth not available, or insufficient permissions" );
          }
  
          //Cancel discovery because it's resource intensive (if it's active)
          mBluetoothAdapter.cancelDiscovery();
  
          //Connect to the device
          try {
              mBluetoothSocket.connect();
              iStream = mBluetoothSocket.getInputStream();
  
              //System.out.println(iStream);
              //OutputStream oStream = mBluetoothSocket.getOutputStream();
          }
          catch ( IOException e ) {
  
              try { mBluetoothSocket.close();
  
              }
              catch ( IOException e2 ) {
                  Log.e( "Bluetooth Socket", "IO Exception" );
              }
          }
          iValue = iStream.toString();
          viewMessage();
      }
  
      public byte[] ParseTag(NdefMessage ndef) {
  
          NdefRecord[] mNdef = ndef.getRecords();
          return mNdef[2].getPayload();
      }
  
      public void viewMessage() {
          Intent intent = new Intent(this, DisplayMessage.class);
          //TextView text = (TextView) findViewById(R.id.tv);
          String message = iValue;//text.getText().toString();
          intent.putExtra(EXTRA_MESSAGE, message);
          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.blue_n, menu);
          return true;
      }
  
  }
  </code></pre>
  
  <p>And the activity that displays the text after the stream is read...</p>
  
  <pre><code>public class DisplayMessage extends Activity {
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_display_message);
          TextView text = (TextView) findViewById(R.id.tv);
              text.setText(com.yogafarts.hackpsuproject.BlueNF.iValue);
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          getMenuInflater().inflate(R.menu.display_message, menu);
          return true;
      }
  }
  </code></pre>