Introduction: Lighting on and Off LEDs With an Android App

In this Instructable I'll show you how to write a very simple Android app which will allow you to turn ON and OFF some LEDs via bluetooth.

This is a non-rigurous English translation for an article in my personal website: https://jjosemayorga.com/aplicacion-android-con-funcionalidad-bluetooth/.


You can find this and many other interesting projects in my website and my social media.

🌐 https://jjosemayorga.com/

Twitter ► https://twitter.com/jjosemayorga

Instagram ► https://www.instagram.com/jjosemayorga/

Facebook ► https://www.facebook.com/jjosemayorgau

Youtube ► https://www.youtube.com/@jjosemayorga

TikTok ► https://www.tiktok.com/@jjosemayorga

Supplies

Step 1: Wire the Components All Together

In order to make the whole setup work, you just need to wire all the components in the way I show you in this picture.

If you need further explanation on how each element works or why I use them that way, you just need to visit the article on my website and get some instruction on it (it's in Spanish but, if you are not fluent in that language, Google translator will do the job 😉).

Step 2: Load the Arduino Code

As for the Arduino part, I provide you the Arduino code I've used.

It's a pretty simple of the use of serial communication and bluetooth. Should you need to learn the very basics of this, let me address you again to some articles on my website. Apart from the main one, this one about serial communication, and this one dealing specifically with bluetooth.


Step 3: Build the Android App

An Android app is made of different parts. If you use an IDE such as Android Studio and you create a project from scratch you will have the basic scheme to write the different files.

One of the main files is the Java code, located under the \app\src\main\java\ route. Here you find the code I've written:

package juanjo.ledblog;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.Toast;

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

public class LEDcontrol extends AppCompatActivity
{

private static final String TAG = "bluetooth";

Button btn_red_on, btn_red_off, btn_yellow_on, btn_yellow_off;
ImageView redled, yellowled;
Switch swt_bluetooth, swt_conectar;

int rstate=0;
int ystate=0;
int conectado=0;

private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;

// SPP UUID service
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

// MAC-address of Bluetooth module (you must edit this line)
private static String address = "00:06:66:4B:E4:25"; //para el modem blueSmirf
//private static String address = "98:D3:31:90:8E:68"; //para el modulo HC-05

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ledcontrol);

btn_red_on = (Button) findViewById(R.id.btn_red_on);
btn_red_off = (Button) findViewById(R.id.btn_red_off);
btn_yellow_on = (Button) findViewById(R.id.btn_yellow_on);
btn_yellow_off = (Button) findViewById(R.id.btn_yellow_off);
swt_bluetooth=(Switch)findViewById(R.id.swt_bluetooth);
swt_conectar=(Switch)findViewById(R.id.swt_conectar);

redled = (ImageView) findViewById(R.id.redled);
yellowled = (ImageView) findViewById(R.id.yellowled);


btAdapter = BluetoothAdapter.getDefaultAdapter();
//checkBTState();

swt_bluetooth.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
//is chkIos checked?
if (swt_bluetooth.isChecked())
{
checkBTState();
}
else
{
if(conectado==1)
{
swt_conectar.setChecked(false);
desconectarRobot();
}
btAdapter.disable();
}
}
});

swt_conectar.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
//is chkIos checked?
if (swt_conectar.isChecked())
{
conectarRobot();
}
else
{
desconectarRobot();
}
}
});

btn_red_on.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
sendData("c");
Toast.makeText(getBaseContext(), "Encendiendo LED rojo", Toast.LENGTH_SHORT).show();
redled.setImageResource(R.drawable.redon);
rstate=1;
}
});

btn_red_off.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
sendData("d");
Toast.makeText(getBaseContext(), "Apagando LED rojo", Toast.LENGTH_SHORT).show();
redled.setImageResource(R.drawable.redoff);
rstate=0;
}
});

