I am going to implement the module of sending commands from my Android tablet to electronic device embedded with Bluetooth IC-chips Andrino HC-06 , for configuration of my device via Bluetooth. When it comes to execution, it seems that there is no observable response from the device when sending 22 23 54 01 C8.
It show the following timeout exception
It is expected that the device will restart and return many messages. What should I know more about when sending these eta commands to my device for remote control ?
The log cat message
05-23 18:19:44.866: E/BluetoothChatService(512): java.io.IOException: bt socket closed, read return: -1
05-23 18:19:44.866: E/BluetoothChatService(512): at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:429)
05-23 18:19:44.866: E/BluetoothChatService(512): at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96)
05-23 18:19:44.866: E/BluetoothChatService(512): at java.io.InputStream.read(InputStream.java:162)
05-23 18:19:44.866: E/BluetoothChatService(512): at com.example.android.BluetoothChat.BluetoothChatService$ConnectedThread.run(BluetoothChatService.java:485)
The below is my code
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
.show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
mOutEditText.setText(mOutStringBuffer);
}
}
Sending Commands
public void write(byte[] buffer) {
try {
boolean connected = false;
BluetoothSocket sock = null;
InputStream in = null ;
OutputStream out = null ;
BluetoothDevice zee = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("00:14:01:12:28:12");
Method m = zee.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
sock = (BluetoothSocket) m.invoke(zee, Integer.valueOf(1));
sock.connect();
in = sock.getInputStream();
out = sock.getOutputStream();
char[] test = { 0x22 , 0x21 , 0x03 , 0x00 , 0xc9};
for(int k=0; k < test.length; k++){
new DataOutputStream(sock.getOutputStream()).writeByte(test[k]);
}
byte [] bfferX = new String(test).getBytes("UTF-8");*/
mmOutStream.write(buffer);
mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I suppose the device are already paired and that the android device performs the discovery.
Why do you think it is a matter of timeout? The exception tells that the communication socket is already closed. Maybe you succeed in create a BluetoothSocket and close it "accidentally" (maybe, after flushing, you close the output or input stream related to the socket).
Since you are following the Android BluetoothChat example you should:
1) perform the discovery and listen for available devices:
private final BroadcastReceiver deviceFoundBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action) && mState==STATE_DISCOVERING) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
new ConnectThread(device).start();
}
}
};
2) connect to the device:
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = InsecureBluetooth.createRfcommSocketToServiceRecord(mmDevice, YOUR_UUID, false);
}
catch (IOException e) { }
mmSocket = tmp;
}
#Override
public void run() {
try {
btAdapter.cancelDiscovery(); // be sure discovery is cancelled
mmSocket.connect(); // blocking call, returns only on a successful connection or an exception
connected(mmSocket, mmSocket.getRemoteDevice());
new ConnectedThread(mmSocket, mmDevice.getAddress()).start(); // start connected thread
}
catch (IOException e) {}
}
public void cancel() {}
}
3) Retrieve the input and output stream for communicating with the paired device (do not close the streams while communication is needed):
private class ConnectedThread extends Thread {
private BluetoothSocket mmSocket;
private String macAddress;
public ConnectedThread(BluetoothSocket socket, String macAddress) {
this.macAddress = macAddress;
this.mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
mmInStream = mmSocket.getInputStream();
mmOutStream = mmSocket.getOutputStream();
}
catch (IOException e) {}
}
#Override
public void run() {
// perform communication
}
}
The class InsecureBluetooth is used to "avoid" the pairing phase and is based on this Stanford peace of code:
#TargetApi(10)
public class InsecureBluetooth {
static private class InUse extends RuntimeException { }
public static BluetoothServerSocket listenUsingRfcommWithServiceRecord(BluetoothAdapter adapter, String name, UUID uuid, boolean encrypt) throws IOException {
if(Build.VERSION.SDK_INT<10) {
try {
Class c_rfcomm_channel_picker = null;
Class[] children = BluetoothAdapter.class.getDeclaredClasses();
for(Class c : children) {
Log.e("TO", "class " + c.getCanonicalName());
if(c.getCanonicalName().equals(BluetoothAdapter.class.getName() + ".RfcommChannelPicker")) {
c_rfcomm_channel_picker = c;
break;
}
}
if(c_rfcomm_channel_picker == null)
throw new RuntimeException("can't find the rfcomm channel picker class");
Constructor constructor = c_rfcomm_channel_picker.getDeclaredConstructor(UUID.class);
if(constructor == null)
throw new RuntimeException("can't find the constructor for rfcomm channel picker");
Object rfcomm_channel_picker = constructor.newInstance(new Object[] {uuid});
Method m_next_channel = c_rfcomm_channel_picker.getDeclaredMethod("nextChannel", new Class[] {});
m_next_channel.setAccessible(true);
BluetoothServerSocket socket = null;
int channel;
int errno;
while (true) {
channel = (Integer)m_next_channel.invoke(rfcomm_channel_picker, new Object[] {});
if (channel == -1) {
throw new IOException("No available channels");
}
try {
socket = listenUsingRfcomm(channel, encrypt);
break;
} catch(InUse e) {
continue;
}
}
Field f_internal_service = adapter.getClass().getDeclaredField("mService");
f_internal_service.setAccessible(true);
Object internal_service = f_internal_service.get(adapter);
Method m_add_rfcomm_service_record = internal_service.getClass().getDeclaredMethod("addRfcommServiceRecord", new Class[] {String.class, ParcelUuid.class, int.class, IBinder.class});
m_add_rfcomm_service_record.setAccessible(true);
int handle = (Integer)m_add_rfcomm_service_record.invoke(internal_service, new Object[] { name, new ParcelUuid(uuid), channel, new Binder() } );
if (handle == -1) {
try {
socket.close();
} catch (IOException e) {}
throw new IOException("Not able to register SDP record for " + name);
}
Field f_internal_handler = null;
try {
f_internal_handler = adapter.getClass().getDeclaredField("mServiceRecordHandler");
} catch(Exception e) {
f_internal_handler = adapter.getClass().getDeclaredField("mHandler");
}
f_internal_handler.setAccessible(true);
Object internal_handler = f_internal_handler.get(adapter);
Method m_set_close_handler = socket.getClass().getDeclaredMethod("setCloseHandler", new Class[] {Handler.class, int.class});
m_set_close_handler.setAccessible(true);
m_set_close_handler.invoke(socket, new Object[] { internal_handler, handle});
return socket;
} catch (Exception e) {}
}
else {
return adapter.listenUsingInsecureRfcommWithServiceRecord(name, uuid);
}
}
private static BluetoothServerSocket listenUsingRfcomm(int port, boolean encrypt, boolean reuse) throws IOException, InUse {
BluetoothServerSocket socket = null;
try {
Constructor<BluetoothServerSocket> constructor = BluetoothServerSocket.class.getDeclaredConstructor(int.class, boolean.class, boolean.class, int.class);
if(constructor == null)
throw new RuntimeException("can't find the constructor");
constructor.setAccessible(true);
Field f_rfcomm_type = BluetoothSocket.class.getDeclaredField("TYPE_RFCOMM");
f_rfcomm_type.setAccessible(true);
int rfcomm_type = (Integer)f_rfcomm_type.get(null);
Field f_e_addr_in_use = BluetoothSocket.class.getDeclaredField("EADDRINUSE");
f_e_addr_in_use.setAccessible(true);
int e_addr_in_use = (Integer)f_e_addr_in_use.get(null);
socket = constructor.newInstance(new Object[] { rfcomm_type, false, encrypt, port } );
Field f_internal_socket = socket.getClass().getDeclaredField("mSocket");
f_internal_socket.setAccessible(true);
Object internal_socket = f_internal_socket.get(socket);
Method m_bind_listen = internal_socket.getClass().getDeclaredMethod("bindListen", new Class[] {});
m_bind_listen.setAccessible(true);
Object result = m_bind_listen.invoke(internal_socket, new Object[] {});
int errno = (Integer)result;
if(reuse && errno == e_addr_in_use) {
throw new InUse();
} else if (errno != 0) {
try {
socket.close();
} catch (IOException e) {}
internal_socket.getClass().getMethod("throwErrnoNative", new Class[] {int.class}).invoke(internal_socket, new Object[] { errno });
}
return socket;
} catch (Exception e) {}
}
public static BluetoothServerSocket listenUsingRfcomm(int port, boolean encrypt) throws IOException {
return listenUsingRfcomm(port, encrypt, false);
}
private static BluetoothSocket createRfcommSocketToServiceRecord(BluetoothDevice device, int port, UUID uuid, boolean encrypt) throws IOException {
try {
BluetoothSocket socket = null;
Constructor<BluetoothSocket> constructor = BluetoothSocket.class.getDeclaredConstructor(
int.class, int.class, boolean.class, boolean.class, BluetoothDevice.class, int.class, ParcelUuid.class);
if(constructor == null)
throw new RuntimeException("can't find the constructor for socket");
constructor.setAccessible(true);
Field f_rfcomm_type = BluetoothSocket.class.getDeclaredField("TYPE_RFCOMM");
f_rfcomm_type.setAccessible(true);
int rfcomm_type = (Integer)f_rfcomm_type.get(null);
socket = constructor.newInstance(new Object[] { rfcomm_type, -1, false, true, device, port, uuid != null ? new ParcelUuid(uuid) : null} );
return socket;
} catch (Exception e) {}
}
public static BluetoothSocket createRfcommSocketToServiceRecord(BluetoothDevice device, UUID uuid, boolean encrypt) throws IOException{
if(Build.VERSION.SDK_INT<10) {
return createRfcommSocketToServiceRecord(device, -1, uuid, encrypt);
}
else {
return device.createInsecureRfcommSocketToServiceRecord(uuid);
}
}
public static BluetoothSocket createRfcommSocket(BluetoothDevice device, int port, boolean encrypt) throws IOException {
return createRfcommSocketToServiceRecord(device, port, null, encrypt);
}
}
Related
I am using bluetoothconnection service on my fragment but ConnectedThread return empty. Although i am calling bluetoothconnection service but doesnt work. I dont find any solutions for this. How can i fix ?
Fragment:
if(convertView==null) {
convertView = inflater.inflate(R.layout.fragment_ota__update, container, false);
text=(TextView)convertView.findViewById(R.id.text);
InputStream is =this.getResources().openRawResource(R.raw.blink);
BufferedReader reader = new BufferedReader( new InputStreamReader(is));
send =(Button) convertView.findViewById(R.id.send);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
getActivity().registerReceiver(mBroadcastReceiver4, filter);
mBluetoothConnection = new BluetoothConnectionService(getActivity().getApplicationContext());
mBluetoothConnection.startClient(mBTDevice,MY_UUID_INSECURE);
if(is!=null){
try {
while ((data = reader.readLine()) != null) {
char [] ch =data.toCharArray();
for (char c: ch) {
int i= (int) c;
sbuffer.append(Integer.toHexString(i).toUpperCase());
text.setText(sbuffer);
}
}
is.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(sbuffer!=null) {
byte[] bytes = sbuffer.toString().getBytes(Charset.defaultCharset());
mBluetoothConnection.write(bytes);
}
}
});
}
In the fragment i am calling with this code:
mBluetoothConnection = new BluetoothConnectionService(getActivity().getApplicationContext());
BluetoothConnectionService part of write function
public void write(byte[] out) {
if(mConnectedThread !=null ){
// Create temporary object
// Synchronize a copy of the ConnectedThread
Log.d(TAG, "write: Write Called.");
//perform the write
mConnectedThread.write(out);
}
else{
Log.d(TAG, "mConnectedThread empty ");
}
}
And this is my bluetooth connection class :https://paste.ubuntu.com/p/gcPrydZnDw/
Your code is not something I can fix directly. But I here is aan example of how I made a connection and then send data to this connected device:
public class BluetoothConnection extends Thread {
public static BluetoothSocket mSocket;
private InputStream mInStream;
private OutputStream mOutStream;
private byte[] buffer;
private BluetoothAdapter mAdapter;
private Handler mHandler;
private String output;
private String sendString;
private String tempTester = "";
static UUID MY_UUID;
/**
* Constructor initializes all necessary variables.
* #param device the device that the constructor will connect to
*/
public BluetoothConnection(BluetoothDevice device){
MY_UUID = device.getUuids()[0].getUuid();
mAdapter = null;
mSocket = createMSocket(device);
mSocket = connectSocket(mSocket);
InputStream tmpIn = null;
OutputStream tmpOut = null;
try{
tmpIn = mSocket.getInputStream();
tmpOut = mSocket.getOutputStream();
}catch (IOException e){
e.printStackTrace();
}
mInStream = tmpIn;
mOutStream = tmpOut;
buffer = new byte[25];
}// end constructor
/**
* Creates the main socket that will be used in connection with device.
* #param device a BluetoothDevice
* #return a BluetoothSocket mSocket.
*/
private BluetoothSocket createMSocket(BluetoothDevice device) {
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
e.printStackTrace();
}
return tmp;
}// end createMSocket
/**
* Socket makes connection to device then returns back the updated socket.
* #param socket BluetoothSocket
* #return an updated version of the parameter socket.
*/
private BluetoothSocket connectSocket(BluetoothSocket socket){
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket.connect();
System.out.println("$$$$$$$$$$$$$$$$****** socket connected ******$$$$$$$$$$$$$$$$");
} catch (IOException e) {
//connection to device failed so close the socket
try {
socket.close();
System.out.println("$$$$$$$$$$$$$$$$****** socket closed ******$$$$$$$$$$$$$$$$");
} catch (IOException e2) {
e2.printStackTrace();
}
}
return socket;
}// end connectSocket
/**
* Sends message back to device in the form of a byte[].
* #param buffer byte[]
*/
public void write(byte[] buffer){
try{
mOutStream.write(buffer);
}catch(IOException e) {
e.printStackTrace();
}
}// end write
/**
* Closes the connection with the device
*/
public void cancel(){
try{
mSocket.close();
}catch(IOException e){
e.printStackTrace();
}
}// end cancel
}
Then on your main thread in an activity, you can call the following code (as long as you know the device you are connecting to):
BluetoothConnection connection = new BluetoothConnection(connectedDevice);
public void sendData(){
String s = editText.getText().toString();
byte[] b = s.getBytes();
connection.write(b);
//System.out.println("Bytes Sent");
}// end sendData
i'm trying to exchange Strings between two android devices. I'm able to establishe a RFCOMM connection and sending a String. But my APP cant receive it. After days of trail and error and searching on the internet i hope somebody can help me:
Thats my code so far:
public class MainActivity extends AppCompatActivity {
BluetoothAdapter bluetoothAdapter;
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg) {
Log.i("MAC", "in handler");
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
// DO something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
connectedThread.run();
Toast.makeText(getApplicationContext(), "CONNECT", Toast.LENGTH_LONG).show();
String s = "successfully connected";
connectedThread.write(s.getBytes());
Log.i("MAC", "connected");
break;
case MESSAGE_READ:
byte[] readBuf = (byte[])msg.obj;
String string = new String(readBuf);
Toast.makeText(getApplicationContext(), string, Toast.LENGTH_LONG).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
registerReceiver(mReceiver,filter);
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)){
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("MAC","Connect to : " +device.getAddress());
ConnectingThread ct = new ConnectingThread(device);
ct.start();
}
}
};
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.fromString("00001101-0000-1000-8000-00805F9B34FB"));
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
}
public void run() {
// Cancel any 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
mHandler.obtainMessage(SUCCESS_CONNECT, bluetoothSocket).sendToTarget();
/*
manageBluetoothConnection(bluetoothSocket);
*/
}
// Cancel an open connection and terminate the thread
public void cancel() {
try {
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
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) { }
}
}
}
I am having a bluetooth device . Basically i want my app to connect to the device and receive the data it sends.However so far i am able to connect to the bluetooth device,but i am not able to receive any inputs from it .
here is my problem:
i) DataInputStream.available() always return 0.
ii) If i use any breakpoint on line
bytes = input.read(buffer); // This will freeze doesn't show anything.
and line below it never executes
public class ConnectThread extends Thread{
final String TAG="ConnectThread";
private ReadThread mReadThread = null;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private boolean isDeviceConnected;
public final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private BluetoothSocket mmSocket = null;
Handler mHandler;
BluetoothDevice bTdevice;
private DataInputStream mReadData = null;
public ConnectThread(BluetoothDevice bTdevice, Handler mHandler) {
super();
this.bTdevice = bTdevice;
this.mHandler = mHandler;
InputStream tmpIn = null;
OutputStream tmpOut = null;
BluetoothSocket socket;
try {
socket = bTdevice.createRfcommSocketToServiceRecord(MY_UUID);
System.out.println("**** Socket created using standard way******");
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
mmSocket = socket;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
#Override
public synchronized void run() {
// TODO Auto-generated method stub
super.run();
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
adapter.cancelDiscovery();
Log.i("***Bluetooth Adapter**", "Bluetooth Discovery Canceled");
}
if (mmSocket != null) {
mmSocket.connect();
Log.i("***Socket Connection Successful**", "Socket Connection Successful");
isDeviceConnected = true;
mReadData = new DataInputStream(mmSocket.getInputStream());
Log.i("***Read data**", "" + mReadData);
if (mReadThread == null) {
mReadThread=new ReadThread(mReadData,mmSocket);
mReadThread.start();
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("***Error**", "Socket Connection failed");
e.printStackTrace();
try {
mmSocket.close();
isDeviceConnected = false;
} catch (IOException closeException) {
e.printStackTrace();
}
}
// mHandler.obtainMessage(DisplayBtdataActivity.SUCCESS_CONNECT,mmSocket).sendToTarget();
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
}
}
// Read the data from device
private class ReadThread extends Thread {
/** The input. */
private DataInputStream input;
/**
* Constructor for ReadThread.
*
* #param input
* DataInputStream
*/
private BluetoothSocket mSocket;
public ReadThread(DataInputStream input, BluetoothSocket socket) {
this.input = input;
this.mSocket = socket;
}
/**
* Method run.
*
* #see java.lang.Runnable#run()
*/
public synchronized void run() {
try {
Log.d(TAG, "ReadThread run");
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
bytes = input.available(); // always return 0
// bytes = mReadData.readInt();
Log.i("***Bytes data**", "" + bytes);// print 0
Log.i("***Data input stream**", "" + input); // Here input is not null
if (input != null) {
Log.i("***hello world**", "...");
while (isDeviceConnected) {
try {
bytes = input.read(buffer); // this code never executes
Log.i("**bytes data**", " " + bytes);
if (input != null) {
int len = input.readInt();
Log.i(TAG, "Response Length: " + len);
if (len > 65452) {// Short.MAX_VALUE*2
Log.i(TAG, "Error: Accesory and app are not in sync.");
continue;
}
Log.d(TAG, "Response Length: " + len);
Log.d(TAG, "Reading start time:" + System.currentTimeMillis());
byte[] buf = new byte[len];
Log.d(
TAG, "input.available() " + input.available());
if (input.available() > 0) {
input.readFully(buf);
System.out.println("Output:=");
}
Log.d(TAG, "Reading end time:" + System.currentTimeMillis());
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
isDeviceConnected = false;
}
}
}
} catch (Exception e) {
e.printStackTrace();
isDeviceConnected = false;
Log.e(TAG, "catch block 3 " + e.toString());
}
}
}
}
In ReadThread.Run() - you have to move the code
bytes = input.available (); // Always return 0
into while loop
1, you use input before checking for null if (input! = null)
2, Data is sent continuously and is a high probability that when running thread do not come any data, so therefore you have to give input.available bytes = (); into a while loop.
3, You can try to modify data processing. In principle, quickly read the data in the temporary buffer, and then move to MainBuffer and then manipulated with it. An example is in c # .net Xamarin, but just for an example :
private const int BTLPacketSize = 1024;
private const int BTLdataSize = 65536;
private System.Object InternaldataReadLock = new System.Object();
private System.Object dataReadLock = new System.Object();
private byte[] InternaldataRead = new byte[BTLPacketSize];//posila 64Byte pakety (resp. 62, protoze 2 jsou status bytes)
private byte[] TempdataRead = new byte[BTLPacketSize];
private byte[] dataRead = new byte[BTLdataSize];//Tyto pameti pouzivaji cursorc -> musim ohlidat preteceni pameti//Max. prenos rychlost je 115200 b/s.
private bool continueRead = true;
public override void Run()
{
while (continueRead)
{
try
{
int readBytes = 0;
lock (InternaldataReadLock)
{//Quick reads data into bigger InternaldataRead buffer and next move only "received bytes" readBytes into TempdataRead buffer
readBytes = clientSocketInStream.Read(InternaldataRead, 0, InternaldataRead.Length);
Array.Copy(InternaldataRead, TempdataRead, readBytes);
}
if (readBytes > 0)
{//If something reads move it from TempdataRead into main dataRead buffer a send it into MainThread for processing.
lock (dataReadLock)
{
dataRead = new byte[readBytes];
for (int i = 0; i < readBytes; i++)
{
dataRead[i] = TempdataRead[i];
}
}
Bundle dataBundle = new Bundle();
dataBundle.PutByteArray("Data", dataRead);
Message message = btlManager.sourceHandler.ObtainMessage();
message.What = 1;
message.Data = dataBundle;
btlManager.sourceHandler.SendMessage(message);
}
}
catch (System.Exception e)
{
if (e is Java.IO.IOException)
{
//.....
}
}
}
}
I want to connect my Nexus 7 device with my Nexus 4 device and later i want to connect my Nexus 7 device with a micro controller. Do i have to know the UUID of my devices to connect them using bluetooth?
Are the UUID's being exchanged when i pair my devices?
If yes: Why is there a defined UUID in android example?
public class BluetoothService extends Thread {
private static final String TAG = BluetoothService.class.getSimpleName();
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
private BluetoothAdapter bluetoothAdapter = null;
private Handler handler = null;
private ConnectThread connectThread = null;
private ConnectedThread connectedThread = null;
private int bluetoothState = STATE_NONE;
public BluetoothService(Handler handler) {
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.bluetoothState = STATE_NONE;
this.handler = handler;
}
public synchronized void startConnection() {
Log.d(TAG, "start");
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.setBluetoothState(STATE_LISTEN);
}
public synchronized void connect(BluetoothDevice device) {
if (this.bluetoothState == STATE_CONNECTING) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.connectThread = new ConnectThread(device);
this.connectThread.start();
this.setBluetoothState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.connectedThread = new ConnectedThread(socket);
this.connectedThread.start();
Message msg = this.handler.obtainMessage(Globals.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Globals.DEVICE_NAME, device.getName());
msg.setData(bundle);
this.handler.sendMessage(msg);
this.setBluetoothState(STATE_CONNECTED);
}
public synchronized void stopConnection() {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.setBluetoothState(STATE_NONE);
}
public void write(byte[] out) {
ConnectedThread connectedThread = null;
synchronized (this) {
if (this.bluetoothState != STATE_CONNECTED) {
return;
}
connectedThread = this.connectedThread;
}
connectedThread.write(out);
}
private void connectionFailed() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Unable to connect device");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.startConnection();
}
private void connectionLost() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Device connection was lost");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.startConnection();
}
public synchronized int getBluetoothState() {
return this.bluetoothState;
}
private synchronized void setBluetoothState(int bluetoothState) {
this.bluetoothState = bluetoothState;
}
private class ConnectThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private BluetoothDevice bluetoothDevice = null;
public ConnectThread(BluetoothDevice bluetoothDevice) {
this.bluetoothDevice = bluetoothDevice;
BluetoothSocket tempBluetoothSocket = null;
try {
tempBluetoothSocket = this.bluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + "create() failed", e);
}
this.bluetoothSocket = tempBluetoothSocket;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
this.setName("ConnectThread");
bluetoothAdapter.cancelDiscovery();
try {
this.bluetoothSocket.connect();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
connectionFailed();
try {
this.bluetoothSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
return;
}
synchronized (BluetoothService.this) {
connectThread = null;
}
connected(this.bluetoothSocket, this.bluetoothDevice);
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
public ConnectedThread(BluetoothSocket bluetoothSocket) {
Log.d(TAG, "create ConnectedThread");
this.bluetoothSocket = bluetoothSocket;
InputStream tempInputStream = null;
OutputStream tempOutputStream = null;
try {
tempInputStream = this.bluetoothSocket.getInputStream();
tempOutputStream = this.bluetoothSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
this.inputStream = tempInputStream;
this.outputStream = tempOutputStream;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes = 0;
while (true) {
try {
bytes = this.inputStream.read(buffer);
handler.obtainMessage(Globals.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
BluetoothService.this.start();
break;
}
}
}
public void write(byte[] buffer) {
try {
this.outputStream.write(buffer);
handler.obtainMessage(Globals.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
If no: How to exchange the UUID's to be able to connect the devices?
The UUID defined in the google sample/example must be known by the server and the client :
The server create a RFcomm ServerSocket that listen for incoming connection with this UUID
The client create a RFcomm bluetoothsocket that will try to connect to the server socket
if the uuids matches the connection is established.
The pairing saves the informations about the remote device (name, adress, ... etc) so that when you want to connect again you don't have to search for the device to get them =)
I am trying to connect bluetooth device and want to send data to that device and also want to receive data from that device.
To achieve this I follow android developer bluetooth document but seems I unable to connect another device because while connecting it's throwing following exception.
09-13 13:27:56.913: I/BluetoothConnect(2980): Connect exception:-java.io.IOException: [JSR82] connect: Connection is not created (failed or aborted).
Steps which I follow.
Enabling Bluetooth
Intent turnOnIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOnIntent, REQUEST_ENABLE_BT);
Getting Bluetooth Paired Device
Set<BluetoothDevice> bondSet = myBluetoothAdapter.getBondedDevices();
ArrayList<HashMap<String, String>> bondedhDevicesList = new ArrayList<HashMap<String, String>>();
for (Iterator<BluetoothDevice> it = bondSet.iterator(); it.hasNext();) {
BluetoothDevice bluetoothDevice = (BluetoothDevice) it.next();
HashMap<String, String> map = new HashMap<String, String>();
map.put("name", bluetoothDevice.getName());
map.put("address", bluetoothDevice.getAddress());
bondedhDevicesList.add(map);
}
Getting UUID of device
bluetoothDevice =
myBluetoothAdapter.getRemoteDevice(address);
// min api 15 !!!
Method m;
try {
m = bluetoothDevice.getClass().
getMethod("fetchUuidsWithSdp", (Class[]) null);
m.invoke(bluetoothDevice, (Object[]) null );
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Connecting to device
private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
public ConnectThread(BluetoothDevice device, String uuid, BluetoothAdapter mBluetoothAdapter) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
this.mBluetoothAdapter = mBluetoothAdapter;
mmDevice = device;
Method m;
try {
mBluetoothAdapter.cancelDiscovery();
mmSocket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID);
m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] {int.class});
mmSocket = (BluetoothSocket) m.invoke(device, 1);
} catch (IOException | IllegalArgumentException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
// TODO Auto-generated catch block
Log.i("BluetoothConnect", e.toString());
e.printStackTrace();
}
//mBluetoothAdapter.cancelDiscovery();
//socket.connect();
}
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();
Constants.globalSocket = mmSocket;
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
Log.i("BluetoothConnect", "Connect exception:-"+connectException.toString());
try {
mmSocket.close();
} catch (IOException closeException) {
Log.i("BluetoothConnect", "close exception:-"+closeException.toString());
}
return;
}
}
But while connecting then i am getting that exception.
5. Writing to device.
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
CreatePacket.mHandler.obtainMessage(MESSAGE_READ , bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.i("ConnectedThread", "while receiving data:-"+e.toString());
break;
}
}
}
public void write(byte[] bytes) {
Log.i("ConnectedThread", "data while writing:-"+bytes.toString());
try {
mmOutStream.write(bytes);
} catch (IOException e) {
Log.i("ConnectedThread", "while writing data to bluetooth:-"+e.toString());
}
}
If I still try to write then data then I am getting following exception.
Please give me any hint or reference.
09-13 13:48:55.079: I/ConnectedThread(2980): while writing data to bluetooth:-java.io.IOException: socket closed
I am stuck on this from last three day but still not getting any solution.
The best way is to refer the sample chat application provided by the Android. That has covered all necessary tasks like list out available devices, establish connection, send data and receive, etc. U can get that and refer.
https://android.googlesource.com/platform/development/+/eclair-passion-release/samples/BluetoothChat
Here is a sample code which I am using to connect to my Bluetooth module..
public class OpenBluetoothPort extends AsyncTask<String, Void, BluetoothSocket> {
private final UUID SPP_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private BluetoothAdapter mBluetoothAdapter;
private OnBluetoothPortOpened mCallback;
private BluetoothSocket mBSocket;
public interface OnBluetoothPortOpened {
public void OnBluetoothConnectionSuccess(BluetoothSocket socket);
public void OnBluetoothConnectionFailed();
}
public OpenBluetoothPort(Context context, OnBluetoothPortOpened callback) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mCallback = callback;
}
#Override
protected BluetoothSocket doInBackground(String... params) {
if(mBluetoothAdapter.isEnabled()) {
try {
for(BluetoothDevice bt: mBluetoothAdapter.getBondedDevices()) {
if(bt.getName().equalsIgnoreCase(params[0])) {
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(bt.getAddress());
mBluetoothAdapter.cancelDiscovery();
mBSocket = device.createRfcommSocketToServiceRecord(SPP_UUID);
mBSocket.connect();
return mBSocket;
}
}
} catch(IOException e) {
if(mBSocket != null) {
try {
mBSocket.close();
} catch (IOException e1) {
Log.i("Bluetooth Close Exception","Error in closing bluetooth in OpenBluetoothPort.class");
e1.printStackTrace();
}
mBSocket = null;
}
Log.i("Bluetooth Connect Exception","Error in connecting in OpenBluetoothPort.class");
e.printStackTrace();
return null;
}
}
return null;
}
#Override
protected void onPostExecute(BluetoothSocket result) {
super.onPostExecute(result);
if(result != null && result.isConnected()) {
mCallback.OnBluetoothConnectionSuccess(result);
} else {
mCallback.OnBluetoothConnectionFailed();
}
}
}