I have the need to detect if a certain mac address is connected or in range, if it is then my app assumes that you are for example at home or in your car.
From my reading on the Bluetooth docs, it all seems more to scan and try pair / connect with new devices. I don't want to do this, Just detect if a device is in range or connected. I will know the mac address up front.
for example:
if(BluetoothAdapter.IsConnectedTo("MAC ADDRESS"))
{
Toast.makeText(this,"You are in your car",Toast.Short).show();
}
In other questions they say I should set a broadcast intent for onConnected and on disconnect. However this will only trigger when connecting, This wont help me if the device is already connected.
The other option they scan for discover-able devices, But this does not show me if the phone is currently connected to that specific device?
Related
I used "createBond" method to pair my phone and my device with BLE.it succeed.but I took my phone away from the device at a distance, about 10 meters.My app received the broadcast: BluetoothDevice.ACTION_BOND_STATE_CHANGED, and the device status is became BluetoothDevice.BOND_NONE. Is it normal or something wrong?
after my app receive the broadcast I will unpaired the device.because I think the device is unpaired manually by user from setting activity.
10 meters is a normal range for a BLE device. You got too far from it so you couldn't maintain a connection. This is normal. With some devices the distance will be even shorter (perhaps 5m).
BluetoothDevice.BOND_NONE broadcast when phone is away from the paired device at a distance is not normal I guess.
Yes, the disconnection from the paired device when you're out of the bluetooth range is normal, but, as I said earlier in the comment, pairing and connectivity are two different things. The BLE might not be connected but, it can be shown in the paired list of Android once its paired.
And another interesting thing what I want to share in this case is, the bluetooth devices which are already paired once with an Android, are somehow remembered in Android device even if you un-pair them. I had this tested for some of my personal projects.
I am trying to achieve the following :
Select a device from the scan results of BluetoothLeScan.
Trying to connect to this device using BluetoothGatt.connect()
Once the connection has been established, I try to createBond with the connected device as well.
When this bond process is initiated I exchange the pin programmatically.
Once this pin is exchanged with the peripheral device, I setPairingConfirmation(true) to dismiss the enter pin dialog.
Problem - This doesn't work always. The pin isn't always exchanged successfully. Although the pin is written to the bluetooth stack successfully, but the pin received by the peripheral device is not the same. For some manufacturers like Samsung this problem has lower reproducibility but for others like iBall, this is 100% reproducible.
Please suggest
my app shall connect to a Bluetooth LE device. Usually you perform a device scan using mBluetoothAdapter.startLeScan(mLeScanCallback);. The callback provides you information about available devices.
If you want to connect to a dedicated device, you do something like
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
and then
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
To me it looks like the only thing you need to connect to a BLE device, is to know the BLE address and then connect to it with the above two steps. So if I know a BLE address already (e.g. it is written on the label of the BLE device) I don’t need to perform a BLE scan.
But what I have encountered is, that if I have a BLE device which I have never found through a BLE scan before, it is not possible to connect to it directly in using its BLE address. I have to find it through a scan at least one time with my android phone. Afterwards I never need a scan again and I can connect to the BLE device just by using its BLE address.
Is it supposed to be like this or did I oversee something?
Thanks a lot,
Stefan
The device address is merely a unique identifier for the bluetooth device, it doesn't contain the information for connection. The scan is necessary to retrieve the information within the broadcast signal from the bluetooth device so that a connection can be made. Once the scan is done, the information is saved somewhere on the device and bound to the device address.
I think if you try to retrieve the value for the bluetooth address it will return null until after it has been scanned once.
The answer from Hoa Do is not really correct.
Due to some horrible design flaws in Android's BLE API there is no way to tell it if you mean the given address is a Public Address or a Random Address. (You can read more about different address types at https://devzone.nordicsemi.com/question/43670/how-to-distinguish-between-random-and-public-gap-addresses/). The getRemoteDevice method should take an additional parameter "random address/public address" but it doesn't. Without the correct address type, the Bluetooth controller cannot connect to the device.
Android's BLE stack has some internal heuristics to "guess" if the address is public or random, but unfortunately that differs between Android versions and also if you use autoConnect=true or false. However if you have bonded the device (https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#createBond()) then it will store in its internal DB whether the given address is public or random. If the peripheral you want to connect to uses a random resolvable address it can handle that as well if you use bonding. Therefore I strongly suggest to use bonding.
If you don't use bonding you will need to scan before you connect to the device, since when you start a scan and a device is detected, Android's BLE stack will temporarily (until next restart of Bluetooth) remember the address type for an address. If you don't scan the device before connecting, it will still try to connect, but there is a possibility it tries to connect with the wrong address type and hence fail.
Many years have passed since this was first asked and I was able to make the following work. My device does not have a random address so if you know this about your device then the following should work fine.
// perform scan, get device and store address somewhere
// like in shared preferences
String bleAddress = bluetoothDevice.getAddress();
this.getSharedPreferences("myPrefs", MODE_PRIVATE).edit().putString("BLE_ADDRESS",bleAddress .apply();
// next time no need to scan, just get the remote device
// from the bluetoothAdapter and connect.
String address = this.getSharedPreferences("myPrefs", MODE_PRIVATE).getString("BLE_ADDRESS",null);
if (address != null) {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(ble_address)
device.connectGatt(context, false, this, BluetoothDevice.TRANSPORT_LE);
}
Hi I am working with embedded bluetooth device connection with my android application.
My application is installed in Android phone and phone has some paired bluetooth devices, Now I want that if any paired bluetooth device is enabled(starts/turns on) the application should receive notification.
of-course bluetooth will be enabled in phone and bluetooth devices will be within range.
please let me know How this is possible ?
Thanks!
How about using http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#ACTION_CONNECTION_STATE_CHANGED
To check all changed states and then comparing what the new state is:
STATE_DISCONNECTED, STATE_CONNECTING, STATE_CONNECTED etc.
There is nothing automatic that can detect this, you will have to make both your App and the paired device do some work to detect this. TYhere could be 2 options :
Your app could do some periodic device discovery (low frequency - else it will kill the battery) to search for the paired devices in vicinity.
The paired devices on getting enabled / starting on should put itself to be discoverable.
A better way is for the apired device to autimaically initiate a connection once it comes on to the device it was paired with, and typically on most phones by default if Bluetooth is turned on its also scanning for incoming connection , so your app can be ready to accept incoming connections.
This question already has answers here:
How can I programmatically tell if a Bluetooth device is connected?
(7 answers)
Closed 10 years ago.
I have already discovered the other device and I have already paired it. At least I have it in the list of paired devices on my Android phone.
Now on BluetoothSocket.connect() two problems can occur:
The remote device is switched off or otherwise unavailable
The remote device forgot about the pairing because it can only pair one other device and has been paired with a different phone
=> Then connect fails after a certain timeout.
Is it possible to check that an already paired device is really available and remembers that it was paired with my phone without connecting to it? This is not about detecting if a device is connected. Paired and visible is not the same as connected.
I'm sorr t report but there's no way for your device to know another is in range except by attempting to connect to it. And, to know if the remote device has removed the pairing one would have to ask it, e.g. connect and see if it asks for pairing then.
Other ways would be get the user to confirm these before connecting, or maybe use an external channel TCP/IP or WiFi or NFC. If none of those then magical powers would be the only alternative. :-,)
Remembering the device that was connected is actually kinda simple. Once you have a successful bind to a device you get BluetoothDevice object. you can inquire it's unique mac address with getAddress(). Once you have the address save it to a shared preference. this covers the "was it paired" - the next time we use the BluetoothAdapter and receive the list of bound devices we can search for the saved device address among them.
Now that we know the exact address of the device, how can we tell if it's "really available" ? Well, if it's enough for you to try and discover the device (startDiscovery ()) to check if it's available in the "discover" level - then you know the trick (list item 1). If you found out the device is discoverable and you need to test the device for full connectivity you'll have to open a new socket and see if it goes smooth.
In my experience I treat 3 different possible BT device situations:
Device not bound
Device bound - but not connected
Device bound - and connected
You can get an already paired device list and cross verify them with current discoverable devices.So this will give you already paired devices those are in discoverable mode.
But for undiscoverable devices compulsory you have to connect with them. Try to create socket connection between them if data successfully sent remote device is active.
Also you can use getBondState () of remote device to check bonded state and register ACTION_BOND_STATE_CHANGED receiver for getting callback of bonded state changes.