Saturday 13 June 2015

Introduction to Docker


    A developer always looks to develop apps on one platform and make it available on multiple platforms. While developing the app, they don't care about the development environment. Truly, it's all about the app and all app needs is a secure isolated environment with minimal OS services to run.

    We've been using VMs since a long time for running applications on different platforms. It is indeed a major advancement over physical machine. But the VMs do come with a fully blown OS which takes a lot of resources. So wouldn't it be better if we can run our apps without the underlying OS overhead?
    Let's find out how to achieve this as we go ahead.


Container


    Containers are an application runtime environment similar to virtual machines. Runtime environment contains the things that an application needs in order to execute. But containers are much more light weight than virtual machines. Now as we all know the operating system(Linux) is installed on top of the physical machine. The Linux kernel manages the hardware underneath it. Before the containers and VMs, every app would be installed on the user space.

    Containers enable us to create multiple isolated instances of user space. These isolated instances of user space are called containers. This type of virtualization is called OS level virtualization. Containers are light weight because they share a single common Linux kernel on the host. Thus containers are faster and portable.




    Each container has an independent and isolated instance of user space. Now for an isolated user space we need an isolated root file system, process hierarchy and networking stacks. So each instance of the user space has its own view of the root file system, process hierarchy and networking stacks. Thus an app running inside of a container can change anywhere within its own view of the file system. 

    But this kind of isolation is provided by the feature of the linux kernel called namespaces. They allow partitioning of the system namespaces (For ex. process namespace) and assign a partition to a container.

    Next, cgroups(control groups) is a linux kernel feature to limit, account and isolate resource usage (CPU, memory, disk I/O, etc) of process groups. In case of containers, cgroups are mapped one to one to containers. Thus we can control how much CPU, memory etc. the container has access to.



Docker 


    Docker itself is an isolated runtime environment. It is an open source platform for developers and system admins to build, ship and run distributed apps.

    Well for me, I had to ship one of my applications from Ubuntu to CentOS, that's when I started learning docker. So packaging everything for use elsewhere is always a challenge when it comes to porting your application stack together with its dependencies. This is where docker enables apps to be quickly assembled from components. As a result, IT can ship faster and run the same app, unchanged, on laptops, data center VMs, and any cloud.

    Docker brings together the namespaces, cgroups into its docker engine. It provides a standard runtime providing developers to code apps in docker container and package them and ship to any docker container and start working on it. It can be shipped to data center, AWS, Azure anywhere where the destination is running docker runtime or daemon. Docker seems to be evolving as a platform rather than a runtime.

    Remember I said earlier that docker containers share the Linux kernel features such as namespaces, cgroups, etc. Now docker contains libcontainer as the default execution driver for sharing the Linux kernel features. You can configure it to use lxc or libvirt.


Installing Docker


    We'll install docker on Linux 14.04. It is recommended to have a Linux kernel of minimum 3.8. This is for the support of namespaces plus stability. To check the version of Linux kernel you can run the following command in the terminal window as follows:

uname -a



    As you can see the kernel version for my system is 3.13 which is even better. Next run the following command to update the packages.

apt-get update



    It is not necessary to login as root but I don't like to prefix "sudo" before running every command.


    Next we will install docker using the following command:

apt-get install -y docker.io




    Once docker is successfully installed, check if the docker.io service is running using the following command:

service docker.io status



    Woah! Docker is installed and is running. This indicates that the docker daemon is running. Docker comes with a client as well as daemon.

    Now let's use the client and get the version of docker installed on our system using the following command:

docker -v



    Then run the following command to get more details about the docker:

docker version



    This tells us that the client as well as server are of the same version(i.e. 1.0.1). Good for us!

   
    Next, run the following command to get internal info about the docker:

docker info



    As you can see, this gives us information about the containers and images in the docker. Docker uses the aufs union file system as the storage driver. Here the native execution driver indicates that it is using libcontainer. Remember I said earlier that docker uses lxc or libcontainer to talk to the Linux kernel.

    I guess that's it for this post. You must have got the idea of what docker is, what docker does, and how to install it and run some basic commands.

    Do keep learning. I hope this post will get you started with docker. If you have any doubts, do comment below and I'll look to it.

    Happy Reading! :)


Saturday 6 June 2015

