here is my code:
Thread connectThread = new Thread(new Runnable() {
#Override
public void run() {
try {
boolean gotuuid = btDevices.getItem(position)
.fetchUuidsWithSdp();
if (gotuuid){
UUID uuid = btDevices.getItem(position).getUuids()[0]
.getUuid();
mbtSocket = btDevices.getItem(position)
.createRfcommSocketToServiceRecord(uuid);
mbtSocket.connect();
} else {
Log.e("ID22", "There is no uuid");
}
} catch (IOException ex) {
runOnUiThread(socketErrorRunnable);
try {
mbtSocket.close();
} catch (IOException e) {
// e.printStackTrace();
}
mbtSocket = null;
return;
} finally {
runOnUiThread(new Runnable() {
#Override
public void run() {
finish();
}
});
}
}
});
connectThread.start();
}
When I try to use mbtSocket.connect();to connect to the bluetooth soccket it stops and throws socketErrorRunnable exception. Have you got any idea how to fix this? I searched about that but nothing works for me.
In case you have troubles here are some code from the official Android Bluetooth Chat example :
Server side :
public class BluetoothServer {
private final static String TAG = "BluetoothServer";
private final BluetoothServerSocket serverSocket;
// I would recommand defining a secure connexion so forget the unsecore UUID
private static final UUID MY_UUID_SECURE =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66"); // choose another UUID go to a site that generates a random UUI ;-)
private static final UUID MY_UUID_INSECURE =
UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); // choose another UUID go to a site that generates a random UUI ;-)
// BUT THIS WILL BE THE UUID YOU NEED TO CONNECT TO IN YOUR CLIENT APP -> createRfcommSocketToServiceRecord(UUID.fromString("0800200c9a66"));
// Name for the SDP record when creating server socket
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
public BluetoothServer(BluetoothAdapter adapter, boolean secure) {
try {
if (secure) {
this.serverSocket = adapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
this.serverSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + (secure ? "secure" : "insecure") + "listen() failed", e);
}
}
public void asyncStartServer() {
new Thread(new Runnable() {
#Override
public void run() {
try {
final BluetoothSocket socket = serverSocket.accept(); // blocks/wait until your phone connects
// at this point, your phone is connected
final InputStream is = socket.getInputStream();
// and now start reading
} catch (IOException ioe) {
Log.getStackTraceString(ioe);
}
}
}).start();
}
}
Related
I am trying to send String message via Bluetooh. I am using code from this post:send message
I would like to send message on OnClick() to another connected device. Currently i can display paired devices and i am able to connect with them.
P.S I am trying to send message in write() function. When i tried to debug the code, i've figured out that debugger don't enter toMESSAGE WRITE on MESSAGE READ statement. Thanks for any help.
public class BluetoothActivity extends AppCompatActivity {
public static final int REQUEST_ENABLE_BT=1;
ListView lv_paired_devices;
Button sendMessage;
Set<BluetoothDevice> set_pairedDevices;
ArrayAdapter adapter_paired_devices;
BluetoothAdapter bluetoothAdapter;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static final int MESSAGE_READ=0;
public static final int MESSAGE_WRITE=1;
public static final int CONNECTING=2;
public static final int CONNECTED=3;
public static final int NO_SOCKET_FOUND=4;
String bluetooth_message="00";
#SuppressLint("HandlerLeak")
Handler mHandler=new Handler()
{
#Override
public void handleMessage(Message msg_type) {
super.handleMessage(msg_type);
switch (msg_type.what){
case MESSAGE_READ:
byte[] readbuf=(byte[])msg_type.obj;
String string_recieved=new String(readbuf);
Log.i("TAGREAD", "Bluetooth not supported");
Toast.makeText(getApplicationContext(),string_recieved,Toast.LENGTH_LONG).show();
//do some task based on recieved string
break;
case MESSAGE_WRITE:
if(msg_type.obj!=null){
ConnectedThread connectedThread=new ConnectedThread((BluetoothSocket)msg_type.obj);
connectedThread.write(bluetooth_message.getBytes());
Log.i("TAGWRITE", "Bluetooth not supported");
}
break;
case CONNECTED:
Toast.makeText(getApplicationContext(),"Connected",Toast.LENGTH_SHORT).show();
break;
case CONNECTING:
Toast.makeText(getApplicationContext(),"Connecting...",Toast.LENGTH_SHORT).show();
break;
case NO_SOCKET_FOUND:
Toast.makeText(getApplicationContext(),"No socket found",Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setTitle("Sparowane urządzenia");
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Log.i("TAGTAG", "Bluetooth not supported");
// Show proper message here
finish();
}
else{
setContentView(R.layout.activity_bluetooth);
initialize_layout();
initialize_bluetooth();
start_accepting_connection();
initialize_clicks();
}
}
public void start_accepting_connection()
{
//call this on button click as suited by you
AcceptThread acceptThread = new AcceptThread();
acceptThread.start();
Toast.makeText(getApplicationContext(),"accepting",Toast.LENGTH_SHORT).show();
}
public void initialize_clicks()
{
lv_paired_devices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
Object[] objects = set_pairedDevices.toArray();
BluetoothDevice device = (BluetoothDevice) objects[position];
ConnectThread connectThread = new ConnectThread(device);
connectThread.start();
Toast.makeText(getApplicationContext(),"device choosen "+device.getName(),Toast.LENGTH_SHORT).show();
}
});
}
public void initialize_layout()
{
lv_paired_devices = (ListView)findViewById(R.id.lv_paired_devices);
adapter_paired_devices = new ArrayAdapter(getApplicationContext(),R.layout.support_simple_spinner_dropdown_item);
lv_paired_devices.setAdapter(adapter_paired_devices);
sendMessage=findViewById(R.id.send_button);
}
public void initialize_bluetooth()
{
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
// Device doesn't support Bluetooth
Toast.makeText(getApplicationContext(),"Your Device doesn't support bluetooth. you can play as Single player",Toast.LENGTH_SHORT).show();
finish();
}
//Add these permisions before
// <uses-permission android:name="android.permission.BLUETOOTH" />
// <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
// <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
// <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
else {
set_pairedDevices = bluetoothAdapter.getBondedDevices();
if (set_pairedDevices.size() > 0) {
for (BluetoothDevice device : set_pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
adapter_paired_devices.add(device.getName() + "\n" + device.getAddress());
}
}
}
}
public class AcceptThread extends Thread
{
private final BluetoothServerSocket serverSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = bluetoothAdapter.listenUsingRfcommWithServiceRecord("NAME",MY_UUID);
} catch (IOException e) { }
serverSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null)
{
// Do work to manage the connection (in a separate thread)
mHandler.obtainMessage(CONNECTED).sendToTarget();
}
}
}
}
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
bluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mHandler.obtainMessage(CONNECTING).sendToTarget();
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)
// bluetooth_message = "Initial message"
// mHandler.obtainMessage(MESSAGE_WRITE,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 = new byte[2]; // 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.read(buffer);
// Send the obtained bytes to the UI activity
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
Toast.makeText(BluetoothActivity.this,bytes,Toast.LENGTH_LONG).show();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
sendMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
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 want to make connection between my own android device and the selected Bluetooth device which i get after scanning ... but i don't know how this line of code work to get MAC address of selected device ...
String Mac = string.substring(itemvalue.length() - 17);
Whole code of select item from the list is here :
unpairlv.setOnItemClickListener(new AdapterView.OnItemClickListener() { #Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String itemValue = (String) unpairlv.getItemAtPosition(position);
String MAC = itemValue.substring(itemValue.length() - 17);
BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(MAC);
// Initiate a connection request in a separate thread
ConnectingThread t = new ConnectingThread(bluetoothDevice);
t.start();
}
});
and here is my ConnectingThread class :
private class ConnectingThread extends Thread {
private final BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
public ConnectingThread(BluetoothDevice device) {
BluetoothSocket temp = null;
bluetoothDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
}
public void run() {
// Cancel discovery as it will slow down the connection
bluetoothAdapter.cancelDiscovery();
try {
// This will block until it succeeds in connecting to the device
// through the bluetoothSocket or throws an exception
bluetoothSocket.connect();
} catch (IOException connectException) {
connectException.printStackTrace();
try {
bluetoothSocket.close();
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
// Code to manage the connection in a separate thread
/*
manageBluetoothConnection(bluetoothSocket);
*/
}
// Cancel an open connection and terminate the thread
public void cancel() {
try {
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm trying to get two android phones to connect via bluetooth. I'm following the instructions here from the android online howto's, and I'm following pretty closely.
http://developer.android.com/guide/topics/connectivity/bluetooth.html
I can get bluetooth to connect once, but I have to restart the android device or the app itself in order to get it to connect a second time. This is not a problem during development because with each edit of the code the android studio program re-loads the app. It starts it and restarts it, so that during testing I can connect over and over. During actual use I have to restart the android phone or go to the applications manager option under settings and physically stop that app.
From the code below I can connect if I call these lines:
generateDefaultAdapter();
startDiscovery();
startThreadAccept();
startThreadConnect();
How do I get it so that the bluetooth connection can be initiated over and over again? I see the message 'unable to connect' from the inner class 'ConnectThread' and an IO error from a 'printStackTrace()' from that part of the code. The second time I try, I seem to be able to call the method 'stopConnection()' and then the lines above (starting with 'generateDefaultAdapter()') but I find I cannot connect.
package org.test;
//some import statements here...
public class Bluetooth {
public boolean mDebug = true;
public BluetoothAdapter mBluetoothAdapter;
public UUID mUUID = UUID.fromString(BLUETOOTH_UUID);
public Thread mAcceptThread;
public Thread mConnectThread;
public ConnectedThread mManageConnectionAccept;
public ConnectedThread mManageConnectionConnect;
public APDuellingBluetooth() {
}
public void generateDefaultAdapter() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled() ) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
(mDialogDuel.getActivity()).startActivityForResult(enableBtIntent, INTENT_ACTIVITY_BLUETOOTH_REQUEST_ENABLE);
}
}
public void cancelDiscovery() { if (mBluetoothAdapter != null) mBluetoothAdapter.cancelDiscovery();}
public void startDiscovery() { mBluetoothAdapter.startDiscovery();}
public BluetoothAdapter getBluetoothAdapter() {return mBluetoothAdapter;}
public void stopConnection () {
try {
if (mAcceptThread != null) {
mAcceptThread.interrupt();
//mAcceptThread.join();
mAcceptThread = null;
}
if (mConnectThread != null) {
mConnectThread.interrupt();
//mConnectThread.join();
mConnectThread = null;
}
if (mManageConnectionConnect != null) {
mManageConnectionConnect.cancel();
mManageConnectionConnect.interrupt();
mManageConnectionConnect = null;
}
if (mManageConnectionAccept != null) {
mManageConnectionAccept.cancel();
mManageConnectionAccept.interrupt();
mManageConnectionAccept = null;
}
}
catch(Exception e) {
e.printStackTrace();
}
}
public void startThreadAccept () {
if (mAcceptThread != null && !mAcceptThread.isInterrupted()) {
if (mDebug) System.out.println("server already open");
//return;
mAcceptThread.interrupt();
mAcceptThread = new AcceptThread();
}
else {
mAcceptThread = new AcceptThread();
}
if (mAcceptThread.getState() == Thread.State.NEW ){
//mAcceptThread.getState() == Thread.State.RUNNABLE) {
mAcceptThread.start();
}
}
public void startThreadConnect () {
BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(mChosen.getAddress());
//if (mDebug) System.out.println(mDevice.getAddress() + " -- " + mChosen.getAddress() );
if (mConnectThread != null && !mConnectThread.isInterrupted()) {
if (mDebug) System.out.println("client already open");
//return;
mConnectThread.interrupt();
mConnectThread = new ConnectThread(mDevice);
}
else {
mConnectThread = new ConnectThread(mDevice);
}
if (mConnectThread.getState() == Thread.State.NEW){// ||
//mConnectThread.getState() == Thread.State.RUNNABLE) {
mConnectThread.start();
}
}
public void manageConnectedSocketAccept(BluetoothSocket socket) {
String mTemp = mBluetoothAdapter.getName();
if (mDebug) {
System.out.println("socket accept from " + mTemp);
System.out.println("info accept " + socket.getRemoteDevice().toString());
}
if (mManageConnectionAccept != null && !mManageConnectionAccept.isInterrupted()) {
//mManageConnectionAccept.cancel();
//mManageConnectionAccept.interrupt();
if (mAcceptThread == null) System.out.println(" bad thread accept");
}
else {
mManageConnectionAccept = new ConnectedThread(socket, "accept");
}
if (mManageConnectionAccept.getState() == Thread.State.NEW ){//||
//mManageConnectionAccept.getState() == Thread.State.RUNNABLE) {
mManageConnectionAccept.start();
}
}
public void manageConnectedSocketConnect(BluetoothSocket socket) {
String mTemp = mBluetoothAdapter.getName();
if (mDebug) {
System.out.println("socket connect from " + mTemp);
System.out.println("info connect " + socket.getRemoteDevice().toString());
}
if (mManageConnectionConnect != null && !mManageConnectionConnect.isInterrupted()) {
//mManageConnectionConnect.cancel();
//mManageConnectionConnect.interrupt();
if (mConnectThread == null) System.out.print(" bad thread connect ");
}
else {
mManageConnectionConnect = new ConnectedThread(socket, "connect");
}
if (mManageConnectionConnect.getState() == Thread.State.NEW){// ||
//mManageConnectionConnect.getState() == Thread.State.RUNNABLE) {
mManageConnectionConnect.start();
}
}
public void decodeInput (String mIn, ConnectedThread mSource) {
// do something with info that is returned to me...
}
public void encodeOutput (String mMac1, String mMac2, int mLR1, int mLR2) {
String mTemp = composeOutputString ( mServer, mMac1,mMac2, mLR1, mLR2);
if (mManageConnectionConnect != null && mManageConnectionConnect.isConnected()) {
mManageConnectionConnect.write(mTemp.getBytes());
mManageConnectionConnect.flush();
}
if (mManageConnectionAccept != null && mManageConnectionAccept.isConnected()) {
mManageConnectionAccept.write(mTemp.getBytes());
mManageConnectionAccept.flush();
}
mTemp = composeOutputString ( mClient, mMac1,mMac2, mLR1, mLR2);
if (mManageConnectionConnect != null && mManageConnectionConnect.isConnected()) {
mManageConnectionConnect.write(mTemp.getBytes());
mManageConnectionConnect.flush();
}
if (mManageConnectionAccept != null && mManageConnectionAccept.isConnected()) {
mManageConnectionAccept.write(mTemp.getBytes());
mManageConnectionAccept.flush();
}
}
public String composeOutputString (SocketConnectData mData, String mMac1, String mMac2, int mLR1, int mLR2) {
// make a string here with the data I want to send...
String mTemp = new String();
return mTemp;
}
/////////////////////////////////////////////
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
private boolean mLoop = true;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
mLoop = true;
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(mServiceNameReceive, mUUID );
} catch (IOException e) {
System.out.println("rfcomm problem ");
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (mLoop) {
try {
if (mmServerSocket != null) {
socket = mmServerSocket.accept();
}
} catch (IOException e) {
if (mDebug) System.out.println("rfcomm accept problem");
e.printStackTrace();
break;
}
// If a connection was accepted
if (socket != null && ! isConnectionOpen() ) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocketAccept(socket);
try {
mmServerSocket.close();
}
catch (IOException e) {}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mLoop = false;
mmServerSocket.close();
} catch (IOException e) { }
}
}
/////////////////////////////////////////////
private class ConnectThread extends Thread {
//private final BluetoothSocket mmSocket;
private 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;
try {
tmp = device.createRfcommSocketToServiceRecord(mUUID);
if (mDebug) System.out.println("connect -- rf socket to service record " + tmp);
} catch (Exception e) {
System.out.println("exception -- rf socket to service record problem " + tmp);
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
}
//catch (InterruptedException e ) {System.out.println("interrupted exception");}
catch (IOException e) {
// Unable to connect; close the socket and get out
if (mDebug) System.out.println("unable to connect ");
e.printStackTrace(); // <---- I see output from this spot!!
try {
mmSocket.close();
} catch (IOException closeException) {
System.out.println("unable to close connection ");
}
return;
}
// Do work to manage the connection (in a separate thread)
if (mmSocket.isConnected() && ! isConnectionOpen()) {
manageConnectedSocketConnect(mmSocket);
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
public boolean isConnected() {
return mmSocket.isConnected();
}
}
/////////////////////////////////////////////
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public String mTypeName = "";
private boolean mLoop = true;
public StringWriter writer;
public ConnectedThread(BluetoothSocket socket, String type) {
mTypeName = type;
mLoop = true;
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;
try {
writer = new StringWriter();
}
catch (Exception e) {}
}
public void run() {
byte[] buffer = new byte[1024]; //
int bytes; // bytes returned from read()
String [] mLines ;
// Keep listening to the InputStream until an exception occurs
while (mLoop) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
if (bytes == -1 || bytes == 0) {
if (mDebug) System.out.println("zero read");
return;
}
writer.append(new String(buffer, 0, bytes));
mLines = writer.toString().split("!");
if (mDebug) System.out.println( "lines " +mLines.length);
for (int i = 0; i < mLines.length; i ++ ) {
if (true) {
if (mDebug) System.out.println(" " + mLines[i]);
decodeInput (mLines[i], this);
}
}
} catch (Exception e) {
e.printStackTrace();
if (mDebug) System.out.println("read buffer problem");
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) {
e.printStackTrace();
if (mDebug) System.out.println("bad write");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mLoop = false;
mmSocket.close();
mmOutStream.close();
mmInStream.close();
} catch (IOException e) { }
}
public boolean isConnected() {
boolean mIsOpen = false;
try {
mIsOpen = mmSocket.isConnected() ;
} catch (Exception e) {}
return mIsOpen;
}
public void flush() {
try {
mmOutStream.flush();
}
catch (IOException e) {e.printStackTrace();}
}
}
///////////////////////////////////////////////
}
Thanks for your time.
EDIT: this is the error msg:
W/System.err﹕ java.io.IOException: read failed, socket might closed or timeout, read ret: -1
W/System.err﹕ at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:553)
W/System.err﹕ at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:530)
W/System.err﹕ at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:357)
W/System.err﹕ at org.davidliebman.test.Bluetooth$ConnectThread.run(Bluetooth.java:761)
Try this:
Instead of restarting the app. Turn off the Bluetooth on the Android device and turn it back on after a 5-sec delay. If you could make the connection successfully, it typically a sign that you did not close the connection and socket completely. Log your code. Make sure the closing socket routine is smoothly executed. Check if the IOException you have in your cancel method of your ConnectedThread is not catching any exception:
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
// ADD LOG
mLoop = false;
mmSocket.close();
mmOutStream.close();
mmInStream.close();
// ADD LOG
} catch (IOException e) {
// ADD LOG}
}
I am trying to send data from Android Client (Nexus 4) to Python Server (Linux Machine) over Bluetooth using Python-bluez. Whenever the client writes some bytes to the OutputStream it throws an IO exception "Broken Pipe". The server also seems that it does not accept any connections although the Android client did not throw any exceptions after "socket_name.connect()"
Android Client:
public class MainActivity extends Activity {
private BluetoothSocket ClientSocket;
private BluetoothDevice Client;
private ConnectedThread Writer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#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;
}
public BluetoothAdapter mblue;
public void connect(View sender)
{
mblue = BluetoothAdapter.getDefaultAdapter();
int REQUEST_ENABLE_BT = 1;
final TextView er = (TextView)findViewById(R.id.Error);
if(mblue == null)
er.setText("No Bluetooth!");
else if (mblue.isEnabled()) {
er.setText(mblue.getAddress() + " " + mblue.getName());
}
else{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
public void disov(View sender)
{
final TextView er = (TextView)findViewById(R.id.Error);
boolean tr = mblue.startDiscovery();
if(tr == true)
{
er.setText("Disovering !!");
}
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
}
public void start(View sender)
{
final TextView er = (TextView)findViewById(R.id.Error);
final TextView lol = (TextView)findViewById(R.id.editText1);
Writer.write(lol.getText().toString().getBytes());
lol.setText("");
}
public void send(View sender)
{
ConnectThread con = new ConnectThread(Client);
con.start();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
//mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
final TextView er = (TextView)findViewById(R.id.Error);
if(device.getAddress().equals("9C:2A:70:49:61:B0") == true)
{
Client = device;
er.setText("Connected with the target device!");
}
}
}
};
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;
UUID myuuid = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee");
final TextView er = (TextView)findViewById(R.id.Error);
// 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(myuuid);
} catch (IOException e) {}
ClientSocket = mmSocket = tmp;
Writer = new ConnectedThread(ClientSocket);
}
public void run() {
// Cancel discovery because it will slow down the connection
mblue.cancelDiscovery();
final TextView er = (TextView)findViewById(R.id.Error);
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)
//manageConnectedSocket(mmSocket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {}
}
}
public 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;
final TextView er = (TextView)findViewById(R.id.Error);
// 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;
er.setText(er.getText() + "\n" + socket.toString());
}
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.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) {
final TextView er = (TextView)findViewById(R.id.Error);
try {
mmOutStream.write(bytes);
//mmOutStream.
} catch (IOException e)
{
er.setText(e.toString());
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
Python Server:
from bluetooth import *
server_sock=BluetoothSocket( RFCOMM )
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port = server_sock.getsockname()[1]
uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee"
advertise_service( server_sock, "SampleServer",
service_id = uuid,
service_classes = [ uuid, SERIAL_PORT_CLASS ],
profiles = [ SERIAL_PORT_PROFILE ],
# protocols = [ OBEX_UUID ]
)
print("Waiting for connection on RFCOMM channel %d" % port)
client_sock, client_info = server_sock.accept()
print("Accepted connection from ", client_info)
try:
while True:
data = client_sock.recv(1024)
if len(data) == 0: break
print("received [%s]" % data)
except IOError:
pass
print("disconnected")
client_sock.close()
server_sock.close()
print("all done")
Any help is appreciated.
You have used two public classes i.e public class MainActivity extends Activity{} and public class ConnectedThread extends Thread {}. But in Java there should be one public class and any number of other classes in one JavaClass file. So remove public class ConnectedThread extends Thread {} from that file and create a new Java class: public class ConnectedThread extends Thread {} in the same package.
Android 4.04(java) server to ubuntu 12.04(python) client with bluetooth (RFCOMM)
I'm currently trying to get a bluetooth communication between and android 4.04 galaxy taplet and linux computer with python (the computer will be running a ROS robot, and I need the tablet for GPS and INS data). I need the taplet to function as a server. Both drivers support RFCOMM, but the python option connects based on "Address" and "Port" where the java android connects on "UUID".
I'm currently looking for a way to give my android server a static port number, but I'm also open for other ways to solve the problem.
I have been stuck here for quite a while and have found lots of simular issues but none which solved my case, hope you guys can help me out.
Question: how can I bind my android bluetooth server to a socket ?
Ps: forgive that the code android code isen't perfect it have been modified quite a few times looking for workarounds
My current android code:
public class MainActivity extends Activity{
ArrayAdapter<String> listadapter;
ListView listView;
BluetoothAdapter mBluetoothAdapter;
Set<BluetoothDevice> devicesArray;
ArrayList<String> pairedDevices;
BroadcastReceiver receiver;
AcceptThread acceptThread;
public static final UUID MY_UUID = UUID.fromString("94f39d29-7d6d-437d-973b-fba39e49d4ee");
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
acceptThread = new AcceptThread();
acceptThread.start();
if(mBluetoothAdapter == null){
Toast.makeText(getApplicationContext(), "No bluetooth detected", 0).show();
finish();
}
else{
if(!mBluetoothAdapter.isEnabled()){
turnOnBluetooth();
}
getPairedDevices();
startDiscorevy();
}
}
private void startDiscorevy() {
mBluetoothAdapter.cancelDiscovery();
mBluetoothAdapter.startDiscovery();
}
private void turnOnBluetooth() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private void getPairedDevices() {
devicesArray = mBluetoothAdapter.getBondedDevices();
if(devicesArray.size()>0){
for(BluetoothDevice device:devicesArray){
pairedDevices.add(device.getName()+"\n"+device.getAddress());
}
}
}
private void init(){
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 600);
startActivity(discoverableIntent);
listView = (ListView) findViewById(R.id.listView);
listadapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,0);
listView.setAdapter(listadapter);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
}
#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 enable to continue", 0).show();
finish();
}
}
#Override
protected void onPause() {
super.onPause();
acceptThread.cancel();
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("Location_Service", MY_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
if (socket != null) {
manageConnectedSocket(socket);
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
private void manageConnectedSocket(BluetoothSocket socket) {
OutputStream mmOutStream;
BluetoothSocket mmSocket;
mmSocket = socket;
OutputStream tmpOut = null;
try {
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) { }
mmOutStream = tmpOut;
byte[] bytes = null;
String toSend = "hello world";
bytes = toSend.getBytes();
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
try {
mmSocket.close();
} catch (IOException e) { }
}
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
}
My current python code:
#!python
import bluetooth
from bluetooth import *
import sys
bluetooth_name = "GT-P5110"
bluetooth_address = None
uuid = None
print "looking for device"
nearby_devices = bluetooth.discover_devices()
for bdaddr in nearby_devices:
if bluetooth_name == bluetooth.lookup_name( bdaddr):
bluetooth_address == bdaddr
print "device found on address:"
print bdaddr
service_matches = find_service(uuid = uuid, address = bluetooth_address)
first_match = service_matches[0]
port = first_match["port"]
name = first_match["name"]
host = first_match["host"]
print " --- "
print port
print name
print host
print " --- "
sock = bluetooth.BluetoothSocket( bluetooth.RFCOMM)
sock.connect((bluetooth_address, port))
sock.close()
Note that the python code finds the device in both searches, returns its address correctly, and concludes the port and name to be none. I then get an error in sock.connect(addr,port) since port carnt be none.