Android Tutorial - 1st Bluetooth Communication.

Hi hi hi! Here I come again with a new android tutorial!

At this one we are gonna learn how to create a bluetooth serial communication with our smartphone. First of all I'm gonna do a brief desciption of the tutorial using the following diagram:



  1. First of all, we're going to create a basic UI with two Buttons and one EditText widgets. The firsts ones to look for the device and send info to device respectively and the last one to write the string that will be sent.
  2. Secondly, all bluetooth communication will be manage by a single class called BluetoothManager in which will be every used method. Included methods that are called by buttons.
  3. Finally, I decide to use HC-06 bluetooth module (compatible with arduino). It's a cheap&easy-use module that provides arduino of an easyway of wireless communication. If you dont have it, dont worry, the classes can be use for smartphone2smarphone communication (That will be shown in the following tutorial), so If you try to understand this tutorial, you'll be able to implement bluetooth communication in other situations.

Sooo... It's time to get down to work!

First of all, It's obligatory to configure the permissions, so add in the androidManifest.xml the following lines:


    
    
      


As I said previously, let's starts with the BluetoothManager class:


public class BluetoothManager {
 private BluetoothAdapter mBluetoothAdapter;

 public BluetoothManager() { // OverLoad constructor
  setUpBluetoothManager(); // Call the following function so that the BluetoothManager is configured.
 }

 public int setUpBluetoothManager() { // This function prepare the BluetoothManager
  mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // Here we get an instance of the bluetooth adapter that abstract us of the physic layer

  if (mBluetoothAdapter == null) // Check if the adapter is properly instanciate
   return -1;
  return 0;
 }

 public void enableBluetooth(Activity activity) {
  if (!mBluetoothAdapter.isEnabled()) { // Check if bluetooth is currently enabled. If not call the system dialog to enable it
   Intent enableBtIntent = new Intent(
     BluetoothAdapter.ACTION_REQUEST_ENABLE); // Prepare an intent to call to the system for the dialog
   activity.startActivityForResult(enableBtIntent,
     Types.REQUEST_ENABLE_BT); // Send to the system the intent to open the desired dialog to Activate Bluetooth
  }
 }

 public void startDiscovery(Activity activity) { // Once the bluetooth is enabled look for devices
  if(mBluetoothAdapter.isEnabled())
   mBluetoothAdapter.startDiscovery();
 }


Here we've got the basics to instanciate, enable, and start with bluetooth. Now the phone is looking for devices to connect to. But nothing happens if we dont tell the application how to identify the desired device. In order to do that, we are going to prepare a broadcastReceiver (Now I'vent got any tutorial about them, I want to talk about them afterwards).

Inside BluetoothManager class add the following lines:


 
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) { // When the broadcast receiver receive an intent
   String action = intent.getAction(); // Get the action name

   if (BluetoothDevice.ACTION_FOUND.equals(action)) { // if the action is that the device found a bluetooth device
    BluetoothDevice device = intent
      .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // Get instance of device
    if (device.getName().equals("HC-06")) { // If device name is HC-06 which we are looking for
     Log.d("BLUETOOTHMANAGER", "Found HC-06");
     mBluetoothAdapter.cancelDiscovery(); // Cancel discovery
     connectAsServer(device); // Call the function that will create the connection
    }
   }
  }
 };
 public void registerReceiver(Activity activity) { // This function will be called inside the  "onCreate" method of the main activity in order to attach the receiver to it
  IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); // Create an intent template to specify to the broadcastReceiver that will wait for this kind of intents
  activity.registerReceiver(mReceiver, filter); // Register the broadcastReceiver at the current activity
 }
 
 public void unregisterReceiver(Activity activity) { // This function will be called inside the "onDestroy" method of the main activity in order to deattach the receiver.
  activity.unregisterReceiver(mReceiver); // Unregister the broadcastReceiver
 }


