Showing posts with label Android code sample: BlueTooth. Show all posts
Showing posts with label Android code sample: BlueTooth. Show all posts

Problem of BluetoothChat example

Last year (June 26, 2015) I have a post to show how to "Import Android code sample of BluetoothChat to Android Studio". It work perfectly AT THAT TIME. But I re-try it again on update Android Studio 2.1, and test on ASUS Zenfont 2 running Android 5.0 and XiaoMi RedMi 2 running Android 4.4.4; it almost NOT WORK - no problem in pairing and connecting, but fail to send/receive data: sometimes one-way chat, sometimes totally cannot chat!!!

Then I change the Project Structure to target sdk version Android 4.4 (KitKat), it can be improved, but not 100%.


I have no idea is it related to new Android Studio/SDK? or related to new Android version? or related to individual device(s)?


Bluetooth communication between Android devices

This exercise implement bi-direction Bluetooth communication between Android devices. After connection made in last post "Make BlueTooth connection between Android devices", start another thread, ThreadConnected, to handle read and write once BluetoothSocket established. If any case make the connection lost, the program will not re-connect, so you have to quit and re-start it.


please notice that it is just a exercise to study bluetooth, not a completed example.


AndroidBlueToothBeCOnnected:

MainActivity.java
package com.example.androidbluetoothbeconnected;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private static final int REQUEST_ENABLE_BT = 1;

BluetoothAdapter bluetoothAdapter;

private UUID myUUID;
private String myName;

LinearLayout inputPane;
EditText inputField;
Button btnSend;

TextView textInfo, textStatus;

ThreadBeConnected myThreadBeConnected;
ThreadConnected myThreadConnected;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInfo = (TextView)findViewById(R.id.info);
textStatus = (TextView)findViewById(R.id.status);

inputPane = (LinearLayout)findViewById(R.id.inputpane);
inputField = (EditText)findViewById(R.id.input);
btnSend = (Button)findViewById(R.id.send);
btnSend.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
if(myThreadConnected!=null){
byte[] bytesToSend = inputField.getText().toString().getBytes();
myThreadConnected.write(bytesToSend);
}
}});

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this,
"FEATURE_BLUETOOTH NOT support",
Toast.LENGTH_LONG).show();
finish();
return;
}

//generate UUID on web: http://www.famkruithof.net/uuid/uuidgen
//have to match the UUID on the another device of the BT connection
myUUID = UUID.fromString("ec79da00-853f-11e4-b4a9-0800200c9a66");
myName = myUUID.toString();

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not supported on this hardware platform",
Toast.LENGTH_LONG).show();
finish();
return;
}

String stInfo = bluetoothAdapter.getName() + "\n" +
bluetoothAdapter.getAddress();
textInfo.setText(stInfo);
}

@Override
protected void onStart() {
super.onStart();

//Turn ON BlueTooth if it is OFF
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}

setup();
}

private void setup() {
textStatus.setText("setup()");
myThreadBeConnected = new ThreadBeConnected();
myThreadBeConnected.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

if(myThreadBeConnected!=null){
myThreadBeConnected.cancel();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode==REQUEST_ENABLE_BT){
if(resultCode == Activity.RESULT_OK){
setup();
}else{
Toast.makeText(this,
"BlueTooth NOT enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}


private class ThreadBeConnected extends Thread {

private BluetoothServerSocket bluetoothServerSocket = null;

public ThreadBeConnected() {
try {
bluetoothServerSocket =
bluetoothAdapter.listenUsingRfcommWithServiceRecord(myName, myUUID);

textStatus.setText("Waiting\n"
+ "bluetoothServerSocket :\n"
+ bluetoothServerSocket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void run() {
BluetoothSocket bluetoothSocket = null;

if(bluetoothServerSocket!=null){
try {
bluetoothSocket = bluetoothServerSocket.accept();

BluetoothDevice remoteDevice = bluetoothSocket.getRemoteDevice();

final String strConnected = "Connected:\n" +
remoteDevice.getName() + "\n" +
remoteDevice.getAddress();

//connected
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(strConnected);
inputPane.setVisibility(View.VISIBLE);
}});

startThreadConnected(bluetoothSocket);

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

final String eMessage = e.getMessage();
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("something wrong: \n" + eMessage);
}});
}
}else{
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("bluetoothServerSocket == null");
}});
}
}

