BLE - First connection with app is not working - android

I'm working with device Texas, for management of the LED, in my custom Android app. The device has enabled the pairing with a default passkey 000000. In my code for app, I have this part of code for reading the paired of device.
private void getpaireddevices(){
Set<BluetoothDevice> devicesArray = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
if(devicesArray.size() > 0) {
for(BluetoothDevice device : devicesArray) {
device.getName();
device.getAddress();
}
}
}
In this moment, when I enable the BLE the app found the device, it connect but not works. For this to work I should exit and reconnect with my device. Why?

This is possible if the device is already bonded. Call removeBond() method to clear previous bonding state.
device.removeBond();
For check bonding state of BluetoothDevice, use getBondState().
Ble gatt connection success rate is different per device by device. You may need disconnect ble by hidden method, if your connection fails continuously.
Please read this:
BLE Device Bonding Remove Automatically in Android
The method unpairDevice() will unpair bluetooth connection.
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
for (BluetoothDevice bt : pairedDevices) {
if (bt.getName().contains("String you know has to be in device name")) {
unpairDevice(bt);
}
}
// Function to unpair from passed in device
private void unpairDevice(BluetoothDevice device) {
try {
Method m = device.getClass().getMethod("removeBond", (Class[]) null);
m.invoke(device, (Object[]) null);
} catch (Exception e) { Log.e(TAG, e.getMessage()); }
}

Related

Android bluetooth connection to ELM327/OBD2 device