Introduction to Maven - Part I

 
    Maven in simple words is a powerful build tool. A build tool is a tool that automates everything related to building the software project which includes:

        1. Generating source code
        2. Generating documentation from the source code
        3. Compiling source code
        4. Packaging compiled code into JAR files or ZIP files

    The most important reason behind using maven is it helps us manage dependencies. Dependency management is what makes it such a powerful tool. Besides Maven can also be used as a project management tool. It maintains the version information and can be used to generate the javadoc as well as maintain other information about the component.

    Maven is a open source tool managed by the Apache Software Foundation. The reason you would want to use it is its platform independent. We can recreate our builds for any environment. Downloading a dependency will also pull other items it needs i.e it supports transitive dependency. Maven can be integrated with an IDE or can be used standalone.

    You must have seen people comparing Maven and Ant tool but Ant really isn't a build tool as much as it is a scripting tool. You have to explicitly do everything in Ant.

    Ant uses build.xml as the name for a build file. I have listed a simple build.xml file. It is quite easy to understand what this file does. It first cleans the project then compiles it and creates a jar and finally runs the jar. But there is a problem here, what if i call build before clean. This might introduce some errors in my build.

<project>

    <target name="clean">
        <delete dir="build"/>
    </target>

    <target name="compile">
        <mkdir dir="build/classes"/>
        <javac srcdir="src" destdir="build/classes"/>
    </target>

    <target name="jar">
        <mkdir dir="build/jar"/>
        <jar destfile="build/jar/HelloWorld.jar" basedir="build/classes">
            <manifest>
                <attribute name="Main-Class" value="oata.HelloWorld"/>
            </manifest>
        </jar>
    </target>

    <target name="run">
        <java jar="build/jar/HelloWorld.jar" fork="true"/>
    </target>

</project>



On the other hand, maven contains a lot of implicit functionality. Maven uses a pom.xml for its build.
A simple pom.xml file is listed below. We will discuss more about pom file later.

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
</project>



You can observe that not much information is explicit in maven and this can get quite confusing sometimes. Maven uses a convention over configuration model i.e we are good to go until we use standard maven convention rather than configuring everything like that in ant build.xml.

    Now this pom file can be used to do all those things like clean, compile, build and run. It will all work just looking at my pom file because you don't see all those stuffs set up if i follow their conventions, their directory structure. So it is a little non-descriptive at first until you understand the semantics of how maven works.
    It is really centered around managing your entire project's lifecycle.

Maven directory structure


    Now lets have a look at the maven folder structure. By default maven looks for a src/main/java directory underneath our project directory. It compiles all the code into a target directory. And it references all these things looking into our pom.xml file.  
src/main/java - where we store our Java code following the standard package declaration

For  example, for a project with package name com.myproject, java files will be placed under src/main/java/com/myproject/ directory.

src/test/java - all your unit tests code goes here

target - this is where everything gets compiled to, where tests get ran from and contents in this directory get packaged into a jar, zip etc.


Maven pom.xml file


A pom file is an XML representation of project resources like source code, test code, dependencies i.e external JARs used etc. The POM contains references to all of these resources.

Now a pom.xml file can be divided into 4 basic parts:

1. Project Information: 

    
    This can include 

    a. groupId - This is the package name used inside our application. For example: com.myproject
    b. artifactId - This is the application name. For example: HelloWorld
    c. version - This is the version number of our application. For example: 1.0.0
    d. packaging - This is how we want to distribute our application For example: jar, war

2. Dependencies: 


    This includes the direct dependencies i.e the artifacts that we want to use in our application.Now for adding a dependency we need to know the following three things:

    1. groupId
    2. artifactId
    3. version

Note: Maven stores everything it downloads in your home directory/.m2 directory.
For example: C:\Users\<your_username>\.m2\repository

This is how we can add a dependency in our pom.xml file

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.1</version>
    </dependency>
</dependencies>


Note: For storing a dependency it uses the above info. For example for storing the commons-lang artifact it uses the following directory structure:
C:\Users\<your_username>\.m2\repository\commons-lang\commons-lang\2.1\commons-lang-2.1.jar


Note: Maven does not store the downloaded artifacts into individual project directory instead it stores the artifacts into a local repo so that if an artifact is included in multiple projects it does not have to go and download that multiple times.

3. Build: 


    This includes 

    a. Plugins - The plugins that we want to use in our application
    b. Directory Structure - This is where we can override the default java and other directories

    For example: Lets change the final artifact name of the packaged application. This can be done by adding the following code to the pom.xml file:

<build>
    <finalName>test</finalName>