public void cancel() {

Toast.makeText(getApplicationContext(),
"close bluetoothServerSocket",
Toast.LENGTH_LONG).show();

try {
bluetoothServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

private void startThreadConnected(BluetoothSocket socket){

myThreadConnected = new ThreadConnected(socket);
myThreadConnected.start();
}

private class ThreadConnected extends Thread {
private final BluetoothSocket connectedBluetoothSocket;
private final InputStream connectedInputStream;
private final OutputStream connectedOutputStream;

public ThreadConnected(BluetoothSocket socket) {
connectedBluetoothSocket = socket;
InputStream in = null;
OutputStream out = null;

try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

connectedInputStream = in;
connectedOutputStream = out;
}

@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;

while (true) {
try {
bytes = connectedInputStream.read(buffer);

String strReceived = new String(buffer, 0, bytes);
final String msgReceived = String.valueOf(bytes) +
" bytes received:\n"
+ strReceived;

runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(msgReceived);
}});

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

final String msgConnectionLost = "Connection lost:\n"
+ e.getMessage();
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(msgConnectionLost);
}});
}
}
}

public void write(byte[] buffer) {
try {
connectedOutputStream.write(buffer);
connectedOutputStream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void cancel() {
try {
connectedBluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
}

activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidbluetoothbeconnected.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/info"
android:textStyle="bold|italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/status"
android:textSize="28sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<LinearLayout
android:id="@+id/inputpane"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">

<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sent"/>

</LinearLayout>

</LinearLayout>

download filesDownload the files.

AndroidBlueTooth:

MainActivity.java
package com.example.androidbluetooth;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private static final int REQUEST_ENABLE_BT = 1;

BluetoothAdapter bluetoothAdapter;

ArrayList<BluetoothDevice> pairedDeviceArrayList;

TextView textInfo, textStatus;
ListView listViewPairedDevice;
ArrayAdapter<BluetoothDevice> pairedDeviceAdapter;
private UUID myUUID;

LinearLayout inputPane;
EditText inputField;
Button btnSend;

ThreadConnectBTdevice myThreadConnectBTdevice;
ThreadConnected myThreadConnected;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInfo = (TextView)findViewById(R.id.info);
textStatus = (TextView)findViewById(R.id.status);
listViewPairedDevice = (ListView)findViewById(R.id.pairedlist);

inputPane = (LinearLayout)findViewById(R.id.inputpane);
inputField = (EditText)findViewById(R.id.input);
btnSend = (Button)findViewById(R.id.send);
btnSend.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v) {
if(myThreadConnected!=null){
byte[] bytesToSend = inputField.getText().toString().getBytes();
myThreadConnected.write(bytesToSend);
}
}});

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this,
"FEATURE_BLUETOOTH NOT support",
Toast.LENGTH_LONG).show();
finish();
return;
}

//generate UUID on web: http://www.famkruithof.net/uuid/uuidgen
//have to match the UUID on the another device of the BT connection
myUUID = UUID.fromString("ec79da00-853f-11e4-b4a9-0800200c9a66");

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not supported on this hardware platform",
Toast.LENGTH_LONG).show();
finish();
return;
}

String stInfo = bluetoothAdapter.getName() + "\n" +
bluetoothAdapter.getAddress();
textInfo.setText(stInfo);
}

@Override
protected void onStart() {
super.onStart();

//Turn ON BlueTooth if it is OFF
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}

setup();
}

private void setup() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
pairedDeviceArrayList = new ArrayList<BluetoothDevice>();

for (BluetoothDevice device : pairedDevices) {
pairedDeviceArrayList.add(device);
}

