I'm trying to connect my Android app with a Bluetooth (classic) peripheral.
After finding the device through a scan, I create a BluetoothSocket without problems. However, mySocket.connect() blocks forever.
public void run(BluetoothAdapter mBluetoothAdapter) {
// Cancel discovery because it otherwise slows down the connection.
mBluetoothAdapter.cancelDiscovery();
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mySocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mySocket.close();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
}
Why a connection timeout error is not thrown?
PS: both my app and the peripheral make use of the default UUID ("00001101-0000-1000-8000-00805F9B34FB"), so this should not be my problem.
Related
I deal with a thesis on the topic "car diagnostics via bluetooth". However, now I'm stuck in the problem. I have application, which can connect bluetooth to mobile (from tablet - android to android). Its ok state is CONNECT. But when I tried to connect to the OBD adapter. It was unsuccessful.
Trying to connect approximately this way:
public void run() {
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
connectException = connectException;
mHandler.obtainMessage(NOT_CONNECT).sendToTarget();
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
}
Please can you advise me also how to create a valid AT command, which is then queries the OBD adapter?
Thank you for helps!
I have created one android Bluetooth program which communicates with serial port. In my program I have 3 buttons: Connect, Select & Disconnect. Connect is used for enabling Bluetooth. Select is used for retrieving data from serial port. Disconnect is for disconnecting Bluetooth and the socket which I obtained to retrieve data, and to initialize the socket as null.
btnDisConnect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try{
mBluetoothAdapter.disable();
mmSocket.close();
mmSocket=null;
} catch(Exception e) {
Toast.makeText(getApplicationContext(), "Unable to Close.Try again", Toast.LENGTH_LONG).show();
}
}
});
My problem is when I tried to initialize the socket as null it shows Null Pointer exception.
I want to make this socket as null for further work. How can I make it null on buttonclick?
Please remember to close your Input/output streams first, then close the socket.
By closing the streams, you kick off the disconnect process. After you close the socket, the connection should be fully broken down.
If you close the socket before the streams, you may be bypassing certain shutdown steps, such as the (proper) closing of the physical layer connection.
Here's the method I use when its time to breakdown the connection.
/**
* Reset input and output streams and make sure socket is closed.
* This method will be used during shutdown() to ensure that the connection is properly closed during a shutdown.
* #return
*/
private void resetConnection() {
if (mBTInputStream != null) {
try {mBTInputStream.close();} catch (Exception e) {}
mBTInputStream = null;
}
if (mBTOutputStream != null) {
try {mBTOutputStream.close();} catch (Exception e) {}
mBTOutputStream = null;
}
if (mBTSocket != null) {
try {mBTSocket.close();} catch (Exception e) {}
mBTSocket = null;
}
}
I am writing a program for a new vehicle security app. the app allows the user to control lock/unlock operations via his phone app. Lets say the user's phone Bluetooth is switched off at first. If that's the case, when he opens the app, the phone bluetooth adapter should be automatically switched on and should connect with the bluetooth module fixed in to the vehicle.
according to the code I have done, the programatic enabling of the BT adapter of phone works fine. But the connection to the vehicle BT module does NOT happen.
But if the user opens the app while the phone BT adapter is already switched on, then the connection establishing between the vehicle and phone happens automatically.
I need to know why the connection does NOT happen when the BT adapter is turned on programmatically.
Note - the phone and the vehicle BT module is paired. The bluetooth modules mac address is hard coded in the coding.
The coding is as follows. I only pasted the necessary parts. I hope every needed to understand and solve my problem is here. The way I posted the code is pretty messed up. Sorry about that. Hope it's clear. I'm new to this.
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Insert bluetooth devices MAC address
private static String address = "00:19:5D:EF:03:79";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btAdapter = BluetoothAdapter.getDefaultAdapter();
btAdapter.enable();
#Override
public void onResume() {
super.onResume();
btAdapter.enable();
// 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 = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
// Make sure Discovery isn't going on when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
try {
btSocket.connect();
} 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.
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
}
}
There might be a timing problem, onCreate and onResume are called in very short order. In the case that the BT is not enabled the code in onResume might be called before the BT service is online.
My advice: Try to delay the initiation a few seconds by putting the code in a Runnable.
private Handler mHandler = new Handler();
public void onCreate() {
[...]
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
btAdapter.enable();
// 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 = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
// Make sure Discovery isn't going on when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
try {
btSocket.connect();
} 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.
try {
outStream = btSocket.getOutputStream();
} catch (IOException e) {
errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
}
}, 5000); // 5 second delay
[...]
Caveats: This works really bad if you exit the app promptly after startup. Put the runnable in a member variable and call mHandler.removeCallback(Runnable) in onDestroy().
I'm trying to establish a bluetooth communication between an android phone/tablet (4.0.3), and a bluetooth device, which is an earring reader (Destron Fearring DTR3E, in case you want to know, which I don't suppose you do).
I paired the phone with the reader (the reader has the pairing passcode on a tag) from the bluetooth settings, bluetooth is on of course, and now I'm trying to listen to reads from the device, by means of BluetoothServerSocket. The problem is that the accept call never returns, so obviously I am doing something wrong. The communication is done using RFCOMM.
Code:
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
String uuid = "00001101-0000-1000-8000-00805F9B34FB";
tmp = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("pdfParserServer", UUID.fromString(uuid));
} catch (Exception e) {
e.printStackTrace();
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
try {
mmServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}
Is there something I am missing?
Thank you!
The only reason that could cause the code never to come back from accept is that, the device "Destron Fearring DTR3E" you are trying to connect to, has actually a bluetoothserver socket and not a bluetooth client, hence, the device might be waiting for you to actually connect to it, in stead of you creating a bluetoothserver socket and waiting for it to connect to your android device, you should read the specs on the device and make sure that actually is you the one that has to open a connection on "Destron Fearring DTR3E" socket...
Hope this helps...
Regards!
I am trying to connect a bluetooth device from the Android phone. In most cases, the connection is successful.
I am making the socket connection using the following code:
if (isUsingHtcTypeConnectionScheme) {
try {
if (LOG_ENABLED) Log.d(TAG,"connecting to SPP with createRfcommSocket");
Method m = mRemoteDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
tmpSocket = (BluetoothSocket)m.invoke(mRemoteDevice, 1); // may be from 1 to 3
} catch (java.lang.NoSuchMethodException e){
Log.e(TAG, "java.lang.NoSuchMethodException!!!", e);
} catch ( java.lang.IllegalAccessException e ){
Log.e(TAG, "java.lang.IllegalAccessException!!!", e);
} catch ( java.lang.reflect.InvocationTargetException e ){
Log.e(TAG, "java.lang.InvocationTargetException!!!", e);
}
}
if (tmpSocket == null) {
try {
if (LOG_ENABLED) Log.d(TAG,"connecting to SPP with createRfcommSocketToServiceRecord");
tmpSocket = mRemoteDevice.createRfcommSocketToServiceRecord(uuid); // Get a BluetoothSocket for a connection with the given BluetoothDevice
} catch (IOException e) {
Log.e(TAG, "socket create failed", e);
}
}
mBtSocket = tmpSocket;
try {
mBtSocket.connect();
} catch (IOException e) {
connectionFailed();
setState(STATE_IDLE);
return;
}
And if the other device's bluetooth is not on, it will throw the IOException in 2-3 seconds, this is the normal behavior.
But sometimes the connection takes 20-30 seconds and eventually failed, and the other device's bluetooth is on.
I am wondering why this happens, if the phone cannot connect to device, it should throw IOException in 2-3 seconds. But now is taking 20-30 seconds to throw the IOException. (And the other device is ready for connection actually)
I tested on several Android phones and also have this problem, so may not be related to specific phone.
Any ideas?
Thanks!