</build>

4. Repositories: 


    This is where we download the artifacts from. By default it downloads the artifacts from central maven repository 



I hope this post has given you something to start with maven. If you have any doubts, just leave a comment and I will look to it.
Happy Reading :)




Monday 25 May 2015

Getting started with Redis


        Redis is a really fast and useful NoSQL database. It's used by many large web companies like StackOverflow, Twitter and Instagram.
       
        But if you are reading about it for the first time it can be pretty confusing about what Redis does and how can it be used. Also why do we need to use Redis instead of relational databases like MySQL or SQLServer. This post is meant to give you a brief introduction about Redis and how it differs from relational databases and NoSQL.
       
        Redis is an Open Source database that stores data in the form of a key value pair. Each type of data is associated with a key. You might think of Redis as a dictionary in C# or Map in Java, but the value in Redis is a structured data type consisting of lists, set and hashes.
        The key point about Redis is it stores data in the main memory i.e in the RAM of the computer it is running on. You can persist the data to disk, but the in-memory dataset and the key value pair is what makes Redis extremely fast.

        Redis is built with LUA support. If you are totally new to LUA, you can read about it at http://www.lua.org/start.html. Basically it's a lightweight scripting language. You don't necessarily need to know LUA for working with Redis, but Redis provides support for lua scripts similar to stored procedures for SQL.

        Also Redis can be replicated i.e you can have Redis installed on different machines to read data and a master controlling these nodes. It is highly recommended to deploy Redis on linux machines.

Note: As per the Redis official website, there is no official support for Windows builds, but Microsoft maintains a Win-64 port of Redis.

        You might feel this post being too theoretical but believe me these points will help you decide the usage of Redis in your scenario. So just take a deep breath and continue reading.

        Next we will talk about Sentinel. Pay some attention here because it's kinda senti! Sentinel is a feature that provides an automatic failover mechanism. It's a built-in feature in v2.6+. It automatically promotes a slave to replace a failing master, also reconfigures other slaves to use the new master and informs about it to the client applications. Thus it provides high availability. 
        
       Generally when you're working with a database it's always difficult to monitor and configure it. But Redis Sentinel provides with tasks such as monitoring, notifications and acts as a configuration provider for clients. All in one! Isn't it???

Note: A prerequisite for using Sentinel for automatic failover is to have a master-slave replication setup

         Now lets talk more about Redis. Redis is a NoSQL database as you must be knowing till now i.e it has no schema and is much more flexible in its structure. But Redis actually is quite a bit different from other NoSQL databases such as mongodb or ravendb. These databases focus is to create documents which can be persisted on disk and can be indexed and hence these are known as document databases. 
       On the other hand, Redis stores its data using keys and the data stores can be in the form of different data structures not just a document. There is no kind of indexing in Redis. Offcourse you can implement it yourself but Redis does not provide any support as such. Redis only lets you get data by specifying the key. But it's very fast speed and less overhead over less query capability makes it suitable for certain conditions.





Sunday 24 May 2015

Mongoose tutorial with node.js and mongodb

In recent times NoSQL has gained popularity and of these mongodb is the clear favorite. But for people using relational databases with different object-relational models(ORMs) for some time might find it difficult to switch from schema-based to schema less approach. You may have tried to use mongodb but faced problems due to its lack of structure or schema.

    There are official drivers present for mongodb in different languages such as C#, C++, Java, Python, Ruby, Perl, PHP and Node.js on the mongodb website. This is how native mongodb driver for node.js can be used to connect to mongodb:

var MongoClient = require('mongo').MongoClient;

MongoClient.connect("mongodb://localhost:27017//somedb", function(err, db){
   if(!err){
      console.log("Connection Successful");
   }
});

So why not use native mongodb driver for your application, well sometimes you should but however if you need validations, associations and other high-level data modeling functions, then an Object Document Mapper may be helpful.

According to mongoose website it provides a straight-forward, schema-based solution to modeling your application data and includes built-in type casting, validation, query building, business logic hooks and more, out of the box.

Now let's take a small look at the mongoose schema. Suppose we want to store customer information in mongodb. The schema might look as below:

var mongoose = require("mongoose");

var Schema = mongoose.Schema();
var customerSchema = new Schema({
                 name: String,
                 address: String,
                 phone: Number,
                 createdOn: Date,
                 isActive: Boolean
});