pairedDeviceAdapter = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1, pairedDeviceArrayList);
listViewPairedDevice.setAdapter(pairedDeviceAdapter);

listViewPairedDevice.setOnItemClickListener(new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
BluetoothDevice device =
(BluetoothDevice)parent.getItemAtPosition(position);
Toast.makeText(MainActivity.this,
"Name: " + device.getName() + "\n"
+ "Address: " + device.getAddress() + "\n"
+ "BondState: " + device.getBondState() + "\n"
+ "BluetoothClass: " + device.getBluetoothClass() + "\n"
+ "Class: " + device.getClass(),
Toast.LENGTH_LONG).show();

textStatus.setText("start ThreadConnectBTdevice");
myThreadConnectBTdevice = new ThreadConnectBTdevice(device);
myThreadConnectBTdevice.start();
}});
}
}

@Override
protected void onDestroy() {
super.onDestroy();

if(myThreadConnectBTdevice!=null){
myThreadConnectBTdevice.cancel();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode==REQUEST_ENABLE_BT){
if(resultCode == Activity.RESULT_OK){
setup();
}else{
Toast.makeText(this,
"BlueTooth NOT enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}

private class ThreadConnectBTdevice extends Thread {
private BluetoothSocket bluetoothSocket = null;
private final BluetoothDevice bluetoothDevice;


public ThreadConnectBTdevice(BluetoothDevice device) {
bluetoothDevice = device;

try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
textStatus.setText("bluetoothSocket: \n" + bluetoothSocket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void run() {
boolean success = false;
try {
bluetoothSocket.connect();
success = true;
} catch (IOException e) {
e.printStackTrace();

final String eMessage = e.getMessage();
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("something wrong bluetoothSocket.connect(): \n" + eMessage);
}});

try {
bluetoothSocket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}

if(success){
//connect successful
final String msgconnected = "connect successful:\n"
+ "BluetoothSocket: " + bluetoothSocket + "\n"
+ "BluetoothDevice: " + bluetoothDevice;

runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(msgconnected);

listViewPairedDevice.setVisibility(View.GONE);
inputPane.setVisibility(View.VISIBLE);
}});

startThreadConnected(bluetoothSocket);
}else{
//fail
}
}

public void cancel() {

Toast.makeText(getApplicationContext(),
"close bluetoothSocket",
Toast.LENGTH_LONG).show();

try {
bluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

private void startThreadConnected(BluetoothSocket socket){

myThreadConnected = new ThreadConnected(socket);
myThreadConnected.start();
}

private class ThreadConnected extends Thread {
private final BluetoothSocket connectedBluetoothSocket;
private final InputStream connectedInputStream;
private final OutputStream connectedOutputStream;

public ThreadConnected(BluetoothSocket socket) {
connectedBluetoothSocket = socket;
InputStream in = null;
OutputStream out = null;

try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

connectedInputStream = in;
connectedOutputStream = out;
}

@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;

while (true) {
try {
bytes = connectedInputStream.read(buffer);
String strReceived = new String(buffer, 0, bytes);
final String msgReceived = String.valueOf(bytes) +
" bytes received:\n"
+ strReceived;

runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(msgReceived);
}});

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

final String msgConnectionLost = "Connection lost:\n"
+ e.getMessage();
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(msgConnectionLost);
}});
}
}
}

