I made an app which connects to bluetooth and sends and receive data in an activity. Now I have updates in the app and has to create another activities which connects to the same bluetooth device and transfer data. So I am planning to connect to bluetooth device in my second activity which has some buttons which calls for another activities. I need to retain the bluetooth connection I made in the second activity throughout the activities that are called from the second activity using buttons till the user press back button from second activity (exiting second activity). Please explain how I should change my code to make this happen. This is my current code which is used for single activity bluetooth connection.
public class ViewBoardStatus extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_board_status);
mOutStringBuffer = new StringBuffer("");
IntentFilter filter = new IntentFilter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
List<String> paireddevicesarray = new ArrayList<>();
int iNoOfPariedDev = pairedDevices.size();
int iDeviceCntr = 0;
DevAddressString = new String[iNoOfPariedDev][2];
for (BluetoothDevice device : pairedDevices)
{
DevAddressString[iDeviceCntr][0] = device.getAddress();
DevAddressString[iDeviceCntr][1] = device.getName();
iDeviceCntr++;
if (iDeviceCntr > iNoOfPariedDev)
break;
}
ArrayList<String> aList = new ArrayList<String>();
aList.add("Select Device");
for (int i = 0; i < iDeviceCntr; i++)
{
aList.add(DevAddressString[i][1]);
}
final ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, aList);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
sp_paireddevices.setAdapter(dataAdapter);
sp_paireddevices.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
public void onItemSelected(AdapterView<?> parentView,
View selectedItemView, int position, long id) {
// Object item = parentView.getItemAtPosition(position);
Log.e(TAG, "Executing On ITEM SELECTED");
int iLoc = sp_paireddevices.getSelectedItemPosition();
if (iLoc != 0)
{
Toast.makeText(getApplicationContext(), " Connecting to hardware please wait..", Toast.LENGTH_SHORT).show();
iBTDevSelcted = 1;
Log.e(TAG, "Toast message of Connecting");
address = DevAddressString[iLoc - 1][0];
Log.e(TAG, "Calling OnResume Function");
onResume();
}
else
{
Toast.makeText(getApplicationContext(), " Please select Bluetooth Device", Toast.LENGTH_SHORT).show();
}
}
public void onNothingSelected(AdapterView<?> arg0) {// do nothing
}
});
lvParaHeader.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(touchSource == null)
touchSource = v;
if(v == touchSource)
{
lvParaValue.dispatchTouchEvent(event);
if(event.getAction() == MotionEvent.ACTION_UP)
{
clickSource = v;
touchSource = null;
}
}
return false;
}
});
lvParaValue.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(touchSource == null)
touchSource = v;
if(v == touchSource)
{
lvParaHeader.dispatchTouchEvent(event);
if(event.getAction() == MotionEvent.ACTION_UP)
{
clickSource = v;
touchSource = null;
}
}
return false;
}
});
lvParaHeader.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(parent == clickSource) {
// Do something with the ListView was clicked
}
}
});
lvParaValue.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(parent == clickSource) {
// Do something with the ListView was clicked
}
}
});
lvParaHeader.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(view == clickSource)
lvParaValue.setSelectionFromTop(firstVisibleItem, view.getChildAt(0).getTop() + offset);
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
});
lvParaValue.setOnScrollListener(new OnScrollListener() {
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(view == clickSource)
lvParaHeader.setSelectionFromTop(firstVisibleItem, view.getChildAt(0).getTop() + offset);
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
});
sp_datatype.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
Log.e(l,"Starting ON Item Selected");
if (sp_paireddevices.getSelectedItemPosition()>0)
{
if (sp_datatype.getSelectedItemPosition() == 1) {
sGetRequest = sGetElectricalPara;
sendMessage(sGetRequest);
}
if (sp_datatype.getSelectedItemPosition() == 2) {
sGetRequest = sGetGprsPara;
sendMessage(sGetRequest);
}
if (sp_datatype.getSelectedItemPosition() == 3) {
sGetRequest = sGetSystemPara;
sendMessage(sGetRequest);
}
if (sp_datatype.getSelectedItemPosition() == 4) {
sGetRequest = sGetRS485Para;
sendMessage(sGetRequest);
}
}
else
Toast.makeText(getApplicationContext(), " Connect to a Device and Refresh ", Toast.LENGTH_SHORT).show();
}
#Override
public void onNothingSelected(AdapterView<?> parent)
{
}
});
bt_Refresh.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Log.e(l,"Refresh Button OnClick");
if (sp_paireddevices.getSelectedItemPosition()>0)
{
if (sp_datatype.getSelectedItemPosition() == 0) {
Toast.makeText(getApplicationContext(), " Select a Parameter to Refresh ", Toast.LENGTH_SHORT).show();
}
if (sp_datatype.getSelectedItemPosition() == 1) {
sGetRequest = sGetElectricalPara;
sendMessage(sGetRequest);
Log.e(l, "Send Message Called");
}
if (sp_datatype.getSelectedItemPosition() == 2) {
sGetRequest = sGetGprsPara;
sendMessage(sGetRequest);
}
if (sp_datatype.getSelectedItemPosition() == 3) {
sGetRequest = sGetSystemPara;
sendMessage(sGetRequest);
}
if (sp_datatype.getSelectedItemPosition() == 4) {
sGetRequest = sGetRS485Para;
sendMessage(sGetRequest);
}
Log.e(l, "Send Message Called");
}
else
Toast.makeText(getApplicationContext(), " Connect to a Device and Refresh ", Toast.LENGTH_SHORT).show();
}
});
h = new Handler()
{
public void handleMessage(android.os.Message msg)
{
Log.e(l, "Starting Handler");
int strlen;
switch (msg.what)
{
case RECIEVE_MESSAGE:
Log.d(l, "data received = " );
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1);
String strMsg = new String();
sb.append(strIncom);
int endOfLineIndex = sb.indexOf("#");
if (endOfLineIndex > 0)
{ // if end-of-line,
sJsonData = sb.substring(1, endOfLineIndex); // extract string
sb.delete(0, sb.length());
// and clear
try
{
Log.e(l, "Starting Try of Handler");
Log.e(l, "Data Received: "+sJsonData);
strlen = sJsonData.length();
Log.e(l, "String Length Obtained");
JSONObject mainobject = new JSONObject(sJsonData);
Log.e(l, "main object created");
sDataType = mainobject.getString("DATA_TYPE");
Log.e(l, "Data Type Obtained");
//tv_jsonlength.setText(String.valueOf(strlen));
//tv_JsonPara.setText(TempHeader);
iSelectedParaPostion=sp_datatype.getSelectedItemPosition();
if(sDataType.trim().equalsIgnoreCase("PARA"))
{
if(iSelectedParaPostion==1)
{
sCurrentJsonData = sJsonData;
Log.e(l, "sCurrentJsonData set to sJsonData");
//tv_jsonstring.setText(sCurrentJsonData);
jsonparseelectricalpara();
}
}
if(sDataType.trim().equalsIgnoreCase("GPRS"))
{
if(iSelectedParaPostion==2)
{
sCurrentJsonData = sJsonData;
Log.e(l, "sCurrentJsonData set to sJsonData");
//tv_jsonstring.setText(sCurrentJsonData);
jsonparsegprsdata();
}
}
if(sDataType.trim().equalsIgnoreCase("SYSTEM"))
{
if(iSelectedParaPostion==3)
{
sCurrentJsonData = sJsonData;
Log.e(l, "sCurrentJsonData set to sJsonData");
//
// tv_jsonstring.setText(sCurrentJsonData);
jsonparseSystem();
}
}
}
catch (Exception e)
{
Log.e(l, "CATCH OF HANDLER");
}
}
break;
}
}
};
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
}//oncreate
private void checkBTState()
{
// Check for Bluetooth support and then check to make sure it is turned on
// Emulator doesn't support Bluetooth and will return null
if(mBluetoothAdapter==null) {
// Log.d(TAG, "error, bluetooth not supported");
} else {
if (mBluetoothAdapter.isEnabled()) {
// Log.d(TAG, "...Bluetooth ON...");
} else {
//Prompt user to turn on Bluetooth
tvconnectionstatus.setText("");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
private void errorExit(String title, String message)
{
Toast.makeText(getBaseContext(), title + " - " + message, Toast.LENGTH_LONG).show();
finish();
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException
{
if (Build.VERSION.SDK_INT >= 10)
{
try
{
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[]{UUID.class});
Log.e(TAG, "Bluetooth Socket Creation TRY EXECUTED");
return (BluetoothSocket) m.invoke(device, MY_UUID);
}
catch (Exception e2)
{
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
Log.e(TAG, "Bluetooth Socket Creation CATCH EXECUTED");
}
}
Log.e(TAG, "Exiting Socket Creation Method");
return device.createRfcommSocketToServiceRecord(MY_UUID);
}
public void onResume()
{
super.onResume();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Log.e(TAG, "Starting OnResume Method");
if (iBTDevSelcted == 0) {
Toast.makeText(getApplicationContext(), " Please select Bluetooth Device", Toast.LENGTH_SHORT).show();
return;
}
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.e(TAG, "Obtaining REMOTE DEVICE address");
try {
btSocket = createBluetoothSocket(device);
Log.e(TAG, "BT SOCKET Created");
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
mBluetoothAdapter.cancelDiscovery();
Log.e(TAG, "BT Discovery CANCELLED");
try
{
Log.e(TAG, "TRY STATEMENT OF BT CONNECTION CREATION");
btSocket.connect();
String connectedto = "Connected to: " + sp_paireddevices.getSelectedItem().toString();
tvconnectionstatus.setText(connectedto);
}
catch (IOException e)
{
Log.e(TAG, "CATCH STATEMENT OF BLUETOOTH CONNECTION CREATION");
try {
btSocket.close();
Log.e(TAG, "Bluetooth Socket Closed");
tvconnectionstatus.setText("");
} catch (IOException e2) {
errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
Log.e(TAG, "Unable to Close bluetooth connection");
}
}
// Create a data stream so we can talk to server.
// Log.d(TAG, "...Create Socket...");
mConnectedThread = new ConnectedThread(btSocket);
Log.e(TAG, "Connection Thread Created");
mConnectedThread.start();
Log.e(TAG, "Connection Thread Started");
}
#Override
public void onPause()
{
super.onPause();
// Log.d(TAG, "...In onPause()...");
if(iBTDevSelcted==1) {
try {
btSocket.close();
tvconnectionstatus.setText("");
} catch (IOException e2) {
errorExit("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
}
}
}
private class ConnectedThread extends Thread
{
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket)
{
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try
{
Log.e(TAG, "Trying to get Temp Input/Output Stream");
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
Log.e(TAG, "Input/Output Stream Obtained");
}
catch (IOException e)
{
Log.e(TAG, "I/O Stream CATCH STATEMENT");
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run()
{
Log.e(TAG, "Starting RUN Method");
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 {
Log.e(TAG, "TRY of RUN Method Started");
// Read from the InputStream
bytes = mmInStream.read(buffer); // Get number of bytes and message in "buffer"
h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget(); // Send to message queue Handler
Log.e(l,"Run Executed");
Log.e(TAG, "TRY of RUN Method Completed");
} catch (IOException e)
{
Log.e(TAG, "CATCH of RUN Method");
break;
}
}
}
public void write(String s) throws IOException
{
mmOutStream.write(s.getBytes());
tvconnectionstatus.setText(s);
sGetRequest=sReset;
}
}//connectthread
private void sendMessage(String message)
{
ConnectedThread ct;
Log.e(l,"Connected Thread Object Created");
ct = mConnectedThread;
try {
ct.write(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}//class
Related
I'm trying to connect my device to another one via Bluetooth, but when I select the device I want to connect with, I get an IOException saying
read failed, socket might closed or timeout, read ret: -1
Just to illustrate how my app works, I have a RecyclerView populated with the devices my Bluetooth scan has found, then when I click an item the app is supposed to connect with that device.
Below is my the code for my connection thread:
private val MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb")
private lateinit var device: BluetoothDevice
private lateinit var onDeviceActionListener: OnDeviceActionListener
private lateinit var socket: BluetoothSocket
fun init(device: BluetoothDevice,
onDeviceActionListener: OnDeviceActionListener): ConnectionThread {
this.device = device
this.onDeviceActionListener = onDeviceActionListener
try {
socket = device.createRfcommSocketToServiceRecord(MY_UUID)
} catch (e: IOException) {
Log.e(TAG, "Error creating socket", e)
}
return this
}
override fun run() {
try {
socket.connect()
} catch (openException: IOException) {
Log.e(TAG, "Error opening connection. Trying to close...", openException)
try {
socket.close()
} catch (closeException: IOException) {
Log.e(TAG, "Error closing socket", closeException)
}
return
}
onDeviceActionListener.onDeviceConnect(device)
}
My guess is there is something wrong with my UUID. I've tried some other values but still didn't work.
Any help will be much appreciated.
Well, I don't see exactly what you are doing wrong here. However, I have done quite a bit of Bluetooth work. More recently just focused in BLE. You should be able to discover your nearby BT devices and see their UUIDs.
I have written a helper class about 3 years ago so it's a little old, but should be mostly the same code. Happy to share it with you if it helps.
public class BluetoothConnector {
private static final String TAG = Globals.SEARCH_STRING + BluetoothConnector.class.getSimpleName();
private static final String DEFAULT_SERVER_NAME_FOR_APP = "tn_bt_default_server";
private static final int DEFAULT_DISCOVERABLE_DURATION_MS = 30000;
private static final UUID DEFAULT_UUID = UUID.fromString("6534c201-039c-4e4f-89f9-5ca8cfeb9667");
public static final int ENABLE_DISCOVER_INTENT = 1002;
protected boolean mIsToastEnabled = false; //Access from calling class to enable toasting of progress to screen if necessary
private Handler mUIHandler;
private static ServerSocketThread mServerSocketThread;
private static ClientSocketThread mClientSocketThread;
private ManageConnectionThread mManageConnectionThread;
private Context mContext;
private IBluetoothDataListener mBluetoothDataListener;
public final Object ServerSocketLock = new Object();
public final Object ClientSocketLock = new Object();
public final Object ManageConnectionLock = new Object();
public BluetoothConnector(Context context, IBluetoothDataListener listener){
this(context, new Handler(Looper.getMainLooper()), listener);
}
public BluetoothConnector(Context context, Handler UIHandler, IBluetoothDataListener listener){
Log.v(TAG, "BluetoothConnector(context=" + context + ", Handler=" + UIHandler.getClass().getSimpleName() + ", IBluetoothDataListener=" + listener.getClass().getSimpleName());
mContext = context;
mUIHandler = UIHandler;
mBluetoothDataListener = listener;
}
public void makeThisDeviceDiscoverable(Activity callingActivity){
makeThisDeviceDiscoverable(callingActivity, BluetoothAdapter.getDefaultAdapter(), DEFAULT_DISCOVERABLE_DURATION_MS);
}
public void makeThisDeviceDiscoverable(Activity callingActivity, BluetoothAdapter adapter){
makeThisDeviceDiscoverable(callingActivity, adapter, DEFAULT_DISCOVERABLE_DURATION_MS);
}
public void makeThisDeviceDiscoverable(Activity callingActivity, int durationInMs){
makeThisDeviceDiscoverable(callingActivity, BluetoothAdapter.getDefaultAdapter(), durationInMs);
}
public void makeThisDeviceDiscoverable(Activity callingActivity, BluetoothAdapter adapter, int durationInMs) {
Log.v(TAG, "makeThisDeviceDiscoverable(callingActivity=" + callingActivity.getClass().getSimpleName() + ", BluetoothAdapter=" + (adapter == null ? "null" : adapter.getName()) + ", duration=" + String.valueOf(durationInMs));
if(adapter == null){
Log.v(TAG, "adapter is null");
}else if(adapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Log.v(TAG, "Launching Activity to request Discoverable Permission");
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, durationInMs);
callingActivity.startActivityForResult(discoverableIntent, ENABLE_DISCOVER_INTENT);
}else{
Log.v(TAG, "adapter is already in SCAN MODE");
}
}
public void awaitConnectionFromDevice(){
awaitConnectionFromDevice(DEFAULT_UUID, BluetoothAdapter.getDefaultAdapter());
}
public void awaitConnectionFromDevice(UUID commonKey){
awaitConnectionFromDevice(commonKey, BluetoothAdapter.getDefaultAdapter());
}
public void awaitConnectionFromDevice(BluetoothAdapter adapter){
awaitConnectionFromDevice(DEFAULT_UUID, adapter);
}
public void awaitConnectionFromDevice(UUID commonKey, BluetoothAdapter adapter){
Log.v(TAG, "awaitConnectionFromDevice for UUID: " + String.valueOf(commonKey) + ", BluetoothAdapter=" + (adapter == null ? "null" : adapter.getName()));
cancelDiscovery();
synchronized (ServerSocketLock){
if(mServerSocketThread != null){
Log.v(TAG, "Server Socket Thread was not null so canceling current Thread");
mServerSocketThread.cancel();
}
Log.v(TAG, "Attempting to Start new ServerThread");
mServerSocketThread = new ServerSocketThread(commonKey, adapter);
mServerSocketThread.start();
}
}
public void cancelAwaitingConnectionFromDevice(){
Log.v(TAG, "cancelAwaitingConnectionFromDevice");
synchronized (ServerSocketLock){
if(mServerSocketThread != null){
mServerSocketThread.cancel();
mServerSocketThread = null;
Log.v(TAG, "canceling Server Socket Thread");
}else{
Log.v(TAG, "Server Socket null, so not canceling");
}
}
}
public void startDiscovery() {
startDiscovery(BluetoothAdapter.getDefaultAdapter());
}
public void startDiscovery(BluetoothAdapter adapter){
Log.v(TAG, "startDiscovery to find list of devices in range");
adapter.startDiscovery();
}
public void cancelDiscovery() {
cancelDiscovery(BluetoothAdapter.getDefaultAdapter());
}
public void cancelDiscovery(BluetoothAdapter adapter){
Log.v(TAG, "cancelDiscovery");
adapter.cancelDiscovery();
}
public void connectToDevice(BluetoothDevice device){
connectToDevice(device, DEFAULT_UUID);
}
public void connectToDevice(BluetoothDevice device, UUID commonKey){
Log.v(TAG, "connectToDevice(BluetoothDevice=" + (device == null ? "null" : device.getName()) + ", UUID=" + String.valueOf(commonKey));
synchronized (ClientSocketLock){
if(mClientSocketThread != null){
Log.v(TAG, "Client Socket Thread was not null so canceling current Thread");
mClientSocketThread.cancel();
}else{
Log.v(TAG, "Client Socket Thread is NULL so not canceling");
}
Log.v(TAG, "ClientSocketThread Starting");
mClientSocketThread = new ClientSocketThread(device, commonKey);
mClientSocketThread.start();
}
}
public BluetoothDevice getBluetoothDeviceByMac(String mac){
Log.v(TAG, "getBluetoothDeviceByMac(mac=" + mac);
return getBluetoothDeviceByMac(mac, BluetoothAdapter.getDefaultAdapter());
}
public BluetoothDevice getBluetoothDeviceByMac(String mac, BluetoothAdapter adapter) {
Log.v(TAG, "getBluetoothDeviceByMac(mac=" + mac + ", BluetoothAdapter=" + (adapter == null ? "null" : adapter.getName()));
return adapter.getRemoteDevice(mac);
}
public ArrayList<KeyValueModel> getPairedDevices(){
return getPairedDevices(BluetoothAdapter.getDefaultAdapter());
}
public ArrayList<KeyValueModel> getPairedDevices(BluetoothAdapter adapter){
ArrayList<KeyValueModel> bondedDevices = new ArrayList<KeyValueModel>();
Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
Log.v(TAG, "getPairedDevices Found " + pairedDevices.size() + " number of paired devices");
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
bondedDevices.add(new KeyValueModel(device.getAddress(), device.getName()));
}
}
return bondedDevices;
}
public static void unpairDevice(BluetoothDevice device){
Log.v(TAG, "unpairDevice");
try{
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
}catch (Exception ex){
Log.e(TAG, "Error Unpairing Device: " + ex.getMessage());
}
}
public boolean sendDataToConnectedDevice(byte[] data){
Log.v(TAG, "sendDataToConnectedDevice");
synchronized (ManageConnectionLock){
mManageConnectionThread.write(data);
return true;
}
}
public void setBluetoothDataListener(IBluetoothDataListener listener){
mBluetoothDataListener = listener;
}
public boolean getIsConnected(){
synchronized (ManageConnectionLock) {
return mManageConnectionThread != null && mManageConnectionThread.isAlive();
}
}
private void startManageConnectionThread(BluetoothSocket socket){
Log.v(TAG, "startManageConnectionThread for Socket: " + (socket == null ? "null" : socket.getClass().getSimpleName()));
synchronized (ManageConnectionLock) {
mManageConnectionThread = new ManageConnectionThread(socket);
mManageConnectionThread.start();
}
}
private void handleDataReceivedFromConnectedDevice(final byte[] bytes){
Log.v(TAG, "handleDataReceivedFromConnectedDevice");
Log.v(TAG, "bytes to Listener: " + new String(bytes));
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if (mBluetoothDataListener != null) {
mBluetoothDataListener.onReceivedPayloadFromConnectedDevice(bytes);
}
}
});
}else{
Log.v(TAG, "UIHandler was null so skipped sending payload to listener");
}
}
private void handleConnected(){
Log.e(TAG, "handleConnected");
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onConnectedToTargetDevice();
}
}
});
}else{
Log.v(TAG, "UIHandler was null so skipped sending payload to listener");
}
}
private void handleDisconnected(){
Log.e(TAG, "handleDisconnected");
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onDisconnectedFromTargetDevice();
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleFailedToConnectAsServer(final Exception ex){
Log.e(TAG, "handleFailedToConnectAsServer ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onFailedToReceiveConnectionFromTargetDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleFailedToConnectAsClient(final Exception ex){
Log.e(TAG, "handleFailedToConnectAsClient ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onFailedToConnectToTargetDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleErrorInRetrievingData(final Exception ex){
Log.e(TAG, "handleErrorInRetrievingData ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onErrorReceivingPayloadFromConnectedDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void handleFailedToSendDataToConnectedDevice(final Exception ex){
Log.e(TAG, "handleFailedToSendDataToConnectedDevice ex: " + ex.getMessage());
if(mUIHandler != null && mBluetoothDataListener != null){
mUIHandler.post(new Runnable() {
#Override
public void run() {
if(mBluetoothDataListener != null){
mBluetoothDataListener.onFailedToSendDataToConnectedDevice(ex);
}
}
});
}else{
Log.v(TAG, "UIHandler or Listener was null so skipped sending payload to listener");
}
}
private void toastMessage(final String value){
if(!mIsToastEnabled || mUIHandler == null) {
return;
}
mUIHandler.post(new Runnable() {
#Override
public void run() {
try{
Toast.makeText(mContext, value, Toast.LENGTH_SHORT).show();
}catch(Exception ex){
Log.v(TAG, "Error Toasting, possibly bad handler, or context: " + ex.getMessage());
}
}
});
}
private class ServerSocketThread extends Thread{
private final String TAG = Globals.SEARCH_STRING + ServerSocketThread.class.getSimpleName();
private final BluetoothServerSocket mServerSocket;
public ServerSocketThread(UUID commonKey, BluetoothAdapter adapter) {
Log.v(TAG, "ServerSocketThread Constructor");
BluetoothServerSocket tmp = null;
try {
Log.v(TAG, "listening for RFComas Server: " + DEFAULT_SERVER_NAME_FOR_APP + ", and commonKey: " + String.valueOf(commonKey));
// MY_UUID is the app's UUID string, also used by the client code
tmp = adapter.listenUsingRfcommWithServiceRecord(DEFAULT_SERVER_NAME_FOR_APP, commonKey);
toastMessage("Listening for RFComm As Server on UUID: " + String.valueOf(commonKey));
} catch (IOException e) {
Log.e(TAG, "Error creating ServerSocket: " + e.getMessage());
toastMessage("Error Creating ServerSocket: " + e.getMessage());
}
mServerSocket = tmp;
}
public void run() {
Log.v(TAG, "ServerSocket run");
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (mServerSocket != null) {
try {
Log.v(TAG, "ServerSocket.accept()");
toastMessage("ServerSocket.accept()");
//Waits for Client Connection to pass Socket, then we close down
socket = mServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "ServerSocket.accept() Error: " + e.getMessage());
toastMessage("ServerSocket.accept() Error: " + e.getMessage());
handleFailedToConnectAsServer(e);
break;
}
// If a connection was accepted we don't need to keep server listening, so close unless multiple client/server connections is desired
if (socket != null) {
try{
Log.v(TAG, "ServerSocket Accepted Client Socket, Begin Listening Connect Thread");
toastMessage("ServerSocket Accepted Client Socket, Begin Listening Connect Thread");
// Do work to manage the connection (in a separate thread)
startManageConnectionThread(socket);
//mServerSocket.close();
}catch(Exception ex){
Log.e(TAG, "Exception closing Server Socket");
}
//break; //Add in Break if you want to shut down listening for connections
}else{
Log.v(TAG, "Socket wasn't accepted");
toastMessage("Socket wasn't accepted");
handleFailedToConnectAsServer(new Exception("Socket is Null"));
}
}
Log.v(TAG, "Exiting Server Accept Thread");
}
public void cancel() {
try {
Log.v(TAG, "ServerSocketThread Canceled");
mServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "ServerSocketThread Error: " + e.getMessage());
}
}
}
private class ClientSocketThread extends Thread{
private BluetoothSocket mSocket;
private final BluetoothDevice mDevice;
public ClientSocketThread(BluetoothDevice device, UUID commonKey) {
Log.v(TAG, "ClientSocketThread Constructor");
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
Log.v(TAG, "Client creating RFComm Socket to Server with UUID: " + String.valueOf(commonKey));
toastMessage("Client creating RFComm Socket to Server with UUID: " + String.valueOf(commonKey));
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(commonKey);
} catch (IOException e) {
Log.e(TAG, "Error creating Client Socket: " + e.getMessage());
toastMessage("Creating Socket Exception: " + e.getMessage());
handleFailedToConnectAsClient(e);
}
mSocket = tmp;
}
public void run() {
try {
if(mSocket == null){
Log.e(TAG, "Error Client Socket is Null, Canceling Client Thread");
return;
}
Log.v(TAG, "Client Connecting");
// Connect to the server, or timeout eventually
toastMessage("Client Connecting");
mSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and try the fallback method of reflection with port to connect
try {
Log.e("", "trying fallback...");
toastMessage("Client Connection Failed Exception: " + connectException.getMessage());
mSocket = (BluetoothSocket) mDevice.getClass().getMethod("createRfcommSocket", new Class[]{int.class}).invoke(mDevice, 1);
toastMessage("Client Connect Again Attempt 2, but with fall back Reflection and port");
Log.v(TAG, "Client Connect Again Attempt 2, but with fall back Reflection and port");
mSocket.connect();
Log.e("", "Connected");
toastMessage("Client Connected");
} catch (Exception ex) {
Log.e("", "Couldn't establish Bluetooth connection!");
toastMessage("Client Couldn't Establish Connection to Server: " + ex.getMessage());
handleFailedToConnectAsClient(ex);
return;
}
}
// Do work to manage the connection (in a separate thread)
startManageConnectionThread(mSocket);
}
public void cancel() {
try {
Log.v(TAG, "Client Socket cancel");
mSocket.close();
} catch (IOException e) {
Log.e(TAG, "Error Closing Socket");
}
}
}
private class ManageConnectionThread extends Thread {
/////////////
// MEMBERS //
/////////////
private final String TAG = Globals.SEARCH_STRING + ManageConnectionThread.class.getSimpleName();
private final BluetoothSocket mSocket;
private final InputStream mInStream;
private final OutputStream mOutStream;
//////////////////
// CONSTRUCTOR //
//////////////////
public ManageConnectionThread(BluetoothSocket socket) {
mSocket = socket;
handleConnected();
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
try {
Log.v(TAG, "ManageConnectionThread Constructor");
Log.v(TAG, "Connected to Socket = " + String.valueOf(socket.isConnected()));
toastMessage("Listening for input or output Stream");
Log.v(TAG, "Get InputStream");
tmpIn = socket.getInputStream();
Log.v(TAG, "Get OutputStream");
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error getting Socket Streams: " + e.getMessage());
toastMessage("Connect Thread: Error: " + e.getMessage());
handleErrorInRetrievingData(e);
}
mInStream = tmpIn;
mOutStream = tmpOut;
}
///////////////
// OVERRIDES //
///////////////
public void run() {
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
byte[] data = new byte[16384];
int nRead;
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((nRead = mInStream.read(data, 0, data.length)) != -1) {
//Log.v(TAG, "bytes Read: " + String.valueOf(nRead));
buffer.write(data, 0, nRead);
//TODO Find better way to find End Of Message rather than looking for }
String temp = new String(buffer.toByteArray());
//Log.v(TAG, "current Data: " + temp);
if(temp.contains("}")){
Log.v(TAG, "bytes reading complete");
handleDataReceivedFromConnectedDevice(buffer.toByteArray());
buffer.flush();
buffer = new ByteArrayOutputStream();
}else{
Log.v(TAG, "More bytes Available");
}
}
} catch (IOException e) {
Log.e(TAG, "Error reading inputStream");
handleErrorInRetrievingData(e);
break;
}
}
Log.v(TAG, "Exiting Managed Connection Thread");
handleDisconnected();
}
/////////////
// METHODS //
/////////////
public void write(byte[] bytes) {
try {
Log.v(TAG, "ManageConnectionThread write(bytes)");
mOutStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "Error Writing Stream: " + e.getMessage());
handleFailedToSendDataToConnectedDevice(e);
}
}
public void cancel() {
try {
Log.v(TAG, "ManageConnectionThread cancel");
handleDisconnected();
mSocket.close();
} catch (IOException e) {
Log.e(TAG, "Error Closing BluetoothSocket: " + e.getMessage());
}
}
}
public interface IBluetoothDataListener{
//////////////////////
// OVERRIDE METHODS //
//////////////////////
void onReceivedPayloadFromConnectedDevice(byte[] payload);
void onErrorReceivingPayloadFromConnectedDevice(Exception ex);
void onFailedToConnectToTargetDevice(Exception ex);
void onFailedToReceiveConnectionFromTargetDevice(Exception ex);
void onFailedToSendDataToConnectedDevice(Exception ex);
void onConnectedToTargetDevice();
void onDisconnectedFromTargetDevice();
}
}
Then of course you will want to make sure you have your broadcast receivers setup:
<receiver
android:name=".receivers.BluetoothChangedReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.SCAN_MODE_CHANGED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_STARTED" />
<action android:name="android.bluetooth.adapter.action.DISCOVERY_FINISHED" />
<action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" />
<action android:name="android.bluetooth.device.action.FOUND" />
<action android:name="android.bluetooth.device.action.DISAPPEARED" />
</intent-filter>
</receiver>
<receiver
android:name=".receivers.BluetoothDeviceReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.bluetooth.device.action.FOUND" />
<action android:name="android.bluetooth.device.action.DISAPPEARED" />
<action android:name="android.bluetooth.device.action.ACL_CONNECTED" />
<action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" />
<action android:name="android.bluetooth.device.action.ACTION_ACL_DISCONNECT_REQUESTED" />
<action android:name="android.bluetooth.device.action.BOND_STATE_CHANGED" />
<action android:name="android.bluetooth.device.action.UUID" />
</intent-filter>
</receiver>
I have the following code in android studio, we have a arduino with a bluetooth module HC-05 and we are trying to send a data from a sensor via the bluetooth to the android app:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_temperature);
btnOn = (Button) findViewById(R.id.measure);
sensorView0 = (TextView) findViewById(R.id.temp);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
CheckBlueToothState();
btnOn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try {
sendData();
} catch (IOException ex) {
}
Toast.makeText(getBaseContext(), "Start Measuring", Toast.LENGTH_SHORT).show();
}
});
}
void openBT() throws IOException {
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb"); //Standard //SerialPortService ID
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
mmSocket.connect();
mmOutputStream = mmSocket.getOutputStream();
mmInputStream = mmSocket.getInputStream();
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { //if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
recDataString.append(readMessage); //keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("%"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string
int dataLength = dataInPrint.length(); //get length of data received
if (recDataString.charAt(0) == '*') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, endOfLineIndex); //get sensor value from string between indices 1-5
sensorView0.setText( sensor0 ); //update the textviews with sensor values
}
recDataString.delete(0, recDataString.length()); //clear all string data
dataInPrint = " ";
}
}
}
};
beginListenForData1();
Handler myHandler = new Handler();
myHandler.postDelayed(mMyRunnable, 1000);//Message will be delivered in 1 second.
// myLabel.setText("Bluetooth Opened");
}
void beginListenForData1() {
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInputStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
});
workerThread.start();
}
private Runnable mMyRunnable = new Runnable()
{
#Override
public void run()
{
//Change state here
}
};
private void CheckBlueToothState() {
if (mBluetoothAdapter == null) {
} else {
if (mBluetoothAdapter.isEnabled()) {
if (mBluetoothAdapter.isDiscovering()) {
} else {
}
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if(pairedDevices.size() > 0) {
for(BluetoothDevice device : pairedDevices) {
if(device.getName().equals("HC-05")) {
mmDevice = device;
break;
}
}
try {
openBT();
}
catch (IOException ex) {
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();};
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == REQUEST_ENABLE_BT) {
{CheckBlueToothState();
}
}
}
void sendData() throws IOException
{
String msg = "1";
msg += "\n";
mmOutputStream.write(msg.getBytes());
//myLabel.setText("Data Sent");
}
void sendData0() throws IOException
{
String msg = "0";
msg += "\n";
mmOutputStream.write(msg.getBytes());
//myLabel.setText("Data Sent");
}
#Override
public void onBackPressed() {
super.onBackPressed();
try {
sendData0();
} catch (IOException e) {
e.printStackTrace();
}
try {
closeBT();
} catch (IOException e) {
e.printStackTrace();
}
//System.exit(0);
this.finish();
}
void closeBT() throws IOException
{
stopWorker = true;
mmOutputStream.close();
mmInputStream.close();
mmSocket.close();
}
}
The code works for the second time only, so when i press the button in the app for the first time it does not show the data, but when i press it at the second time it shows the data, why is that happening?
I wanted to start with the basics of bluetooth connection and make a simple app capable of scanning, pairing and connecting.
I'm struggling with the last concept, i followed a lot of tutorials but I couldn't make it. I don't know if you can help me but here is my code.
ublic class MainActivity extends Activity {
private final String TAG = "Debugging";
private final static int REQUEST_CODE_ENABLE_BLUETOOTH = 0;
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothAdapter btAdapter;
ArrayList<String> arrayListpaired;
ArrayAdapter<String> listAdapter,adapter;
ListView listView,listViewPaired;
Set<BluetoothDevice> deviceArray;
ArrayList<String> pairedDevices;
IntentFilter filter;
BroadcastReceiver receiver;
BluetoothDevice bdDevice;
ArrayList<BluetoothDevice> arrayListBluetoothDevices = null;
ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices;
ListItemClicked listItemClicked;
ListItemClickedonPaired listItemClickedonPaired;
String tag = "debugging";
Handler mHandler= new Handler() {
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(),"Connect",Toast.LENGTH_LONG).show();
String s= "Succesfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readbuff=(byte[])msg.obj;
String string= readbuff.toString();
Toast.makeText(getApplicationContext(), string,Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btAdapter = BluetoothAdapter.getDefaultAdapter();
arrayListBluetoothDevices = new ArrayList<BluetoothDevice>();
arrayListpaired = new ArrayList<String>();
arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice>();
adapter= new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, arrayListpaired);
listItemClickedonPaired = new ListItemClickedonPaired();
listViewPaired = (ListView) findViewById(R.id.listView3);
listItemClicked = new ListItemClicked();
listView = (ListView) findViewById(R.id.listView2);
listAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_activated_1);
listView.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
listViewPaired.setAdapter(adapter);
setupMessageButton1();
setupMessageButton2();
setupMessageButton3();
setupMessageButton4();
setupMessageButton5();
init();
getPairedDevices();
}
private void init() {
listView.setOnItemClickListener(listItemClicked);
listViewPaired.setOnItemClickListener(listItemClickedonPaired);
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String Action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(Action)) {
Toast.makeText(getApplicationContext(), "One Device Found", Toast.LENGTH_SHORT).show();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (arrayListBluetoothDevices.size() < 1) // this checks if the size of bluetooth device is 0,then add the
{ // device to the arraylist.
listAdapter.add(device.getName() + "\n" + device.getAddress());
arrayListBluetoothDevices.add(device);
listAdapter.notifyDataSetChanged();
}
else
{
boolean flag = true; // flag to indicate that particular device is already in the arlist or not
for (int i = 0; i < arrayListBluetoothDevices.size(); i++) {
if (device.getAddress().equals(arrayListBluetoothDevices.get(i).getAddress())) {
flag = false;
}
}
if (flag == true) {
listAdapter.add(device.getName() + "\n" + device.getAddress());
arrayListBluetoothDevices.add(device);
listAdapter.notifyDataSetChanged();
}
}
}
}
};
registerReceiver(receiver, filter);
}
private void createBond(BluetoothDevice btDevice){
try
{
Method method = btDevice.getClass().getMethod("createBond", (Class[]) null);
method.invoke(btDevice, (Object[]) null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void unpairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void getPairedDevices() {
Set<BluetoothDevice> pairedDevice = btAdapter.getBondedDevices();
if(pairedDevice.size()>0)
{
for(BluetoothDevice device : pairedDevice)
{
arrayListpaired.add(device.getName()+"\n"+device.getAddress());
arrayListPairedBluetoothDevices.add(device);
}
}
adapter.notifyDataSetChanged();
}
public class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
getPairedDevices();
createBond(bdDevice);
adapter.notifyDataSetChanged();
Log.i("Log", "The bond is created: with" + bdDevice.toString());
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
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) { }
}
}
#Override
protected void onDestroy() {
super.onDestroy();
btAdapter.cancelDiscovery();
unregisterReceiver(receiver);
}
class ListItemClickedonPaired implements OnItemClickListener
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
bdDevice = arrayListPairedBluetoothDevices.get(position);
unpairDevice(bdDevice);
//arrayListPairedBluetoothDevices.clear();
}
}
private void makeDiscoverable() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 150);
startActivity(discoverableIntent);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(MainActivity.this, "Bluetooth must be enabled to start scanning", Toast.LENGTH_SHORT).show();
} else
{
Toast.makeText(MainActivity.this, "Click on TURN_OFF to disable bluetooth", Toast.LENGTH_LONG).show();
}
}
private void setupMessageButton1() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button1);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listAdapter.clear();
arrayListBluetoothDevices.clear();
btAdapter.startDiscovery();
}
});
}
private void setupMessageButton2() {
//1.get a reference to the button.
Button messageButton = (Button) findViewById(R.id.button2);
//2. set the click listener to run my code.
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (btAdapter.isEnabled()) {
listAdapter.clear();
btAdapter.disable();
} else
{
Toast.makeText(MainActivity.this, "Dont worry it's already off", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setupMessageButton3() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button3);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void setupMessageButton4() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button4);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btAdapter.enable();
}
});
}
private void setupMessageButton5() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button5);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
makeDiscoverable();
}
});
}
}
Concerning the log i have that message :
"D/BluetoothUtils﹕ isSocketAllowedBySecurityPolicy start : device null"
"W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback"
"D/BluetoothSocket﹕ connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[75]} "
public class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
createBond(bdDevice);
adapter.notifyDataSetChanged();
ConnectThread connect = new ConnectThread(bdDevice);
connect.start();
}
}
For the connection, i use the ConnectThread found in Bluetooth APi developer Website:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
it's ok i found the solution, i had the problem with the phone i'm using, he is not supporting SPP.
Thank you anyway
I have an Arduino Bluetooth shield HC-05. I paired the Bluetooth shield first with Android device and tried to send data to Arduino via Bluetooth shield. Android app sends data to the shield. But Arduino not receiving the command more than (4 to 13) times I think my app not holding the connection properly with the Bluetooth shield, I am not sure about the problem. I tried with the same Arduino code with some other Android application. It was working well. So problem is in my code only. I am using log to monitor the flow of code. The data is sending from the Android device and the Bluetooth is live and still paired. I think Bluetooth shield was not receiving or it was receiving and not passing the data to Arduino. I am troubling for couple of weeks.
Thanks in Advance !!
My code goes here...
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private static String address = "98:D3:31:30:25:DC";//old: 20:14:12:03:12:42, 98:D3:31:30:25:DC
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private InputStream inStream = null;
Handler handler = new Handler();
byte delimiter = 10;
boolean stopWorker = false;
int readBufferPosition = 0;
byte[] readBuffer = new byte[1024];
//
//Bluetooth sender ends
//
//
private final BroadcastReceiver commandAction = new BroadcastReceiver() {
#Override
public void onReceive(Context context2, Intent intent2) {
String com = intent2.getStringExtra("key");
commandAction(com);
Toast.makeText(context2, "commandAction:"+com, Toast.LENGTH_SHORT).show();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
commandAction("up");
}
});
GCMRegistrar.checkDevice( this );
GCMRegistrar.checkManifest( this );
final String regId = GCMRegistrar.getRegistrationId( this );
if( regId.equals( "" ) ) {
GCMRegistrar.register( this, "501396392354" );
Toast.makeText(this," 501396392354", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(this,regId, Toast.LENGTH_SHORT).show();
Log.v( TAG2, "Already registered" );
Log.v(TAG2, "Registration id is: " + regId );
}
startService(new Intent(MainActivity.this, LocationService.class));
CheckBt();
Connect();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.e("Jon", device.toString());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
#Override
public Object onRetainNonConfigurationInstance() {
if (mAccessory != null) {
return mAccessory;
} else {
return super.onRetainNonConfigurationInstance();
}
}
#Override
public void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("in.robot.gcm.commandaction");
registerReceiver(commandAction, intentFilter);
if (mInputStream != null && mOutputStream != null) {
return;
}
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(commandAction);
closeAccessory();
}
#Override
public void onDestroy() {
unregisterReceiver(mUsbReceiver);
stopService(new Intent(MainActivity.this, LocationService.class));
try {
btSocket.close();
} catch (IOException e) {
}
super.onDestroy();
}
private void openAccessory(UsbAccessory accessory) {
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
mAccessory = accessory;
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Log.d(TAG, "accessory opened");
} else {
Log.d(TAG, "accessory open fail");
}
}
private void closeAccessory() {
try {
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
} catch (IOException e) {
} finally {
mFileDescriptor = null;
mAccessory = null;
}
}
public void commandAction(String command){
byte[] buffer = new byte[1];
MediaPlayer mp;
Toast.makeText(this,"in cmd action",Toast.LENGTH_SHORT).show();
if("up".equals(command)){
buffer[0]=(byte)0;
Log.v(TAG ,"up heay");
writeData("1");
Toast.makeText(this,"UP",Toast.LENGTH_SHORT).show();
}
else if("down".equals(command)) {
buffer[0]=(byte)1;
Log.v(TAG ,"down heay");
writeData("2");
}
else if("left".equals(command)){
buffer[0]=(byte)2;
writeData("3");
}
else if("right".equals(command)){
buffer[0]=(byte)3;
writeData("4");
}
else if("break".equals(command)){
buffer[0]=(byte)4;
writeData("0");
}
else if("camera left".equals(command)){
buffer[0]=(byte)5;
//writeData("0");
}
else if("camera right".equals(command)){
buffer[0]=(byte)6;
//writeData("0");
}
else if ("jigsaw1".equals(command)){
mp = MediaPlayer.create(MainActivity.this, R.raw.jigsaw1);
mp.start();
}
else if("jigsaw2".equals(command)){
mp = MediaPlayer.create(MainActivity.this, R.raw.jigsaw2);
mp.start();
}
else if("horn".equals(command)){
mp = MediaPlayer.create(MainActivity.this, R.raw.horn);
mp.start();
}
else if("start".equals(command)){
mp = MediaPlayer.create(MainActivity.this, R.raw.start);
mp.start();
}
else if("ghosts".equals(command)){
mp = MediaPlayer.create(MainActivity.this, R.raw.ghosts);
mp.start();
}
else if("flash on".equals(command)){
if((this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) && !(isLighOn)){
cam = Camera.open();
Parameters params = cam.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_ON);
cam.setParameters(params);
cam.startPreview();
isLighOn=true;
Log.v("camera","flash on");
}
else{Log.v("camera","flash not exsisted");}
}
else if("flash off".equals(command)){
if(isLighOn){
cam.stopPreview();
cam.release();
isLighOn=false;
Log.v("camera","flash off");
} }
else if("location on".equals(command)){
startService(new Intent(MainActivity.this, LocationService.class));
}
else if("location off".equals(command)){
stopService(new Intent(MainActivity.this, LocationService.class));
}
else if("speed min".equals(command)){
buffer[0]=(byte)7;
}
else if("speed min".equals(command)){
buffer[0]=(byte)8;
}
else if("speed max".equals(command)){
buffer[0]=(byte)9;
}
else{
Log.v(TAG ,"no command recieved");}
if (mOutputStream != null) {
try {
mOutputStream.write(buffer);
} catch (IOException e) {
Log.e(TAG, "write failed", e);
}
}
}
//
//
//
//
private void CheckBt() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(), "Bluetooth Disabled !",
Toast.LENGTH_SHORT).show();
}
if (mBluetoothAdapter == null) {
Toast.makeText(getApplicationContext(),
"Bluetooth null !", Toast.LENGTH_SHORT)
.show();
}
}
public void Connect() {
Log.d(TAG, address);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.d(TAG, "Connecting to ... " + device);
Toast.makeText(this, "Connecting to...", Toast.LENGTH_SHORT).show();
mBluetoothAdapter.cancelDiscovery();
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
btSocket.connect();
Log.d(TAG, "Connection made.");
Toast.makeText(this, "Connection made Successful..", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
Log.d(TAG, "Unable to end the connection");
Toast.makeText(this, "Unable to end the connection", Toast.LENGTH_SHORT).show();
}
Log.d(TAG, "Socket creation failed");
Toast.makeText(this, "connection creation failed", Toast.LENGTH_SHORT).show();
}
//beginListenForData();
}
private void writeData(String data) {
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
Log.d(TAG, "Bug BEFORE Sending stuff", e);
}
String message = data;
byte[] msgBuffer = message.getBytes();
try {
outStream.write(msgBuffer);
Toast.makeText(this, "Data Send Successful..", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Log.d(TAG, "Bug while sending stuff", e);
Toast.makeText(this, "Data Send Error..", Toast.LENGTH_SHORT).show();
}
}
}
outStream.write(msgBuffer);
It writes only first bit. how to write 8 bit out of it.If we are sending 00000001 means it writes only 0. But we want to write whole 8 bit how to achieve it.
public class MainActivity extends ActionBarActivity {
private ToggleButton power, simulation, reset, pause, replay, diagnose,
abs, emergency;
private static final String TAG = "bluetooth1";
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
// SPP UUID service
private static final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
// MAC-address of Bluetooth module (you must edit this line)
private static String address = "00:12:02:28:75:34";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
power = (ToggleButton) findViewById(R.id.toggleButton1);
simulation = (ToggleButton) findViewById(R.id.simulation_tb);
reset = (ToggleButton) findViewById(R.id.reset_bt);
pause = (ToggleButton) findViewById(R.id.pause_bt);
replay = (ToggleButton) findViewById(R.id.replay_bt);
diagnose = (ToggleButton) findViewById(R.id.diagnose_bt);
abs = (ToggleButton) findViewById(R.id.abs_bt);
emergency = (ToggleButton) findViewById(R.id.emergency_bt);
btAdapter = BluetoothAdapter.getDefaultAdapter();
checkBTState();
power.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (power.isChecked()) {
String str = "1";
int i = Integer.parseInt(str);
String binarystr = Integer.toBinaryString(i);
char[] buffer = new char[binarystr.length()];
binarystr.getChars(0, binarystr.length(), buffer, 0);
System.out.println("char array:: "
+ Arrays.toString(buffer));
byte[] binaryFormat = getbyteFromString(buffer);
for (byte b : binaryFormat) {
sendData(Integer.toBinaryString(b & 255 | 256)
.substring(1));
}
Toast.makeText(getApplicationContext(), "LED ON",
Toast.LENGTH_LONG).show();
} else {
sendData("0");
Toast.makeText(getApplicationContext(), "LED OFF",
Toast.LENGTH_LONG).show();
}
}
});
}
#Override
public void onBackPressed() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(getString(R.string.const_closeApp))
.setPositiveButton(getString(R.string.const_yes),
dialogClickListener)
.setNegativeButton(getString(R.string.const_no),
dialogClickListener).show();
}
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
// LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(new
// BTStateChangedBroadcastReceiver());
System.exit(0);
finish();
break;
case DialogInterface.BUTTON_NEGATIVE:
// No button clicked
break;
}
}
};
private void checkBTState() {
// Check for Bluetooth support and then check to make sure it is turned
// on
// Emulator doesn't support Bluetooth and will return null
if (btAdapter == null) {
errorExit("Fatal Error", "Bluetooth not support");
} else {
if (btAdapter.isEnabled()) {
Log.d(TAG, "...Bluetooth ON...");
} else {
// Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device)
throws IOException {
if (Build.VERSION.SDK_INT >= 10) {
try {
final Method m = device.getClass().getMethod(
"createInsecureRfcommSocketToServiceRecord",
new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, MY_UUID);
} catch (Exception e) {
Log.e(TAG, "Could not create Insecure RFComm Connection", e);
}
}
return device.createRfcommSocketToServiceRecord(MY_UUID);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void sendData(String message) {
byte[] msgBuffer = message.getBytes();
Log.d(TAG, "...Send data: " + message + "...");
try {
outStream.write(msgBuffer);
Log.d(TAG, "...This is the value byte: " + msgBuffer);
} catch (IOException e) {
String msg = "In onResume() and an exception occurred during write: "
+ e.getMessage();
if (address.equals("00:00:00:00:00:00"))
msg = msg
+ ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 35 in the java code";
msg = msg + ".\n\nCheck that the SPP UUID: " + MY_UUID.toString()
+ " exists on server.\n\n";
errorExit("Fatal Error", msg);
}
}
private void errorExit(String title, String message) {
Toast.makeText(getBaseContext(), title + " - " + message,
Toast.LENGTH_LONG).show();
finish();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public static byte[] getbyteFromString(char[] binarystr) {
int length = binarystr.length / 8;
if (binarystr.length % 8 > 0)
length++;
int iterationCount = length;
byte[] binaryFormat = new byte[iterationCount];
int iter = iterationCount - 1;
for (int i = binarystr.length - 1; i >= 0;) {
byte byt = 0x0;
for (int j = 0; j < 8; j++) {
if (i < 0)
break;
int b = binarystr[i] - 48;
byt = (byte) (byt + (b << j));
i--;
}
binaryFormat[iter] = byt;
iter--;
}
return binaryFormat;
}
#Override
public void onResume() {
super.onResume();
Log.d(TAG, "...onResume - try connect...");
// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. In this case we are using the
// UUID for SPP.
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e1) {
errorExit("Fatal Error", "In onResume() and socket create failed: "
+ e1.getMessage() + ".");
}
/*
* try { btSocket = device.createRfcommSocketToServiceRecord(MY_UUID); }
* catch (IOException e) { errorExit("Fatal Error",
* "In onResume() and socket create failed: " + e.getMessage() + "."); }
*/
// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
Log.d(TAG, "...Connecting...");
try {
btSocket.connect();
Log.d(TAG, "...Connection ok...");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error",
"In onResume() and unable to close socket during connection failure"
+ e2.getMessage() + ".");
}
}
// Create a data stream so we can talk to server.
Log.d(TAG, "...Create Socket...");
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
errorExit(
"Fatal Error",
"In onResume() and output stream creation failed:"
+ e.getMessage() + ".");
}
}
#Override
public void onPause() {
super.onPause();
Log.d(TAG, "...In onPause()...");
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e) {
errorExit(
"Fatal Error",
"In onPause() and failed to flush output stream: "
+ e.getMessage() + ".");
} catch (NullPointerException e) {
e.printStackTrace();
}
}
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "In onPause() and failed to close socket."
+ e2.getMessage() + ".");
}
}
}
It looks like your code is not complete. Anyway, I suggest to use the DataInputStream / DataOutputStream of Android. Just wrap your streams into them. They provide methods for writing any kind of primitive datatype up to String with arbitrary encoding. All you need to do is use the writeString(...) method and use the read String method on the other side. This way you don't need to convert the String in order to write it into you stream and you don't need to care about how to reconstruct it from the stream.
If you only want to write Strings you can use the BufferedWriter which allows you to only write Strings to an stream, you can use it like this to stick it onto a 'OutputStream'
OutputStreamWriter osw = new OutputStreamWriter(outStream);
BufferedWriter writer = new BufferedWriter(osw);