btn_yellow_on.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
sendData("a");
Toast.makeText(getBaseContext(), "Encendiendo LED amarillo", Toast.LENGTH_SHORT).show();
yellowled.setImageResource(R.drawable.yellowon);
ystate=1;
}
});

btn_yellow_off.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
sendData("b");
Toast.makeText(getBaseContext(), "Aagando LED amarillo", Toast.LENGTH_SHORT).show();
yellowled.setImageResource(R.drawable.yellowoff);
ystate=0;
}
});

}

private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
if(Build.VERSION.SDK_INT >= 10){
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, MY_UUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
}
return device.createRfcommSocketToServiceRecord(MY_UUID);
}

public void conectarRobot() {
super.onResume();

Log.d(TAG, "...onResume - try connect...");

// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);

// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. In this case we are using the
// UUID for SPP.

try {
btSocket = createBluetoothSocket(device);
} catch (IOException e1) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e1.getMessage() + ".");
}

/*try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}*/

// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();

// Establish the connection. This will block until it connects.
Log.d(TAG, "...Connecting...");
try {
btSocket.connect();
Log.d(TAG, "...Connection ok...");
conectado=1;
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
}
}

// Create a data stream so we can talk to server.
Log.d(TAG, "...Create Socket...");

try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
}
}

public void desconectarRobot() {
super.onPause();

Log.d(TAG, "...In onPause()...");

if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
errorExit("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
}
}

try {
btSocket.close();
conectado=0;
} catch (IOException e2) {
errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
}
}

private void checkBTState()
{
// Check for Bluetooth support and then check to make sure it is turned on
// Emulator doesn't support Bluetooth and will return null
if(btAdapter==null) {
errorExit("Fatal Error", "Bluetooth not support");
} else {
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}

private void errorExit(String title, String message)
{
Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show();
finish();
}

private void sendData(String message)
{
byte[] msgBuffer = message.getBytes();

Log.d(TAG, "...Send data: " + message + "...");

try {
outStream.write(msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
if (address.equals("00:00:00:00:00:00"))
msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 35 in the java code";
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";

errorExit("Fatal Error", msg);
}
}

}


You can't forget to write the appropriate manifest under \app\src\main:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="juanjo.ledblog">

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">

<activity android:name=".LEDcontrol">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>


And the layou file under \app\src\main\res\layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="16sp">


<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">

<Switch
android:text="Bluetooth"
android:layout_width="wrap_content"
android:id="@+id/swt_bluetooth"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">

<Switch
android:text="Conectar"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:id="@+id/swt_conectar"
android:layout_gravity="center_vertical|center_horizontal"
android:layout_weight="1" />
</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_width="wrap_content"
android:gravity="center_horizontal"
android:layout_height="0dp"
android:layout_weight="2">


<ImageView
android:layout_height="wrap_content"
app:srcCompat="@drawable/redoff"
android:id="@+id/redled"
android:layout_width="0dp"
android:layout_weight="1" />

<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_gravity="center_vertical|center_horizontal">

<Button
android:text="Red LED ON"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_red_on"
android:layout_gravity="center_vertical|center_horizontal" />
<Button
android:text="Red LED OFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_red_off"
android:layout_gravity="center_vertical|center_horizontal" />
</LinearLayout>

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:gravity="center_horizontal"
android:layout_weight="2">


<ImageView
android:layout_height="wrap_content"
app:srcCompat="@drawable/yellowoff"
android:id="@+id/yellowled"
android:layout_width="0dp"
android:layout_weight="1" />

<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:layout_gravity="center_vertical|center_horizontal">

<Button
android:text="Yellow LED ON"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_yellow_on"
android:layout_gravity="center_vertical|center_horizontal" />
<Button
android:text="Yellow LED OFF"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn_yellow_off"
android:layout_gravity="center_vertical|center_horizontal" />
</LinearLayout>


</LinearLayout>

</LinearLayout>

Step 4: Try the Whole Setup

Here you have a demo of the project. Should you have any doubt or difficulty to reach an optimal result, you can contact me.