At last in this class, the "connectAsServer" function. This functions will create a thread to deal with HC-06 the communication:



 
public static final int REQUEST_ENABLE_BT = 1001;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Create a UUID variable that will be used afterwards

 private Thread connectionThread; // Declarate a Thread variable.

 private static InputStream iStream = null; // Input and Output stream variables of the connection. This variables are the ones that we will use for reading and writing information.
 private static OutputStream oStream = null;

 public void connectAsServer(BluetoothDevice device) { // The functions get the device that were find and received by the BroadcastReceiver
  final BluetoothSocket mmSocket; // Variable that got an instance of the communication socket
  final BluetoothDevice mmDevice = device; // Instance of device

  BluetoothSocket tmp = null; // Temporary variable that will contain the socket before copying it to mmSocket variable

  Log.d("BLUETOOTHMANAGER", "Trying connection with HC-06");
  try {
   tmp = mmDevice.createRfcommSocketToServiceRecord(MY_UUID); // Start a Service to create a socket that will allow the application to create the connection with the device wich identification us provided by MY_UUID. MY_UUID can be defined everywhere,in this case in the same BluetoothManager class, outside this function.
  } catch (IOException e) {
  }
  mmSocket = tmp; // Finaly when pass the socket to the proper variable

  Log.d("BLUETOOTHMANAGER", "Waiting connection with HC-06");
  connectionThread = new Thread(new Runnable() { // Create a new thread, beccuse "connect()" function that is used here is blocking, and if we implement it in the current UI thread, the application will be stopped until the connection is done.

   @Override
   public void run() {
    try {
     mmSocket.connect(); // Connect to the device. This is the blocking operation
    } catch (IOException ConnectEx) {
     Log.d("BLUETOOTHMANAGER", "Error connecting to HC-06");
     try {
      mmSocket.close(); // If connection fails, close the socket
     } catch (IOException closeEx) {
     }
     return;
    }
    try {
     iStream = mmSocket.getInputStream(); // If the connection is made, instanciate input and output streams into declarated variables to read and write
     oStream = mmSocket.getOutputStream();

    } catch (IOException e) {
     e.printStackTrace();
    }

   }
  });
  connectionThread.start(); // Start the previously defined thread.

 }

Finally, in order to complete this android application, implement the main activity class:

public class MainActivity extends Activity {

 private Activity mySelf;
 
 private BluetoothManager mBluetoothManager;
 
 private Button sendButton, connectButton;
 private EditText text;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        mySelf = this;
        
        mBluetoothManager = new BluetoothManager(); // Intanciate the class Bluetooth Manager  // Instanciate BluetoothManager class
        
        mBluetoothManager.registerReceiver(this); // Setting up the bluetooth manager // Attach the receiver
        
        mBluetoothManager.enableBluetooth(this); // Enable Bluetooth 
        
       
        
        sendButton = (Button) findViewById(R.id.sendButton); // Instanciate UI views
        connectButton = (Button) findViewById(R.id.button1);
        text = (EditText) findViewById(R.id.text);
        
        sendButton.setOnClickListener(new OnClickListener() { // Set to this button the action of sending the string wrote in the editText

   
   @Override
   public void onClick(View v) {
    mBluetoothManager.write(text.getText().toString().getBytes());
   }
  });
        
        connectButton.setOnClickListener(new OnClickListener() { //  Set to this button the action to startDiscovety
   
   @Override
   public void onClick(View v) {
     mBluetoothManager.startDiscovery(mySelf); 
   }
  });
        
    }

    @Override
    protected void onDestroy() {
 super.onDestroy();
  
 mBluetoothManager.unregisterReceiver(this); // Deattach the receiver
  
    }
    
}
 
And now, the other side of the connection. This code is written in the arduino IDE


    string buffer = "";
    void setup(){
        Serial.begin(9600);
    }

    void loop(){
        if(Serial.available())
            buffer = buffer + Serial.read();
    }


Now every info sent by the android application is stored in buffer varible in arduino, so in conclusion, the Bluetooth communication is completed!

I hope do you enjoyed the tutorial, and learned the basics.
See you soon! Like, comment and share!
Pablo R.S.

No hay comentarios:

Publicar un comentario