I tried to create a simple android application to connect to my ELM327 device to get some car diagnostic data. But I wasn't able to set up the bluetooth connection b/t my android phone and my ELM327 device.
My code is very simple as below:
public class Bluetooth {
protected BluetoothAdapter mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
private ConnectThread mConnectThread = null;
private AcceptThread mAcceptThread = null;
private WorkerThread mWorkerThread = null;
private BluetoothDevice mOBDDevice = null;
private BluetoothSocket mSocket = null;
private String uuid;
Bluetooth() {
mBluetoothAdapter= BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices;
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled())
return;
pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
// There are paired devices. Get the name and address of each paired device.
for (BluetoothDevice device : pairedDevices) {
String deviceName = device.getName();
String deviceHardwareAddress = device.getAddress(); // MAC address
//TODO: check whether this is OBD and whether it is connected
//by sending a command and check response
if (deviceName.contains("OBD")) {
mOBDDevice = device;
uuid = device.getUuids()[0].toString();
break;
}
}
}
mBluetoothAdapter.cancelDiscovery();
}
/**
* Start the chat service. Specifically start AcceptThread to begin a session
* in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void connect()
{
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
mSocket = mOBDDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and return.
try {
mSocket.close();
} catch (IOException closeException) {
Log.e(TAG, "Could not close the client socket", closeException);
}
return;
}
}
}
In the mainactivity, I will first new a Bluetooth class then call bluetooth.connect():
mBluetooth = new Bluetooth();
mBluetooth.connect();
When I debug the program, I was able to get my ELM327 bluetooth device by querying all the bonded devices with a name of "OBD". I also was able to get the device's uuid and create a socket using createRfcommSocketToServiceRecord. But in the connect function, mSocket.connect() always fail with a return value of -1 and get a IOexception.
My questions are:
When my android application connect to the ELM327 device, my android phone is the bluetooth client and my ELM327 device is the bluetooth server, is this understanding correct?
Is there a server program running on my ELM327 device listening and accept incoming connection? Is this defined behavior of ELM327 protocol?
Any idea why mSocket.connect()has failed? Any idea on how to look into this issue? Or any obvious error in my program? Thanks.
problem solved. see source codes below:
public synchronized void connect() throws IOException {
try {
// Get a BluetoothSocket to connect with the given BluetoothDevice.
// MY_UUID is the app's UUID string, also used in the server code.
mSocket = mOBDDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
} catch (IOException e) {
Log.e(TAG, "Socket's create() method failed", e);
}
try {
// Connect to the remote device through the socket. This call blocks
// until it succeeds or throws an exception.
mSocket.connect();
} catch (IOException e1) {
Log.e(TAG, "There was an error while establishing Bluetooth connection. Falling back..", e1);
Class<?> clazz = mSocket.getRemoteDevice().getClass();
Class<?>[] paramTypes = new Class<?>[]{Integer.TYPE};
try {
Method m = clazz.getMethod("createRfcommSocket", paramTypes);
Object[] params = new Object[]{Integer.valueOf(1)};
mFallbackSocket = (BluetoothSocket) m.invoke(mSocket.getRemoteDevice(), params);
mFallbackSocket.connect();
mSocket.close();
mSocket = mFallbackSocket;
} catch (Exception e2) {
Log.e(TAG, "Couldn't fallback while establishing Bluetooth connection.", e2);
mSocket.close();
//throw new IOException();
}
}
inputStream = mSocket.getInputStream();
outputStream = mSocket.getOutputStream();
}
I don't know much about Android, although I know about OBD2 and the lot.
It depends on the type of your adapter. If you have a WiFi adapter, you can consider the adapter being the server and you the client. You connect to a socket and then read from it. In the case of a Bluetooth adapter, it's different. If you connect via rfcomm, it's a serial protocol and neither is the server nor the client. If you connect via BTLE, the OBD2 dongle is the Peripheral and you are the Central.
On WiFi adapters, yes. This behavior is not part of ELM327 though. ELM327 only specifies the serial commands. How you transfer these is not part of the spec, since it happens on the layer above (WiFi, rfcomm, BTLE, USB, etc.).
Are you sure that rfcomm works via the socket interface? It's a serial interface, so I would have expected file-like operations.

Android: Disconnect bluetooth headset to connect my SPP app using bluetooth

I have a SPP Bluetooth app, the problem is this case.
The android device is connected to a Bluetooth Speaker, when i try to connect to my SPP Micro device i can't for the same reason the Bluetooth is already connected.
How i can disconnect the Bluetooth Speaker from my App so i can connect to my SPP micro device after the disconnection.
Thanks!
UPDATE:
Sorry, i forget to specify, the connection to the Bluetooth speaker is made before opening my app, its already connected to the speaker when i open my app and i want to disconnect the bluetooth speaker from my app that didn't connect to the bluetooth speaker and with my app close that connection
You need to manually disconnect your device by closing the socket
You need to check, If the devices are connected. If yes, call reset function
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
resetConnection
}
ResetConnection function definition.
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;
}
}
Edit 1
You will have to create a new BluetoothSocket and then call this method getRemoteDevice().
getRemoteDevice ()
Added in API level 5
Get the remote device this socket is connecting or connected to.
Here is a link to Documentation BluetoothSocket

Connect bluetooth with getRemoteDevice() from BluetoothAdapter

I would like to manually connect a bluetooth device with its MAC address because it is faster and I know exactly which MAC to connect.
I use this method to get the BluetoothDevice : http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getRemoteDevice%28byte[]%29
But the Android doc does not say if Android ensure that the device is in range before creating the BluetoothDevice object.
Do you have this information ?
My code can automatically connect the device, and I would like to check if the target is in range before trying to connect, but without perform a large scan (which can be long...)
When local device connects to remote device using BluetoothSocket, an exception is required.
If remote device isn't in range, It's not found
private class ConnectThread extends Thread {
public ConnectThread(BluetoothDevice device, boolean isSecure, UUID sharedUUID) throws IncorrectSetupException {
try {
//Secure connections requires to get paired before connect
//Insecure connections allows to connect without pairing
if (isSecure) {
mSocket = device.createRfcommSocketToServiceRecord(sharedUUID);
} else {
mSocket = device.createInsecureRfcommSocketToServiceRecord(sharedUUID);
}
} catch (IOException e) {
//Is there some problem with the setup?
}
}
public void run() {
try {
mSocket.connect();
} catch (IOException e) {
//If device is not found, this exception is throwed
}
}
}

Monitoring the connection of a paired bluetooth device

I have written the code which returns me a list of all the paired bluetooth devices of a android device.One among the list of paired bluetooth devices is my laptop as well.
Now my question is
Is there a way I can monitoring the bluetooth connectivity status between the laptop and the android device.The output which I need is "Connected" if there is a bluetooth connection present and "Disconnected" if there is no bluetooth connection
The android version is 2.1.Eclair
Before I proceed further , I have some questions.
->Should I test this application when I connect the laptop and device through USB?
->How to run it on a separate thread or from an AsyncTask?
->The above code is not working for me if I connect the device and the laptop through USB and then launch the application. Even though the laptop and the phone are nearby and they are paired, I am not able to see a connected status in the phone.
The code which I have written is as follows
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth_);
out = (TextView) findViewById(R.id.textView1);
// Getting the Bluetooth adapter
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
// out.append("\nAdapter: " + adapter);
// Check for Bluetooth support in the first place
// Emulator doesn't support Bluetooth and will return null
if (adapter == null) {
out.append("\nBluetooth NOT supported. Aborting.");
return;
}
// Starting the device discovery
out.append("\nStarting discovery...");
adapter.startDiscovery();
out.append("\nDone with discovery...");
// Listing paired devices
out.append("\nDevices Pared:");
Set<BluetoothDevice> devices = BluetoothAdapter.getDefaultAdapter()
.getBondedDevices();
for (BluetoothDevice device : devices) {
out.append("\nFound device: " + device);
out.append("\n The name is: " + device.getName());
out.append("\n The type is: "
+ device.getBluetoothClass().getDeviceClass());
Method m;
try {
System.out.println("Trying to connect to " + device.getName());
m = device.getClass().getMethod("createInsecureRfcommSocket",
new Class[] { int.class });
BluetoothSocket socket = (BluetoothSocket) m.invoke(device, 1);
socket.connect();
out.append("Connected");
} catch (Exception e) {
e.printStackTrace();
out.append("\nDisconnected");
}
}
}
Which android version you are using?
You must have the permission on your AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
You can try the code below, but be sure to run it on a separate thread or from an AsyncTask or your UI can hang up.
This will check for your paired devices and try to connect to each one. If it is successful then it prints Connected on logcat or else it prints Disconnected.
private void checkPairedPrinters() throws IOException {
Set<BluetoothDevice> devices = BluetoothAdapter.getDefaultAdapter().getBondedDevices();
for (BluetoothDevice device : devices) {
Method m;
try {
System.out.println("Trying to connect to " + device.getName());
m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] { int.class });
BluetoothSocket socket = (BluetoothSocket) m.invoke(device, 1);
socket.connect();
System.out.println("Connected");
} catch (Exception e) {
e.printStackTrace();
System.out.println("Disconnected");
}
}
}

How to detect hands free garniture on Android 2.2+?

I want to know when user has connected hands free accessories and hasn't blocked calls\sms. Is it possible to know when it is connected via hardware ports or bluetooth?
Try this in your onCreate or onResume.
BluetoothAdapter myLocalAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice garniture;
Set<BluetoothDevice> connectedDevices = myLocalAdapter.getBondedDevices();
for (BluetoothDevice device : connectedDevices){
String name = device.getName();
//... check for the name you want
if( name.equals("whatnameisit"){
garniture = device
}
}
if (garniture != null){
// yay we found it, lets do our work with the device here
}

Categories

Resources