First we require the mongoose to gain access to the schema object. Next we created a simple flat customer schema. The schema takes the field name and the schema type. The schema types present in mongoose are String, Date, Number, Boolean, ObjectId, Buffer(similar to Object in javascript), Array and Mixed. When you need a flexibility of data types to be stored in a single field, you can use Mixed data type for that. Let's look at a complex schema for customer information storage.

 var Schema = mongoose.Schema();

var addressSchema = new Schema({
                  city: String,
                  state: String,
                  country: String,
                  postalCode: String
});

var customerSchema = new Schema({
                 name: {
                      first: String,
                      last: String
                 },
                 address: addressSchema,
                 phone: Number,
                 createdOn: { type: Date, default: Date.now},
                 isActive: { type: Boolean, default: true}
});

Here, first we dissolved the name property into first and last fields, address becomes a nested schema and it's always a good practice to define the nested schemas separately. Mongoose also provides us with the facility to define the default value for a field. For createdOn and isActive fields we have defined an object instead of a schema type containing the type and the default value for that field. 

We can also add fields to the schema using the add method of schema object. For example,

var customerSchema = new Schema;
customerSchema.add({ name: String});

This allows you to define the schema dynamically depending on some of the known conditions.Next we will connect to the test db in mongo using the mongoose.

mongoose.connect('mongodb://localhost:27017/test');

Next we will create a model using the schema previously defined. The model function takes first argument as the model name and schema as the second. It also contains an optional third argument wherein you can name the collection to be used for this model. We can create multiple models from the schema definition. 

var Customer = mongoose.model('customer', customerSchema);

customerSchema.add({ premiumCode: Number});
var premiumCust = mongoose.model('premiumCustomer', customerSchema);

A document in mongoose is nothing but an instance of a model. This mongoose document is converted into a mongodb document which can then be stored in mongodb.

                   schema --> model --> mongoose document --> mongodb document


Taking our customer model, we now create an instance of the model below:

var Customer = mongoose.model('customer', customerSchema);
var abd = new Customer({
            name: 'AB deVilliers',
            address: 'South Africa',
            phone: 1233567890,
            isActive: true
});

Here as you can see 'abd' is an instance of the Customer model derived from the customerSchema. Next to save this document to mongodb call the save function on the document.

abd.save();

Optionally, the save function also takes a callback as an argument. This can be useful to debug the errors. The save() function with a callback is shown below:

abd.save(function (err) {
         if (err) return console.log(err);
});

Now to retrieve a document from the mongodb, mongoose provides with four most commonly used functions with the model object. These are find, findById, findOne, and where.
The signature of these methods can be seen below:

Model.find(conditions, [fields], [options], [callback])
Model.findOne(conditions, [fields], [options], [callback])
Model.findById(id, [fields], [options], [callback])
Model.where(path, [val])

Remember the Customer variable which holds the model object. We will use this variable to retrieve the documents from mongodb. Here we are using a callback which contains the retrieved data or errors if any.

//This returns all the documents from the collection that was used for the model.

Customer.find(function(err, results){
              if(err) throw err;
              console.log(results);
});


Note: If you don't give the collection name while creating your model, the model name appended with an 's' is taken as the default collection name. For example, in our case the model name is customer and thus it will be assigned to the default 'customers' collection.


//In this case we are passing in some query conditions to narrow down the results.

Customer.find({ name: 'Sachin' }, function(err, results){
});

//This will only return the specified fields from the document.

Customer.find({ name: 'Sachin' }, 'name address' function(err, results){
});


Note: To remove a field from the results, prefix the field name with a '-' sign.


//The find method without any arguments returns only the query object. Then we can call the exec method on the query object to get the results in the form of a callback.

var query = Customer.find();
query.exec(function(err, results){
});

Similarly for the findOne method, as the name suggests it will only return the first matched document.

//Returns the first document that has the name value of Sachin

Customer.findOne({ name: 'Sachin' }, function(err, results){
});

If you want to get any document based on its id, you can use the findById method.

//Returns the document with the specified id field

var id = '3485fgwtr4cnm8175890';
Customer.findById(id, function(err, results){
});


Note: We can also use the mongodb comparison query operators while retrieving the documents
Customer.find({ age: { $gte: 12 }}, function(err, results){
});


The where method works as follows. It expects a field path to be queried against and the query value
Customer.where('age').gte(12).exec(function(err, results){
              if(err) throw err;
              console.log(results);
})

You can also chain your query for retrieving documents such as:

Customer.where('age').gte(12).where('name', 'Rahul').exec(function(err, results){
              if(err) throw err;
              console.log(results);
})

Note: The path in the method signature signifies the field we are querying against. This can also be a nested field like name.first or address.city


I hope after reading this you will feel comfortable with using mongoose and mongodb.
In case you've got any doubts do comment below and I'll be happy to help :)


Wednesday 29 April 2015

Bluetooth communication between Arduino and Android

      Communication between Arduino and Android might seem scary and troublesome at first when you start to get errors in communicating and you don’t find where exactly the problem lies. Believe me it’s lot simpler than it looks. The only thing required is a proper guidance. While doing it on my own I have had many problems and would want others not to face the similar problems. 

      So here in this post I will be controlling a LED light that is connected to the Arduino board from an Android device via Bluetooth.

The hardware requirements are:

      1)      Arduino Uno  
      2)      Bluetooth Module (Example: HC-05) 
      3)      An Android Device (Example: Samsung Galaxy)  
      4)      A LED Light

Once these devices are available the connections that need to be made are as shown in the following fig:


Connect the anode pin of LED light to the Pin12 and cathode pin to the GND Pin of Arduino.

                                                  
The JY-MCU module (Bluetooth module) communicates with the Arduino via a serial connection. The 4 pins that we will be using are:
  • VCC => used to power the module. It needs to be connected to the Arduino 5V pin
  • GND => the ground pin. It needs to be connected to the Arduino GND pin
  • TXD => used to send data from the Bluetooth module to the Arduino. It needs to be connected to the  receive pin (RXD) of the Arduino, which in our case is pin 6 on the UNO.
  • RXD => used to receive data from the Arduino. It needs to be connected to the the Arduino transmit pin (TXD), which in our case is pin 7 of Arduino Uno.
  • We will not be using the “STATE” and the “KEY” pins of the Bluetooth module, so they need not be connected.

Once these connections are done, we have to code the Arduino UNO to accept Bluetooth serial data and make 
the LED ON or OFF depending on the input byte.

To start with, first download the Arduino IDE by visiting the following link:

Then connect the Arduino UNO board to your computer via the USB cable and open the Arduino IDE by clicking on the .exe file that you’ve just downloaded. Then copy the following code to your IDE and save it. Then click the upload button to build, compile and upload the code to your android UNO board. Once the compilation is successful your Arduino board is ready to receive the data.
The arduino code is fairly simple.
  • It establishes a serial connection between the Arduino and the Bluetooth module
  • RXD(Pin 6) and TXD(Pin 7) Arduino pins communicate with the TXD and RXD pins of the module
  • Listen for input on the serial port 12 and process it
  • Turn the LED on pin 12 ON, if it reads 1 (one) as serial input
  • Turn the LED on pin 12 OFF, if it reads 0 (zero) as serial input

Arduino code

#include <SoftwareSerial.h>     //Software Serial Port
#define RxD 6        // This is the pin that the Bluetooth (BT_TX) will transmit to the Arduino (RxD)
#define TxD 7        // This is the pin that the Bluetooth (BT_RX) will receive from the Arduino (TxD)

SoftwareSerial blueToothSerial(RxD,TxD);
char incomingByte;  // incoming data
int  LED = 12;      // LED pin

void setup() {
 Serial.begin(9600);          // Allow Serial communication via USB cable to computer (if required)
pinMode(RxD, INPUT);    // Setup the Arduino to receive INPUT from the bluetooth shield on Digital               Pin 6
pinMode(TxD, OUTPUT);  // Setup the Arduino to send data (OUTPUT) to the bluetooth shield on Digital Pin 7
pinMode(LED, OUTPUT);
setupBlueToothConnection();
}

void loop()
{  
   if(blueToothSerial.available())     // If the bluetooth is connected and sent any characters
  {
        incomingByte = (char)blueToothSerial.read();            // read byte
        if( incomingByte == '0' )
        {
               digitalWrite(LED, LOW);                                          // if 0, switch LED Off
       }
      if( incomingByte == '1' )
      {
          digitalWrite(LED, HIGH);                                  // if 1, switch LED ON
      }
  }
}

void setupBlueToothConnection()
{
   //Setup Bluetooth serial connection to android
  blueToothSerial.begin(115200);
  blueToothSerial.print("$$$");
  delay(100);
  blueToothSerial.println("U,9600,N");
  blueToothSerial.begin(9600);
 }