public void write(byte[] buffer) {
try {
connectedOutputStream.write(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void cancel() {
try {
connectedBluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

}

activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidbluetooth.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/info"
android:textStyle="bold|italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/status"
android:textSize="28sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<ListView
android:id="@+id/pairedlist"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<LinearLayout
android:id="@+id/inputpane"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">

<EditText
android:id="@+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sent"/>

</LinearLayout>

</LinearLayout>


download filesDownload the files.


Remark: both side have to modify AndroidManifest.xml to add permission of "android.permission.BLUETOOTH".


Related:
- Android example to communicate with Bluetooth device, HC-06 Bluetooth Module

Make BlueTooth connection between Android devices

The previous post show how to List paired BlueTooth devices. Here I show how to make connection between Android devices with Bluetooth.

In order to make it simple, I separate its functionality in two app:
  • AndroidBlueToothBeCOnnected:
    It start a BluetoothServerSocket by calling bluetoothAdapter.listenUsingRfcommWithServiceRecord().
    Then wait for connection with accept().
  • AndroidBlueTooth:
    It search for paired bluetooth devices, and request connect.

This example show making connection only, nothing else can do.

AndroidBlueToothBeCOnnected:

MainActivity.java
package com.example.androidbluetoothbeconnected;

import java.io.IOException;
import java.util.UUID;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private static final int REQUEST_ENABLE_BT = 1;

BluetoothAdapter bluetoothAdapter;

private UUID myUUID;
private String myName;

TextView textInfo, textStatus;

ThreadBeConnected myThreadBeConnected;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInfo = (TextView)findViewById(R.id.info);
textStatus = (TextView)findViewById(R.id.status);

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this,
"FEATURE_BLUETOOTH NOT support",
Toast.LENGTH_LONG).show();
finish();
return;
}

//generate UUID on web: http://www.famkruithof.net/uuid/uuidgen
//have to match the UUID on the another device of the BT connection
myUUID = UUID.fromString("ec79da00-853f-11e4-b4a9-0800200c9a66");
myName = myUUID.toString();

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not supported on this hardware platform",
Toast.LENGTH_LONG).show();
finish();
return;
}

String stInfo = bluetoothAdapter.getName() + "\n" +
bluetoothAdapter.getAddress();
textInfo.setText(stInfo);
}

@Override
protected void onStart() {
super.onStart();

//Turn ON BlueTooth if it is OFF
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}

setup();
}

private void setup() {
textStatus.setText("setup()");
myThreadBeConnected = new ThreadBeConnected();
myThreadBeConnected.start();
}

@Override
protected void onDestroy() {
super.onDestroy();

if(myThreadBeConnected!=null){
myThreadBeConnected.cancel();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode==REQUEST_ENABLE_BT){
if(resultCode == Activity.RESULT_OK){
setup();
}else{
Toast.makeText(this,
"BlueTooth NOT enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}


private class ThreadBeConnected extends Thread {

private BluetoothServerSocket bluetoothServerSocket = null;

public ThreadBeConnected() {
try {
bluetoothServerSocket =
bluetoothAdapter.listenUsingRfcommWithServiceRecord(myName, myUUID);

textStatus.setText("Waiting\n"
+ "bluetoothServerSocket :\n"
+ bluetoothServerSocket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void run() {
BluetoothSocket bluetoothSocket = null;

if(bluetoothServerSocket!=null){
try {
bluetoothSocket = bluetoothServerSocket.accept();

BluetoothDevice remoteDevice = bluetoothSocket.getRemoteDevice();

final String strConnected = "Connected:\n" +
remoteDevice.getName() + "\n" +
remoteDevice.getAddress();

//connected
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText(strConnected);
}});

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();

final String eMessage = e.getMessage();
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("something wrong: \n" + eMessage);
}});
}
}else{
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("bluetoothServerSocket == null");
}});
}
}

public void cancel() {

Toast.makeText(getApplicationContext(),
"close bluetoothServerSocket",
Toast.LENGTH_LONG).show();

try {
bluetoothServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

/res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidbluetoothbeconnected.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/info"
android:textStyle="bold|italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/status"
android:textSize="28sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</LinearLayout>

Modify AndroidManifest.xml to add permission of "android.permission.BLUETOOTH".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidbluetoothbeconnected"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.BLUETOOTH"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

</manifest>

download filesDownload the files.


AndroidBlueTooth:

MainActivity.java
package com.example.androidbluetooth;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private static final int REQUEST_ENABLE_BT = 1;

BluetoothAdapter bluetoothAdapter;

ArrayList<BluetoothDevice> pairedDeviceArrayList;

TextView textInfo, textStatus;
ListView listViewPairedDevice;
ArrayAdapter<BluetoothDevice> pairedDeviceAdapter;
private UUID myUUID;

ThreadConnectBTdevice myThreadConnectBTdevice;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInfo = (TextView)findViewById(R.id.info);
textStatus = (TextView)findViewById(R.id.status);
listViewPairedDevice = (ListView)findViewById(R.id.pairedlist);

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this,
"FEATURE_BLUETOOTH NOT support",
Toast.LENGTH_LONG).show();
finish();
return;
}

