I try to make communication between two devices by using Bluteooth but always the application stopped when i try to test it.
I just try to send simple string (for exemple 'A') but also I have errors.
Also i can't turn on/off bluetooth manually.
the error is : Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothAdapter.isEnabled()' on a null object reference
at com.example.pfe.reglages.onCreate(reglages.java:53).
I need help because it's my project to get graduated
Thank you.
entrainement.java
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Handler;
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.os.Message;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import static android.bluetooth.BluetoothAdapter.getDefaultAdapter;
import static android.content.ContentValues.TAG;
public class entrainement extends AppCompatActivity {
private boolean CONTINUE_READ_WRITE = true;
private boolean CONNECTION_ENSTABLISHED = false;
private boolean DEVICES_IN_LIST = true;
private static String NAME = "pfe.fawez";
private static UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
Button btn6, btn7, btn8, btn16, btn9, btn5;
EditText txt;
TextView logview;
ListView lv;
ArrayList<String> listItems;
ArrayAdapter<String> listAdapter;
private BluetoothAdapter adapter;
private BluetoothSocket socket;
private InputStream is;
private OutputStream os;
private BluetoothDevice remoteDevice;
private Set<BluetoothDevice> pairedDevices;
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.entrainement);
btn6 = findViewById(R.id.button6);
btn7 = findViewById(R.id.button7);
btn8 = findViewById(R.id.button8);
btn16 = findViewById(R.id.button16);
btn9 = findViewById(R.id.button9);
btn5 = findViewById(R.id.button5);
txt = findViewById(R.id.editText2);
logview = findViewById(R.id.textView14);
lv = (ListView)findViewById(R.id.listView);
listItems = new ArrayList<String>(); //shows messages in list view
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, listItems);
lv.setAdapter(listAdapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() //list onclick selection process
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if(DEVICES_IN_LIST)
{
String name = (String) parent.getItemAtPosition(position);
selectBTdevice(name); //selected device will be set globally
//Toast.makeText(getApplicationContext(), "Selected " + name, Toast.LENGTH_SHORT).show();
//do not automatically call OpenBT(null) because makes troubles with server/client selection
}
else //message is selected
{
String message = (String) parent.getItemAtPosition(position);
txt.setText(message);
}
}
/*adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) //If the adapter is null, then Bluetooth is not supported
{
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_SHORT).show();
finish();
return;
}
list(null);*/
});
btn9.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = txt.getText().toString();
byte[] b = textToSend.getBytes();
try {
os.write(b);
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
logview.append("\nConnection !\n");
}
});
btn6.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "R";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn16.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "L";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn7.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "X";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
btn8.setOnClickListener(new View.OnClickListener() //sends text from text button
{
#Override
public void onClick(View v) {
String textToSend = "Y";
byte[] b = textToSend.getBytes();
try {
os.write(b);
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Not sent", Toast.LENGTH_SHORT).show(); //usually problem server-client decision
}
}
});
}
private Runnable writter = new Runnable() {
#Override
public void run() {
while (CONTINUE_READ_WRITE) //reads from open stream
{
try
{
os.flush();
Thread.sleep(2000);
} catch (Exception e)
{
Log.e(TAG, "Writer failed in flushing output stream...");
CONTINUE_READ_WRITE = false;
}
}
}
};
public void list(View v) //shows paired devices to UI
{
CONNECTION_ENSTABLISHED = false; //protect from failing
listItems.clear(); //remove chat history
listAdapter.notifyDataSetChanged();
pairedDevices = adapter.getBondedDevices(); //list of devices
for(BluetoothDevice bt : pairedDevices) //foreach
{
listItems.add(0, bt.getName());
}
listAdapter.notifyDataSetChanged(); //reload UI
}
public void selectBTdevice(String name) //for selecting device from list which is used in procedures
{
if(pairedDevices.isEmpty()) {
list(null);
Toast.makeText(getApplicationContext(), "Selecting was unsucessful, no devices in list." ,Toast.LENGTH_SHORT ).show();
}
for(BluetoothDevice bt : pairedDevices) //foreach
{
if(name.equals(bt.getName()))
{
remoteDevice = bt;
Toast.makeText(getApplicationContext(), "Selected " + remoteDevice.getName(), Toast.LENGTH_SHORT ).show();
}
}
}
public void openBT(View v) //opens right thread for server or client
{
if(adapter == null)
{
adapter = getDefaultAdapter();
Log.i(TAG, "Backup way of getting adapter was used!");
}
CONTINUE_READ_WRITE = true; //writer tiebreaker
socket = null; //resetting if was used previously
is = null; //resetting if was used previously
os = null; //resetting if was used previously
if(pairedDevices.isEmpty() || remoteDevice == null)
{
Toast.makeText(this, "Paired device is not selected, choose one", Toast.LENGTH_SHORT).show();
return;
}
}
public void closeBT(View v) //for closing opened communications, cleaning used resources
{
/*if(adapter == null)
return;*/
CONTINUE_READ_WRITE = false;
CONNECTION_ENSTABLISHED = false;
if (is != null) {
try {is.close();} catch (Exception e) {}
is = null;
}
if (os != null) {
try {os.close();} catch (Exception e) {}
os = null;
}
if (socket != null) {
try {socket.close();} catch (Exception e) {}
socket = null;
}
try {
Handler mHandler = new Handler();
mHandler.removeCallbacksAndMessages(writter);
mHandler.removeCallbacksAndMessages(serverListener);
mHandler.removeCallbacksAndMessages(clientConnecter);
Log.i(TAG, "Threads ended...");
}catch (Exception e)
{
Log.e(TAG, "Attemp for closing threads was unsucessfull.");
}
Toast.makeText(getApplicationContext(), "Communication closed" ,Toast.LENGTH_SHORT).show();
list(null); //shows list for reselection
txt.setText(getResources().getString(R.string.demo));
}
private Runnable serverListener = new Runnable()
{
public void run()
{
try //opening of BT connection
{
android.util.Log.i("TrackingFlow", "Server socket: new way used...");
socket =(BluetoothSocket) remoteDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class}).invoke(remoteDevice,1);
socket.connect();
CONNECTION_ENSTABLISHED = true; //protect from failing
} catch(Exception e) //obsolete way how to open BT
{
try
{
android.util.Log.e("TrackingFlow", "Server socket: old way used...");
BluetoothServerSocket tmpsocket = adapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
socket = tmpsocket.accept();
CONNECTION_ENSTABLISHED = true; //protect from failing
android.util.Log.i("TrackingFlow", "Listening...");
}
catch (Exception ie)
{
Log.e(TAG, "Socket's accept method failed", ie);
ie.printStackTrace();
}
}
Log.i(TAG, "Server is ready for listening...");
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
listItems.clear(); //remove chat history
listItems.add(0, String.format(" Server opened! Waiting for clients..."));
listAdapter.notifyDataSetChanged();
}});
try //reading part
{
is = socket.getInputStream();
os = socket.getOutputStream();
new Thread(writter).start();
int bufferSize = 1024;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while(CONTINUE_READ_WRITE) //Keep reading the messages while connection is open...
{
final StringBuilder sb = new StringBuilder();
bytesRead = is.read(buffer);
if (bytesRead != -1) {
String result = "";
while ((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0))
{
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = is.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
sb.append(result);
}
android.util.Log.e("TrackingFlow", "Read: " + sb.toString());
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
Toast.makeText(entrainement.this, sb.toString(), Toast.LENGTH_SHORT).show();
listItems.add(0, String.format("< %s", sb.toString())); //showing in history
listAdapter.notifyDataSetChanged();
}
});
}
}
catch(IOException e){
Log.e(TAG, "Server not connected...");
e.printStackTrace();
}
}
};
private Runnable clientConnecter = new Runnable()
{
#Override
public void run()
{
try
{
socket = remoteDevice.createRfcommSocketToServiceRecord(MY_UUID);
socket.connect();
CONNECTION_ENSTABLISHED = true; //protect from failing
Log.i(TAG, "Client is connected...");
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
listItems.clear(); //remove chat history
listItems.add(0, String.format(" ready to communicate! Write something..."));
listAdapter.notifyDataSetChanged();
}});
os = socket.getOutputStream();
is = socket.getInputStream();
new Thread(writter).start();
Log.i(TAG, "Preparation for reading was done");
int bufferSize = 1024;
int bytesRead = -1;
byte[] buffer = new byte[bufferSize];
while(CONTINUE_READ_WRITE) //Keep reading the messages while connection is open...
{
final StringBuilder sb = new StringBuilder();
bytesRead = is.read(buffer);
if (bytesRead != -1)
{
String result = "";
while ((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0))
{
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = is.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
sb.append(result);
}
android.util.Log.e("TrackingFlow", "Read: " + sb.toString());
runOnUiThread(new Runnable() {
#Override
public void run() { //Show message on UIThread
Toast.makeText(entrainement.this, sb.toString(), Toast.LENGTH_SHORT).show();
listItems.add(0, String.format("< %s", sb.toString()));
listAdapter.notifyDataSetChanged();
}
});
}
}
catch (IOException e)
{
Log.e(TAG, "Client not connected...");
e.printStackTrace();
}
}
};
}
reglages.java
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Set;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
public class reglages extends AppCompatActivity {
private static final int REQUEST_ENABLE_BT = 0;
private static final int REQUEST_DISCOVER_BT = 1;
TextView mStatusBlueTv, mPairedTv;
ImageView mBlueIv;
Button mOnBtn, mOffBtn, mDiscoverBtn, mPairedBtn;
BluetoothAdapter mBlueAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.reglages);
mStatusBlueTv = findViewById(R.id.statusBluetoothTv);
mPairedTv = findViewById(R.id.pairedTv);
mBlueIv = findViewById(R.id.bluetoothIv);
mOnBtn = findViewById(R.id.onBtn);
mOffBtn = findViewById(R.id.offBtn);
mDiscoverBtn = findViewById(R.id.discoverableBtn);
mPairedBtn = findViewById(R.id.pairedBtn);
//adapter
mBlueAdapter = BluetoothAdapter.getDefaultAdapter();
//check if bluetooth is available or not
if (mBlueAdapter == null){
mStatusBlueTv.setText("Bluetooth is not available");
}
else {
mStatusBlueTv.setText("Bluetooth is available");
}
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()){
mBlueIv.setImageResource(R.drawable.ic_action_on);
}
else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
//on btn click
mOnBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBlueAdapter.isEnabled()){
showToast("Turning On Bluetooth...");
//intent to on bluetooth
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
}
else {
showToast("Bluetooth is already on");
}
}
});
//discover bluetooth btn click
mDiscoverBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mBlueAdapter.isDiscovering()){
showToast("Making Your Device Discoverable");
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(intent, REQUEST_DISCOVER_BT);
}
}
});
//off btn click
mOffBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()){
mBlueAdapter.disable();
showToast("Turning Bluetooth Off");
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
else {
showToast("Bluetooth is already off");
}
}
});
//get paired devices btn click
mPairedBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mBlueAdapter.isEnabled()){
mPairedTv.setText("Paired Devices");
Set<BluetoothDevice> devices = mBlueAdapter.getBondedDevices();
for (BluetoothDevice device: devices){
mPairedTv.append("\nDevice: " + device.getName()+ ", " + device);
}
}
else {
//bluetooth is off so can't get paired devices
showToast("Turn on bluetooth to get paired devices");
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK){
//bluetooth is on
mBlueIv.setImageResource(R.drawable.ic_action_on);
showToast("Bluetooth is on");
}
else {
//user denied to turn bluetooth on
showToast("could't on bluetooth");
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
//toast message function
private void showToast(String msg){
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
}
Then change this lines:
//check if bluetooth is available or not
if (mBlueAdapter == null){
mStatusBlueTv.setText("Bluetooth is not available");
}
else {
mStatusBlueTv.setText("Bluetooth is available");
}
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()){
mBlueIv.setImageResource(R.drawable.ic_action_on);
}
else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
To this:
//check if bluetooth is available or not
if (mBlueAdapter == null) {
mStatusBlueTv.setText("Bluetooth is not available");
mBlueIv.setImageResource(R.drawable.ic_action_off);
} else {
mStatusBlueTv.setText("Bluetooth is available");
//set image according to bluetooth status(on/off)
if (mBlueAdapter.isEnabled()) {
mBlueIv.setImageResource(R.drawable.ic_action_on);
} else {
mBlueIv.setImageResource(R.drawable.ic_action_off);
}
}
And each time you check isEnabled check for null first, changing:
if (mBlueAdapter.isEnabled()){
to:
if (mBlueAdapter != null && mBlueAdapter.isEnabled()) {
This way you'll prevent having NullPointers when the Bluetooth is not available (mBlueAdapter == null) as you can not check isEnabled() in this cases.
Related
I am working on a project that can send and receive Strings to and from an Arduino to control and monitor various sensors and lights. I am running into an issue where once I leave the activity that connects to Bluetooth and then return to that same activity after visiting the home activity I am no longer able to send and receive data. The sending and receiving of strings works perfectly until I leave the activity to go to the home activity and come back.
Here is the Java code for the sensor activity:
package com.example.arduinocontrol;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class uvlight extends AppCompatActivity implements OnClickListener{
private static final int REQUEST_ENABLE_BT = 1;
private CardView uvLight;
//listeners for button presses
Button on, off,clear;
//textbox below buttons
TextView t1,t2,t3;
BluetoothAdapter mBluetoothAdapter;
BluetoothDevice mDevice;
ByteArrayInputStream mSocket;
ConnectedThread mConnectedThread = null;
ConnectThread mConnectThread = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
//Instantiation
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_uvlight);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),"BT not supported!", Toast.LENGTH_SHORT).show();
return;
}
if (!mBluetoothAdapter.isEnabled()) {
//opens a window to ask user to turn on bluetooth
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
mDevice = device;
}
}
mConnectThread = new ConnectThread(mDevice);
mConnectThread.start();
try {
setw();
} catch (Exception e) {
e.printStackTrace();
}
}
#SuppressLint("ClickableViewAccessibility")
private void setw() throws IOException {
//text for bluetooth device details
t1=(TextView)findViewById(R.id.textView3);
t2=(TextView)findViewById(R.id.response);
t2.setMovementMethod(new ScrollingMovementMethod());
String name = mDevice.getName().toString();
try {
t1.setText("Connected to: " + name);
} catch (Exception e) {
e.printStackTrace();
}
//links on and off to their element IDs
on=(Button)findViewById(R.id.uvlighton);
off=(Button)findViewById(R.id.uvlightoff);
clear=(Button)findViewById(R.id.clear);
//clears log text
clear.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
t2.setText("");
}
});
on.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
//sends 'o' char to Arduino
// method to turn on uv light
if(mConnectedThread != null) {
//String sig = "o";
//mConnectedThread.write(sig.getBytes());
int sig = 112;
mConnectedThread.write(sig);
}
}
});
off.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
//method to turn off uv light
if(mConnectedThread != null) {
//String sig1 = "f";
//mConnectedThread.write(sig1.getBytes());
int sig = 113;
mConnectedThread.write(sig);
}
}
});
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
//HC-05 unique uuid
private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
try {
//creates RFCOMM socket
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
//shows user they are connected
Toast.makeText(getApplicationContext(), "Connected to your Arduino", Toast.LENGTH_SHORT).show();
//displays bt info in text field
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Unable to connect!", Toast.LENGTH_SHORT).show();
}
mmSocket = tmp;
}
public void run() {
mBluetoothAdapter.cancelDiscovery();
//need the if for this edge case
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
if (mSocket != null) {
mSocket.close();
}
} catch (IOException closeException) {
Toast.makeText(getApplicationContext(), "Unable to connect socket!", Toast.LENGTH_SHORT).show();
}
return;
}
//new connected thread obj
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//Thread for bluetooth process
private class ConnectedThread extends Thread {
//copies bt socket for threading
private final BluetoothSocket mmSocket;
//copies input stream obj for threading
private final InputStream mmInStream;
//copies output stream obj for threading
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
//reads from Arduino
#Override
public void run() {
byte[] buffer = new byte[1024];
int begin = 0;
int bytes = 0;
while (true) {
try {
bytes += mmInStream.read(buffer, bytes, buffer.length - bytes);
for (int i = begin; i < bytes; i++) {
//end char for a given message from Arduino
if (buffer[i] == "#".getBytes()[0]) {
mHandler.obtainMessage(1, begin, i, buffer).sendToTarget();
begin = i + 1;
if (i == bytes - 1) {
bytes = 0;
begin = 0;
}
}
}
} catch (IOException e) {
break;
}
}
}
//writes to the output stream (in this case the Arduino)
public void write(/*byte[] bytes*/int num) {
try {
Toast.makeText(getApplicationContext(), "sending bytes", Toast.LENGTH_SHORT).show();
mmOutStream.write(num);
} catch (IOException e) {
e.printStackTrace();
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
#Override
public void onClick(View v)
{
try
{
}
catch (Exception e)
{
//displays toast message
Toast.makeText(getApplicationContext(),e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
//Suppresses an annoying handler lear warning
#SuppressLint("HandlerLeak")
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
byte[] writeBuf = (byte[]) msg.obj;
int begin = (int)msg.arg1;
int end = (int)msg.arg2;
switch(msg.what) {
case 1:
String writeMessage = new String(writeBuf);
writeMessage = writeMessage.substring(begin, end);
//sends message to homepage to turn cardview red
//string called error contains value of writeMessage
Intent intent = new Intent("errorCode").putExtra("error", writeMessage);
LocalBroadcastManager.getInstance(uvlight.this).sendBroadcast(intent);
//write message to the scrolling textbox
t2.append(writeMessage);
break;
}
}
};
}
Here is the Java code for the home activity:
package com.example.arduinocontrol;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
public class HomeActivity extends AppCompatActivity implements View.OnClickListener {
private CardView airPump, flowMeter, humiditySensor, levelSwitch1, levelSwitch2, lightStrip, phMeter, uvLight, waterPump, solenoidValve, nutrientPump;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
//defines cards
airPump = (CardView) findViewById(R.id.airpump);
flowMeter = (CardView) findViewById(R.id.flowmeter);
humiditySensor = (CardView) findViewById(R.id.humiditysensor);
levelSwitch1 = (CardView) findViewById(R.id.levelswitch1);
levelSwitch2 = (CardView) findViewById(R.id.levelswitch2);
lightStrip = (CardView) findViewById(R.id.lightstrip);
phMeter = (CardView) findViewById(R.id.phmeter);
uvLight = (CardView) findViewById(R.id.uvlight);
waterPump = (CardView) findViewById(R.id.waterpump);
solenoidValve = (CardView) findViewById(R.id.solenoidvalve);
nutrientPump = (CardView) findViewById(R.id.nutrientpump);
//click listeners
airPump.setOnClickListener(this);
flowMeter.setOnClickListener(this);
humiditySensor.setOnClickListener(this);
levelSwitch1.setOnClickListener(this);
levelSwitch2.setOnClickListener(this);
lightStrip.setOnClickListener(this);
phMeter.setOnClickListener(this);
uvLight.setOnClickListener(this);
waterPump.setOnClickListener(this);
solenoidValve.setOnClickListener(this);
nutrientPump.setOnClickListener(this);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, new IntentFilter("errorCode"));
}
//turns Uvlight card red when an error is sent
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String errorMsg = intent.getStringExtra("error");
if (errorMsg.equals("-3")){
uvLight.setCardBackgroundColor(0xFFFF0000);
}
}
};
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
#Override
public void onClick(View v) {
Intent i;
//on click opens the new activity
switch(v.getId()){
case R.id.airpump : i = new Intent(this,Airpump.class); startActivity(i); break;
case R.id.flowmeter : i = new Intent(this,Flowmeter.class); startActivity(i); break;
case R.id.humiditysensor : i =new Intent(this,Humiditysensor.class); startActivity(i); break;
case R.id.levelswitch1 : i = new Intent(this,Levelswitch1.class); startActivity(i); break;
case R.id.levelswitch2 : i = new Intent(this,Levelswitch2.class); startActivity(i); break;
case R.id.lightstrip : i = new Intent(this,Lightstrip.class); startActivity(i); break;
case R.id.phmeter : i = new Intent(this,Phmeter.class); startActivity(i); break;
case R.id.uvlight : i = new Intent(this,uvlight.class); startActivity(i); break;
case R.id.waterpump : i = new Intent(this,Waterpump.class); startActivity(i); break;
case R.id.solenoidvalve : i = new Intent(this,solenoidvalve.class); startActivity(i); break;
case R.id.nutrientpump : i = new Intent(this,Nutrientpump.class); startActivity(i); break;
default:break;
}
}
}
I am new to Android Studio and this is the first time I have had to make a multi-threaded application. Thank You.
you can try to extract the Bluetooth connection method into a simple profit class, similar to "local broadcast manager". When "uvlight" on destroy Bluetooth connection will continue to open. Or you can refer to GitHub's excellent open source libraries, such as: https://github.com/akexorcist/BluetoothSPPLibrary 。 I believe you can learn more in it
I'm working on a project in which I want to receive the data(, separated value"only two values") from BLE server. my first question is I write the code for connection but I din't connect with it. and second how to read this comma separated value. and this comma separated value will come from arduino to BLE server and from BLE server the communication will be done between both. Code is Below.
IDs
#define SERVICE_UUID "ab0828b1-198e-4351-b779-901fa0e0371e"
#define CHARACTERISTIC_UUID_RX "4ac8a682-9736-4e5d-932b-e9b31405049c"
#define CHARACTERISTIC_UUID_TX "0972EF8C-7613-4075-AD52-756F33D4DA91"
code
package com.grng.rthr;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import com.grng.rthr.main.core.viewmodel.MainViewModel;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.grng.rthr.main.BackAwareApplication;
import com.grng.rthr.main.core.viewmodel.MainViewModel;
import com.grng.rthr.main.ui.fragment.atWork.ModeFragment;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;
public class BluetoothActivity extends AppCompatActivity {
// GUI Components
private TextView mBluetoothStatus;
private MainViewModel viewModel;
private TextView mReadBuffer;
private Button mScanBtn;
private Button mOffBtn;
private BluetoothAdapter mBTAdapter;
private Set<BluetoothDevice> mPairedDevices;
private ArrayAdapter<String> mBTArrayAdapter;
private ListView mDevicesListView;
private final String TAG = BluetoothActivity.class.getSimpleName();
private Handler mHandler; // Our main handler that will receive callback notifications
private ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
private BluetoothSocket mBTSocket = null; // bi-directional client-to-client data path
private static final UUID BTMODULEUUID = UUID.fromString("ab0828b1-198e-4351-b779-901fa0e0371e"); // "random" unique identifier
// #defines for identifying shared types between calling functions
private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
private final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
private final static int CONNECTING_STATUS = 3; // used in bluetooth handler to identify message status
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
// setTitle("Belt Monitoring");
setTitle("Belt Monitoring");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back_btn);
mBluetoothStatus = (TextView)findViewById(R.id.bluetoothStatus);
mReadBuffer = (TextView) findViewById(R.id.readBuffer);
mScanBtn = (Button)findViewById(R.id.scan);
mOffBtn = (Button)findViewById(R.id.off);
mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
mDevicesListView = (ListView)findViewById(R.id.devicesListView);
mDevicesListView.setAdapter(mBTArrayAdapter); // assign model to view
mDevicesListView.setOnItemClickListener(mDeviceClickListener);
bluetoothOn();
// Ask for location permission if not already allowed
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
mHandler = new Handler(){
public void handleMessage(android.os.Message msg){
if(msg.what == MESSAGE_READ){
String readMessage = null;
try {
readMessage = new String((byte[]) msg.obj, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mReadBuffer.setText(readMessage);
}
if(msg.what == CONNECTING_STATUS){
if(msg.arg1 == 1)
mBluetoothStatus.setText("Connected to Device: " + (String)(msg.obj));
else
mBluetoothStatus.setText("Connection Failed");
}
}
};
if (mBTArrayAdapter == null) {
// Device does not support Bluetooth
mBluetoothStatus.setText("Status: Bluetooth not found");
Toast.makeText(getApplicationContext(),"Bluetooth device not found!",Toast.LENGTH_SHORT).show();
}
else {
mScanBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bluetoothScan(v);
}
});
mOffBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
bluetoothOff(v);
}
});
}
}
private void bluetoothOn(){
if (!mBTAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
mBluetoothStatus.setText("Bluetooth enabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
}
}
private void bluetoothScan(View view){
mBTArrayAdapter.clear();
mPairedDevices = mBTAdapter.getBondedDevices();
if(mBTAdapter.isEnabled()) {
// put it's one to the adapter
for (BluetoothDevice device : mPairedDevices)
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
discovering();
}
private void discovering(){
if(mBTAdapter.isDiscovering()){
mBTAdapter.cancelDiscovery();
Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
}
else{
if(mBTAdapter.isEnabled()) {
mBTArrayAdapter.clear(); // clear items
mBTAdapter.startDiscovery();
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
else{
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
}
}
// Enter here after user selects "yes" or "no" to enabling radio
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent Data){
// Check which request we're responding to
if (requestCode == REQUEST_ENABLE_BT) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
mBluetoothStatus.setText("Enabled");
}
else
mBluetoothStatus.setText("Disabled");
}
}
private void bluetoothOff(View view){
mBTAdapter.disable(); // turn off
mBluetoothStatus.setText("Bluetooth disabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
}
final BroadcastReceiver blReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name to the list
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
}
};
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
if(!mBTAdapter.isEnabled()) {
Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
return;
}
mBluetoothStatus.setText("Connecting...");
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
final String address = info.substring(info.length() - 17);
final String name = info.substring(0,info.length() - 17);
// Spawn a new thread to avoid blocking the GUI one
new Thread()
{
public void run() {
boolean fail = false;
BluetoothDevice device = mBTAdapter.getRemoteDevice(address);
try {
mBTSocket = createBluetoothSocket(device);
} catch (IOException e) {
fail = true;
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
}
// Establish the Bluetooth socket connection.
try {
mBTSocket.connect();
} catch (IOException e) {
try {
fail = true;
mBTSocket.close();
mHandler.obtainMessage(CONNECTING_STATUS, -1, -1)
.sendToTarget();
} catch (IOException e2) {
//insert code to deal with this
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
}
}
if(fail == false) {
mConnectedThread = new ConnectedThread(mBTSocket);
mConnectedThread.start();
mHandler.obtainMessage(CONNECTING_STATUS, 1, -1, name)
.sendToTarget();
}
}
}.start();
}
};
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
return (BluetoothSocket) m.invoke(device, BTMODULEUUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.available();
if(bytes != 0) {
buffer = new byte[1024];
SystemClock.sleep(100); //pause and wait for rest of data. Adjust this depending on your sending speed.
bytes = mmInStream.available(); // how many bytes are ready to be read?
bytes = mmInStream.read(buffer, 0, bytes); // record how many bytes we actually read
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget(); // Send the obtained bytes to the UI activity
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(String input) {
byte[] bytes = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
I am trying to make a link (bluetooth) between my arduino and android. i want to recieve the data from the arduino. The ListenInput thread does get started but nothing more
Here is my code
package com.codeyard.teleprompter;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
public class bleutoothrevivedeletenow extends AppCompatActivity {
static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
String address = null;
BluetoothAdapter myBluetooth = null;
BluetoothSocket btSocket = null;
Button StartConnection;
Button Disconnect;
Button Recieve;
TextView incomingData;
InputStream mmInStream = null;
String incomingMessage;
StringBuilder messages;
Thread ListenInput = new Thread() {
#Override
public void run() {
try {
mmInStream = btSocket.getInputStream();
byte[] buffer = new byte[1024];
int bytes;
Toast.makeText(getApplicationContext(), "Thread started///", Toast.LENGTH_LONG).show();
while (true) {
// Read from the InputStream
try {
if (mmInStream == null) {
Log.e("", "InputStream is null");
}
bytes = mmInStream.read(buffer);
incomingMessage = new String(buffer, 0, bytes);
messages.append(incomingMessage);
Toast.makeText(getApplicationContext(), "incoming message", Toast.LENGTH_LONG).show();
Toast.makeText(bleutoothrevivedeletenow.this, incomingMessage, Toast.LENGTH_LONG).show();
//TODO Remove this
} catch (Exception e) {
Toast.makeText(bleutoothrevivedeletenow.this, "128", Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
Toast.makeText(bleutoothrevivedeletenow.this, "133", Toast.LENGTH_SHORT).show();
}
}
};
private boolean isBtConnected = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bleutoothrevivedeletenow);
messages = new StringBuilder();
SharedPreferences sharedPreferences;
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(bleutoothrevivedeletenow.this);
address = sharedPreferences.getString("ADDRESS", "");
StartConnection = findViewById(R.id.button5);
Disconnect = findViewById(R.id.button6);
incomingData = findViewById(R.id.textView);
Recieve = findViewById(R.id.button7);
StartConnection.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new ConnectBT().execute();
}
});
Disconnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (btSocket != null) //If the btSocket is busy
{
try {
btSocket.close(); //close connection
} catch (IOException e) {
e.printStackTrace();
}
}
finish();
}
});
Recieve.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ListenInput.start();
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
incomingData.setText(messages);
handler.postDelayed(this, 2000);
}
};
runnable.run();
}
});
}
private class ConnectBT extends AsyncTask<Void, Void, Void> // UI thread
{
private boolean ConnectSuccess = true; //if it's here, it's almost connected
#Override
protected void onPreExecute() {
Toast.makeText(getApplicationContext(), "Connecting....", Toast.LENGTH_LONG).show();
}
#Override
protected Void doInBackground(Void... devices) //while the progress dialog is shown, the connection is done in background
{
try {
if (btSocket == null || !isBtConnected) {
ActivityCompat.requestPermissions(bleutoothrevivedeletenow.this, new String[]{Manifest.permission.BLUETOOTH}, 1);
ActivityCompat.requestPermissions(bleutoothrevivedeletenow.this, new String[]{Manifest.permission.BLUETOOTH_ADMIN}, 1);
ActivityCompat.requestPermissions(bleutoothrevivedeletenow.this, new String[]{Manifest.permission.BLUETOOTH_PRIVILEGED}, 1);
myBluetooth = BluetoothAdapter.getDefaultAdapter();//get the mobile bluetooth device
BluetoothDevice dispositivo = myBluetooth.getRemoteDevice(address);
//connects to the device's address and checks if it's available
btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID);//create a RFCOMM (SPP) connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
btSocket.connect();//start connection
}
} catch (IOException e) {
ConnectSuccess = false;//if the try failed, you can check the exception here
}
return null;
}
#Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess) {
Toast.makeText(getApplicationContext(), "Connection Failed", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(getApplicationContext(), "Connection Successful", Toast.LENGTH_SHORT).show();
isBtConnected = true;
}
}
}
}
P.S. i have provided the entire code. this code is actually of this github repo:
https://github.com/IamMayankThakur/android-arduino-using-bluetooth
The code first genereated a IllegalThreadException but after debugging i edited the code and now it doesn't crash but still no incoming data
So I have been working with arduino for a while and now I've been trying to connect to the blue-tooth module with android studio. I was able to get the blue-tooth to connect but I'm having issues making the blue-tooth connection a service so that it can run even if the app is closed. Whenever I try to get the service to run on my phone, the app crashes as soon as i try to connect to blue-tooth module where as before when it was an activity, it worked perfectly. I've looked at a lot of links and guides on using services and blue-tooth but none of them do exactly what I want.
Below are some code snippets, but here is a link to the entire GitHub project
Blue-tooth activity that I got to work:
package edu.memphis.teamhack.smart_nightlight;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.UUID;
public class BluetoothActivity extends AppCompatActivity {
// GUI Components
private TextView mBluetoothStatus;
private TextView mReadBuffer;
private Button mScanBtn;
private Button mOffBtn;
private Button mListPairedDevicesBtn;
private Button mDiscoverBtn;
private BluetoothAdapter mBTAdapter;
private Set<BluetoothDevice> mPairedDevices;
private ArrayAdapter<String> mBTArrayAdapter;
private ListView mDevicesListView;
private CheckBox mLED1;
private final String TAG = MainActivity.class.getSimpleName();
private Handler mHandler; // Our main handler that will receive callback notifications
private ConnectedThread mConnectedThread; // bluetooth background worker thread to send and receive data
private BluetoothSocket mBTSocket = null; // bi-directional client-to-client data path
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // "random" unique identifier
// #defines for identifying shared types between calling functions
private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
private final static int MESSAGE_READ = 2; // used in bluetooth handler to identify message update
private final static int CONNECTING_STATUS = 3; // used in bluetooth handler to identify message status
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
mBluetoothStatus = (TextView)findViewById(R.id.bluetoothStatus);
mReadBuffer = (TextView) findViewById(R.id.readBuffer);
mScanBtn = (Button)findViewById(R.id.scan);
mOffBtn = (Button)findViewById(R.id.off);
mDiscoverBtn = (Button)findViewById(R.id.discover);
mListPairedDevicesBtn = (Button)findViewById(R.id.PairedBtn);
mLED1 = (CheckBox)findViewById(R.id.checkboxLED1);
mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
mDevicesListView = (ListView)findViewById(R.id.devicesListView);
mDevicesListView.setAdapter(mBTArrayAdapter); // assign model to view
mDevicesListView.setOnItemClickListener(mDeviceClickListener);
// Ask for location permission if not already allowed
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
mHandler = new Handler(){
public void handleMessage(android.os.Message msg){
if(msg.what == MESSAGE_READ){
String readMessage = null;
try {
readMessage = new String((byte[]) msg.obj, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
mReadBuffer.setText(readMessage);
}
if(msg.what == CONNECTING_STATUS){
if(msg.arg1 == 1)
mBluetoothStatus.setText("Connected to Device: " + (String)(msg.obj));
else
mBluetoothStatus.setText("Connection Failed");
}
}
};
if (mBTArrayAdapter == null) {
// Device does not support Bluetooth
mBluetoothStatus.setText("Status: Bluetooth not found");
Toast.makeText(getApplicationContext(),"Bluetooth device not found!",Toast.LENGTH_SHORT).show();
}
else {
mLED1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
SharedPreferences settings = getSharedPreferences("MyPref",
Context.MODE_PRIVATE);
Integer myInt = settings.getInt("colorHex", 0);
if(mConnectedThread != null){ //First check to make sure thread created
mConnectedThread.write(myInt.toString());}
}
});
mScanBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bluetoothOn(v);
}
});
mOffBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
bluetoothOff(v);
}
});
mListPairedDevicesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
listPairedDevices(v);
}
});
mDiscoverBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
discover(v);
}
});
}
}
private void bluetoothOn(View view){
if (!mBTAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
mBluetoothStatus.setText("Bluetooth enabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
}
}
// Enter here after user selects "yes" or "no" to enabling radio
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent Data){
// Check which request we're responding to
if (requestCode == REQUEST_ENABLE_BT) {
// Make sure the request was successful
if (resultCode == RESULT_OK) {
// The user picked a contact.
// The Intent's data Uri identifies which contact was selected.
mBluetoothStatus.setText("Enabled");
}
else
mBluetoothStatus.setText("Disabled");
}
}
private void bluetoothOff(View view){
mBTAdapter.disable(); // turn off
mBluetoothStatus.setText("Bluetooth disabled");
Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
}
private void discover(View view){
// Check if the device is already discovering
if(mBTAdapter.isDiscovering()){
mBTAdapter.cancelDiscovery();
Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
}
else{
if(mBTAdapter.isEnabled()) {
mBTArrayAdapter.clear(); // clear items
mBTAdapter.startDiscovery();
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
else{
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
}
}
final BroadcastReceiver blReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name to the list
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
}
};
private void listPairedDevices(View view){
mPairedDevices = mBTAdapter.getBondedDevices();
if(mBTAdapter.isEnabled()) {
// put it's one to the adapter
for (BluetoothDevice device : mPairedDevices)
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
Toast.makeText(getApplicationContext(), "Show Paired Devices", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
if(!mBTAdapter.isEnabled()) {
Toast.makeText(getBaseContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
return;
}
mBluetoothStatus.setText("Connecting...");
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
final String address = info.substring(info.length() - 17);
final String name = info.substring(0,info.length() - 17);
// Spawn a new thread to avoid blocking the GUI one
new Thread()
{
public void run() {
boolean fail = false;
BluetoothDevice device = mBTAdapter.getRemoteDevice(address);
try {
mBTSocket = createBluetoothSocket(device);
} catch (IOException e) {
fail = true;
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
}
// Establish the Bluetooth socket connection.
try {
mBTSocket.connect();
} catch (IOException e) {
try {
fail = true;
mBTSocket.close();
mHandler.obtainMessage(CONNECTING_STATUS, -1, -1)
.sendToTarget();
} catch (IOException e2) {
//insert code to deal with this
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_SHORT).show();
}
}
if(fail == false) {
mConnectedThread = new ConnectedThread(mBTSocket);
mConnectedThread.start();
mHandler.obtainMessage(CONNECTING_STATUS, 1, -1, name)
.sendToTarget();
}
}
}.start();
}
};
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", UUID.class);
return (BluetoothSocket) m.invoke(device, BTMODULEUUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection",e);
}
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.available();
if(bytes != 0) {
buffer = new byte[1024];
SystemClock.sleep(100); //pause and wait for rest of data. Adjust this depending on your sending speed.
bytes = mmInStream.available(); // how many bytes are ready to be read?
bytes = mmInStream.read(buffer, 0, bytes); // record how many bytes we actually read
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget(); // Send the obtained bytes to the UI activity
}
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(String input) {
byte[] bytes = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Here is the Bluetooth Service I'm working on:
package edu.memphis.teamhack.smart_nightlight;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast;
public class BluetoothCommService extends Service {
// #defines for identifying shared types between calling functions
private final static int REQUEST_ENABLE_BT = 1; // used to identify adding bluetooth names
private BluetoothAdapter mBTAdapter;
private ArrayAdapter<String> mBTArrayAdapter;
public BluetoothCommService() {
}
public void onCreate(Bundle savedInstanceState){
//super.onCreate(savedInstanceState);
mBTAdapter = BluetoothAdapter.getDefaultAdapter(); // get a handle on the bluetooth radio
mBTArrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
void bluetoothOn(View view){
if (!mBTAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
//GUI
//mBluetoothStatus.setText("Bluetooth enabled");
// Toast.makeText(getApplicationContext(),"Bluetooth turned on",Toast.LENGTH_SHORT).show();
}
else{
//Toast.makeText(getApplicationContext(),"Bluetooth is already on", Toast.LENGTH_SHORT).show();
}
}
private void bluetoothOff(View view){
mBTAdapter.disable(); // turn off
//GUI
//mBluetoothStatus.setText("Bluetooth disabled");
//Toast.makeText(getApplicationContext(),"Bluetooth turned Off", Toast.LENGTH_SHORT).show();
}
private void discover(View view){
// Check if the device is already discovering
if(mBTAdapter.isDiscovering()){
mBTAdapter.cancelDiscovery();
Toast.makeText(getApplicationContext(),"Discovery stopped",Toast.LENGTH_SHORT).show();
}
else{
if(mBTAdapter.isEnabled()) {
mBTArrayAdapter.clear(); // clear items
mBTAdapter.startDiscovery();
Toast.makeText(getApplicationContext(), "Discovery started", Toast.LENGTH_SHORT).show();
registerReceiver(blReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
}
else{
Toast.makeText(getApplicationContext(), "Bluetooth not on", Toast.LENGTH_SHORT).show();
}
}
}
final BroadcastReceiver blReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action)){
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// add the name to the list
mBTArrayAdapter.add(device.getName() + "\n" + device.getAddress());
mBTArrayAdapter.notifyDataSetChanged();
}
}
};
}
Feel free to ask any questions.
Try this instructables, i did it by reffering to this tutorial
http://www.instructables.com/id/Android-Bluetooth-Control-LED-Part-2/
for more idea, also refer to
https://www.intorobotics.com/how-to-develop-simple-bluetooth-android-application-to-control-a-robot-remote/
I'm working on a app that will connect to a OBD2 device through Bluetooth, but I haven't yet figured out how to connect to a Bluetooth device.
I followed a video tutorial, and am currently following this tutorial with hopefully better luck, but I don't really understand how to implement the code since I can't see the full code (I'm a beginner).
Any help is appreciated!
Image:
(Here's where I want to press on a device and connect to it.)
BluetoothActivity:
package com.example.asabanov.powersupplytool;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Set;
import java.util.UUID;
public class BluetoothActivity extends AppCompatActivity implements OnItemClickListener {
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
ArrayAdapter<String> listAdapter;
ListView listView;
BluetoothAdapter btAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
IntentFilter filter;
BroadcastReceiver receiver;
//String tag = "debugging";
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case SUCCESS_CONNECT:
//do something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
Toast.makeText(getApplicationContext(), "Connect", Toast.LENGTH_SHORT).show();
String s = "Successfully connected";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String string = new String(readBuf);
Toast.makeText(getApplicationContext(), "Connect", Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
init(); //initiate Bluetooth
if (btAdapter == null) {
Toast.makeText(getApplicationContext(), "No bluetooth detected on this device", Toast.LENGTH_SHORT).show();
finish();
} else {
if (!btAdapter.isEnabled()) {
turnOnBT();
}
pairedDevices=getPairedDevices();
startDiscovery();
}
}
private void startDiscovery() {
btAdapter.cancelDiscovery();
btAdapter.startDiscovery();
}
private void turnOnBT() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private ArrayList getPairedDevices() {
devicesArray = btAdapter.getBondedDevices();
if (devicesArray.size() > 0) {
//add devices in array to list array
for (BluetoothDevice device : devicesArray) {
pairedDevices.add(device.getName() + "\n" + device.getAddress());
}
}
return pairedDevices;
}
private void init() {
listView = (ListView) findViewById(R.id.listView);
listView.setOnItemClickListener(this);
listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
listView.setAdapter(listAdapter);
btAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(device);
String s = "";
for (int a = 0; a < pairedDevices.size(); a++) {
if (device.getName().equals(pairedDevices.get(a))) {
s = "Paired";
break;
}
}
// matt-hp (paired)
listAdapter.add(device.getName() + " " + s + " " + "\n" + device.getAddress());
} else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//run some code
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//run some code
} else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
if (btAdapter.getState() == btAdapter.STATE_OFF) {
turnOnBT();
}
}
}
};
registerReceiver(receiver, filter);
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(receiver, filter);
filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (btAdapter.isDiscovering()) {
btAdapter.cancelDiscovery();
}
if (listAdapter.getItem(position).contains("Paired")) {
BluetoothDevice selectedDevice = devices.get(position);
ConnectThread connect = new ConnectThread(selectedDevice);
connect.start();
Toast.makeText(getApplicationContext(), "Device is paired", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Device is not paired", Toast.LENGTH_SHORT).show();
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
btAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) {
}
return;
}
// Do work to manage the connection (in a separate thread)
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
/**
* Will cancel an in-progress connection, and close the socket
*/
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
}
}