Next create a new Android project in Eclipse and copy the following code into your MainActivity.java file:

MainActivity.java

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class ConnectArduino extends Activity{           
    BluetoothAdapter mBluetoothAdapter;
    BluetoothSocket mmSocket;
    BluetoothDevice mmDevice;
    OutputStream mmOutputStream;
    InputStream mmInputStream;
   
    TextView status;
    Button connect;
    Button disconnect;
    Button turn_LED_ON;
    Button turn_LED_OFF;

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                        // TODO Auto-generated method stub
                        super.onCreate(savedInstanceState);
                        setContentView(R.layout.activity_main);
                        connect = (Button)findViewById(R.id.connect);
                        disconnect = (Button)findViewById(R.id.disconnect);
                        turn_LED_ON = (Button)findViewById(R.id.on);
                        turn_LED_OFF = (Button)findViewById(R.id.off);
                        status = (TextView)findViewById(R.id.status);
                        status.setText(“Bluetooth Disconnected”);
                        disconnect.setEnabled(false);
                        turn_LED_ON.setEnabled(false);
                        turn_LED_OFF.setEnabled(false);                   

connect.setOnClickListener(new View.OnClickListener()
                     {
                         public void onClick(View v)
                         {     
                        try
                                    {
                                    findBT();
                                    }
                           catch (IOException ex) { }
}
                     }); 
                        disconnect.setOnClickListener(new View.OnClickListener()
                     {
                         public void onClick(View v)
                         {     
                        try
                                    {
                                    closeBT();
                                    }
                           catch (IOException ex) { }
}
                     }); 
                        Turn_LED_ON.setOnClickListener(new View.OnClickListener()
                     {
                         public void onClick(View v)
                         {     
                        try
                                    {
                                    sendData(“1”);
                                    }
                           catch (IOException ex) { }
}
                     }); 
                        Turn_LED_OFF.setOnClickListener(new View.OnClickListener()
                     {
                         public void onClick(View v)
                         {     
                        try
                                    {
                                    sendData(“0”);
                                    }
                           catch (IOException ex) { }
}
                     }); 
}

void findBT() throws IOException
    {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if(mBluetoothAdapter == null)
        {
            status.setText("No bluetooth adapter available");
        }
        if(!mBluetoothAdapter.isEnabled())
        {
            Intent enableBluetooth = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBluetooth, 0);
        }
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        mmDevice = mBluetoothAdapter.getRemoteDevice("20:13:09:23:00:48");
         //”20:13:09:23:00:48” is the MAC address of the Bluetooth module
        if (pairedDevices.contains(mmDevice))
        {
             status.setText("Bluetooth Device Found, address: " + mmDevice.getAddress() );
                Log.d("ArduinoBT", "BT is paired");
        } 
      
        UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
        mmSocket = mmDevice.createInsecureRfcommSocketToServiceRecord(uuid);
        Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
        mmSocket = (BluetoothSocket) m.invoke(mmDevice, 1);
        mBluetoothAdapter.cancelDiscovery();
        mmSocket.connect();       
        mmOutputStream = mmSocket.getOutputStream();
        mmInputStream = mmSocket.getInputStream();

        status.setText("Bluetooth Connected");
        connect.setEnabled(false);
        disconnect.setEnabled(true);
        turn_LED_ON.setEnabled(true);
        turn_LED_OFF.setEnabled(true); 
}
void sendData(String m) throws IOException
 {
mmOutputStream.write(m.getBytes());
}
void closeBT() throws IOException
{                  
mmOutputStream.close();
mmInputStream.close();
            mmSocket.close();
            status.setText("Bluetooth Disconnected");
              connect.setEnabled(true);
              disconnect.setEnabled(false);
              turn_LED_ON.setEnabled(false);
              turn_LED_OFF.setEnabled(false);      
}
}

In your activity_main.xml file create four buttons for connect, disconnect, turn_LED_ON, turn_LED_OFF operations and a TextView to display the status of the Bluetooth.


Also, include the following uses-permission in your AndroidManifest.xml file
<uses-permission android:name=”android.permission.BLUETOOTH” />

NOTETo find out the MAC address of your Bluetooth module you need to connect your module to PC and then click on the device’s properties window. You can then read the MAC address of your module from the properties window.


Hope this information was useful. If you have any doubts or you’re still encountering any errors just leave a comment and I will try my best to help you out. Keep reading! J