//generate UUID on web: http://www.famkruithof.net/uuid/uuidgen
//have to match the UUID on the another device of the BT connection
myUUID = UUID.fromString("ec79da00-853f-11e4-b4a9-0800200c9a66");

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not supported on this hardware platform",
Toast.LENGTH_LONG).show();
finish();
return;
}

String stInfo = bluetoothAdapter.getName() + "\n" +
bluetoothAdapter.getAddress();
textInfo.setText(stInfo);
}

@Override
protected void onStart() {
super.onStart();

//Turn ON BlueTooth if it is OFF
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}

setup();
}

private void setup() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
pairedDeviceArrayList = new ArrayList<BluetoothDevice>();

for (BluetoothDevice device : pairedDevices) {
pairedDeviceArrayList.add(device);
}

pairedDeviceAdapter = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1, pairedDeviceArrayList);
listViewPairedDevice.setAdapter(pairedDeviceAdapter);

listViewPairedDevice.setOnItemClickListener(new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
BluetoothDevice device =
(BluetoothDevice)parent.getItemAtPosition(position);
Toast.makeText(MainActivity.this,
"Name: " + device.getName() + "\n"
+ "Address: " + device.getAddress() + "\n"
+ "BondState: " + device.getBondState() + "\n"
+ "BluetoothClass: " + device.getBluetoothClass() + "\n"
+ "Class: " + device.getClass(),
Toast.LENGTH_LONG).show();

textStatus.setText("start ThreadConnectBTdevice");
myThreadConnectBTdevice = new ThreadConnectBTdevice(device);
myThreadConnectBTdevice.start();
}});
}
}



@Override
protected void onDestroy() {
super.onDestroy();

if(myThreadConnectBTdevice!=null){
myThreadConnectBTdevice.cancel();
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode==REQUEST_ENABLE_BT){
if(resultCode == Activity.RESULT_OK){
setup();
}else{
Toast.makeText(this,
"BlueTooth NOT enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}

private class ThreadConnectBTdevice extends Thread {
private BluetoothSocket bluetoothSocket = null;
private final BluetoothDevice bluetoothDevice;


public ThreadConnectBTdevice(BluetoothDevice device) {
bluetoothDevice = device;

try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(myUUID);
textStatus.setText("bluetoothSocket: \n" + bluetoothSocket);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

@Override
public void run() {
boolean success = false;
try {
bluetoothSocket.connect();
success = true;
} catch (IOException e) {
e.printStackTrace();

final String eMessage = e.getMessage();
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("something wrong bluetoothSocket.connect(): \n" + eMessage);
}});

try {
bluetoothSocket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}

if(success){
//connect successful
runOnUiThread(new Runnable(){

@Override
public void run() {
textStatus.setText("connect successful");
}});
}else{
//fail
}
}

public void cancel() {

Toast.makeText(getApplicationContext(),
"close bluetoothSocket",
Toast.LENGTH_LONG).show();

try {
bluetoothSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

}

/res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidbluetooth.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/info"
android:textStyle="bold|italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/status"
android:textSize="28sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

<ListView
android:id="@+id/pairedlist"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>

AndroidManifest.xml with permission of "android.permission.BLUETOOTH"
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidbluetooth"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.BLUETOOTH"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

</manifest>

download filesDownload the files.

Next:
Bluetooth communication between Android devices

List paired BlueTooth devices, and read its information

This example check BlueTooth support of the device, then check if it is enabled, and list paired devices in ListView. When user click on any device, display it details.


MainActivity.java
package com.example.androidbluetooth;

import java.util.ArrayList;
import java.util.Set;

import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

private static final int REQUEST_ENABLE_BT = 1;

BluetoothAdapter bluetoothAdapter;

ArrayList<BluetoothDevice> pairedDeviceArrayList;

ListView listViewPairedDevice;
ArrayAdapter<BluetoothDevice> pairedDeviceAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listViewPairedDevice = (ListView)findViewById(R.id.pairedlist);

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
Toast.makeText(this,
"FEATURE_BLUETOOTH NOT support",
Toast.LENGTH_LONG).show();
finish();
return;
}

bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this,
"Bluetooth is not supported on this hardware platform",
Toast.LENGTH_LONG).show();
finish();
return;
}
}

@Override
protected void onStart() {
super.onStart();

//Turn ON BlueTooth if it is OFF
if (!bluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}

setup();
}

private void setup() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
pairedDeviceArrayList = new ArrayList<BluetoothDevice>();

for (BluetoothDevice device : pairedDevices) {
pairedDeviceArrayList.add(device);
}

pairedDeviceAdapter = new ArrayAdapter<BluetoothDevice>(this,
android.R.layout.simple_list_item_1, pairedDeviceArrayList);
listViewPairedDevice.setAdapter(pairedDeviceAdapter);

listViewPairedDevice.setOnItemClickListener(new OnItemClickListener(){

@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
BluetoothDevice device =
(BluetoothDevice)parent.getItemAtPosition(position);
Toast.makeText(MainActivity.this,
"Name: " + device.getName() + "\n"
+ "Address: " + device.getAddress() + "\n"
+ "BondState: " + device.getBondState() + "\n"
+ "BluetoothClass: " + device.getBluetoothClass() + "\n"
+ "Class: " + device.getClass(),
Toast.LENGTH_LONG).show();
}});
}
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if(requestCode==REQUEST_ENABLE_BT){
if(resultCode == Activity.RESULT_OK){
setup();
}else{
Toast.makeText(this,
"BlueTooth NOT enabled",
Toast.LENGTH_SHORT).show();
finish();
}
}
}
}

/res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidbluetooth.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<ListView
android:id="@+id/pairedlist"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>

"android.permission.BLUETOOTH" is needed in AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidbluetooth"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.BLUETOOTH"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

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

</manifest>

download filesDownload the files.

Next:
Make BlueTooth connection between Android devices
Bluetooth communication between Android devices

Check if your Android device support Bluetooth Low Energy

Android 4.3 (API Level 18) introduces built-in platform support for Bluetooth Low Energy in the central role and provides APIs that apps can use to discover devices, query for services, and read/write characteristics.

To check if your device support Bluetooth Low Energy programmically, check (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)).

Nexus 7, 1st gen, not support BlueTooth LE!
MK 908III Android mini PC support both Bluetooth and Bluetooth LE


package com.example.androidcheckbtle;

import android.support.v7.app.ActionBarActivity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {

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

TextView textManufacturer = (TextView)findViewById(R.id.manufacturer);
TextView textModel = (TextView)findViewById(R.id.model);
TextView textSupportBT = (TextView)findViewById(R.id.supportbt);
TextView textSupportBTLE = (TextView)findViewById(R.id.supportbtle);

//Get brand, manufacturer and model of your device
textManufacturer.setText(Build.BRAND + " : " + Build.MANUFACTURER);
textModel.setText(Build.MODEL);

//Check if your device support BlueTooth
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)){
textSupportBT.setText("Support BLUETOOTH");
}else{
textSupportBT.setText("NOT Support BLUETOOTH");
}

//Check if your device support Bluetooth Low Energy
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
textSupportBTLE.setText("Support BLUETOOTH_LE");
}else{
textSupportBTLE.setText("NOT Support BLUETOOTH_LE");
}
}

}

/res/layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.example.androidcheckbtle.MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/manufacturer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/model"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/supportbt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/supportbtle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</LinearLayout>