what is Bluetooth low energy in android.I know how to connect two devices using Bluetooth. But i don't know How to connect two android device using Bluetooth low energy.
If you wanna get a list of Bluetooth LE (Low Energy) devices. You need to use the Bluetooth LE scanning API's.
If you are supporting API's lower than 21 (above 18, though) you should use the startLeScan() to discover LE devices. When on API level 21 and above, you get access to a more robust and powerful scanning API that allows you to customize the devices returned back based on Services available, device name, MAC address and such. Instead of calling startLeScan on the BluetoothAdapter, you'd call startScan() on a BluetoothLeScanner object that you'd get from BluetoothAdapter via a call to getBluetoothLeScanner().
When using either API, you must have BLUETOOTH_ADMIN permission. You most also hold the at least one of the following location permissions, ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION when running on API 21 and above.
To connect to an LE device you simply need to call connectGatt() on a LE BluetoothDevice. You can check if a BluetoothDevice is an LE device by calling getType() which returns a int constant that represents one of the various bluetooth device types android supports.
If you want to connect two device using bluetooth low energy then you need to make one device as a simulator same as BLE device, like your device one is advertising and In second device you need to scan that device and connect that device and now your both device is connected. you can send and receive data.
For Bluetooth advertising :
refer this link : - https://developer.android.com/reference/android/bluetooth/le/BluetoothLeAdvertiser
Related
https://developer.android.com/guide/topics/connectivity/bluetooth-le#roles
Central vs. peripheral. This applies to the BLE connection itself. The
device in the central role scans, looking for advertisement, and the
device in the peripheral role makes the advertisement.
To check if a device supports "peripheral"/advertisement mode it looks as though I can use getBluetoothLeAdvertiser()
getBluetoothLeAdvertiser
added in API level 21 public
BluetoothLeAdvertiser getBluetoothLeAdvertiser () Returns a
BluetoothLeAdvertiser object for Bluetooth LE Advertising operations.
Will return null if Bluetooth is turned off or if Bluetooth LE
Advertising is not supported on this device.
Use isMultipleAdvertisementSupported() to check whether LE Advertising
is supported on this device before calling this method.
Now I've heard some rumors that some devices can actually give you a BluetoothLeAdvertiser, but return false on isMultipleAdvertisementSupported() which is another issue in itself, but on the central side of things, the docs don't say anything!
Am I missing something? https://developer.android.com/reference/android/bluetooth/BluetoothAdapter doesn't say anything about central mode. Am I missing something basic here? Thanks for any help. I have heard bluetooth is a pain on Android and it is my first day exploring these APIs.
Short Answer
As DigitalNinja pointed out, an Android phone will always support Central role functionality by default, so if your phone supports BLE, then it can definitely operate in the central Role
Long Answer
You're right, the API might not be straight-forward but this is down to how Bluetooth Low Energy (BLE) API was added to Android and even down to the history of BLE technology itself.
When BLE was first introduced, it was aimed to be for sensors only (e.g. thermometer, heart rate, proximity, etc) and devices that talk to these sensors. The sensors were the peripherals in this case, and the devices that talk to these sensors are the centrals. The peripherals were the true Low Energy (LE) devices, as they would just advertise and send data once in a while. Centrals on the other hand would not be very power efficient as they would have to continuously scan for devices, connect to these devices, and remain in charge of maintaining and monitoring that connection, meaning the radio would be on for a much longer time when compared to the peripheral.
When Bluetooth Low Energy (BLE) API was added to Android, it supported Central role only. In other words, you could write an Android app to scan and connect to peripherals (sensors), but the Android device itself could not act as a peripheral (Because the assumption was that you wouldn't need an Android device to act as a sensor). This was done in Android 4.3 (API 18).
As people started to use BLE more often and the technology matured, it started being used for all sorts of different applications (e.g. virtual serial port, data transfer, beacons, etc). Moreover, standalone central devices started appearing in the market and there was a need to use them with phones or at least test them out against phones/tablets during the development stages. As such, the distinction between central and peripheral started becoming fuzzier and fuzzier, and there was a demand for Android to start supporting peripheral role. This is when the BLE API was updated to introduce peripheral role functionality, which happened in Android 5.0 (API 21).
So to answer your question, if BLE is supported on an Android device then it is safe to state that it will by default support central role as this is the foundation of the BLE functionality for Android. However, API was introduced later to support the peripheral role, which is why not all Android devices that support BLE will support peripheral role.
Finally, please note that isMultipleAdvertisementSupported is a different feature which indicates if your device supports sending out multiple adverts at the same time. Some devices support sending out different adverts simultaneously, while others don't. However, this does not mean that they do not support advertising at all. A device that supports isMultipleAdvertisementSupported will definitely support BluetoothLeAdvertiser, but the other way around is not guaranteed.
To conclude, the safest way to check if your device supports central and/or peripheral role is through the Android version and the API level used, as indicated by the two links above. On Android 5 (API 21) onwards, you can write applications that support both central and peripheral roles, whereas before that you can only write applications for the central role.
I hope this helps.
I've built a dual mode Bluetooth device using the BT 121 from Silicon Labs. The device implements SPP over the classic connection. The device name of the classic node is "XYZ Classic". It also implements a custom service (128-bit UUID) in BLE. The device name of the BLE node is "XYZ_BLE". Both nodes have the same MAC address.
When pairing under 'Bluetooth' settings, sometimes I will see 'XYZ Classic' and sometimes I will see 'XYZ_BLE'. It seems random which one it will pair to but many Android devices I've tested have a tendency to want to pair to the classic node. After pairing, a connection over classic/SPP ALWAYS works. However, I can only connect to the custom service if paired to the BLE node. If paired to classic I can see non-custom BLE services but not my custom service. To summarize:
Function Classic Pairing BLE Pairing
Spp Works Works
Cust BLE Doesn't Work Works
When I pair in code (Android) the problem also happens despite the fact that I search for the devices named 'XYZ_BLE' and then pair to the device returned. I've looked but I can't see a way to force Android to pair to the BLE node.
My only workaround thus far has been to modify my BT 121 firmware to not allow bonding in classic mode. This is not an ideal solution has any Bluetooth Classic only devices will not be able to bond with my device (In reality this might not be too big of a problem but I have one tablet in my possession that only has Bluetooth Classic).
It should be noted that I've used 'BLE Scanner' from the play store to verify that my custom service works/doesn't work depending on the pairing mode. In other words, it's not just my code. :)
So, does anybody have any ideas on how to force Android to pair to the BLE node?
I see similar issues. Some hints:
Android behaviour differs dependent on the bit flags you set in the BLE advertising. There is for example a bit called "no br/edr support" or so. There are also bits telling explicitly that br/edr dual role is supported.
Also ble pairing may be enforced if you access a characteristic which returns a "not authenticated error" from a ble app. At least on iohone, the os will initiate the ble pairing automatically.
While scanning for advertising data with startLeScan method,
this method also request to pheripheral device for scan response data.
I only want to scan for advertising data.
I don't want to send response request to peripheral device.
and peripheral device can't change advertise mode.
According Bluetooth 4.0 Core spec, There exists passive scan mode.
https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=282159
And also, android has parameter that determines scan type.
And Active Scanning is android's default scan mode.
http://androidxref.com/5.1.1_r6/xref/external/bluetooth/bluedroid/stack/btm/btm_ble_gap.c#327
How to use passive scan mode?
or
Possible to change or add in btm_ble_gap.c in external folder?
please help. thanks.
Even if the Bluetooth stack internally supports passive scan, there is no public API available to use for apps for some reason.
Can a mobile application that is developed to work on Bluetooth technology be used on Bluetooth LE technology?
Or does the developer need to modify code to handle Bluetooth LE (Smart) signals, input, output etc. ?
EDIT
While i was asking this question i want to know
if i write a code piece, can i run it on BLE devices, also with BLE performance?
Is it possible, or not?
If a device can have both B and BLE then i have one more question:
Should we write code with different APIs for ordinary B and BLE?
I don't know of any phone that is doing BTLE but not classic Bluetooth as well. So the application should still work but it will still just be using the classic Bluetooth portion of the hardware.
Of course from the sensor of other device your talking to point of view the situation may well be different as there are BTLE only sensors for example that may have a similar function to an old style Bluetooth sensor but they want be compatible. E.g. some classic Heart Rate sensors and modern BTLE heart rate sensors.
If you want to connect to only BLE devices(LE profiles) , then you need to definitely modify code as profiles on LE devices are GATT based , unlike Bluetooth Classic.
You will need to implement GATT Client and GATT server in your code.
my goal is to find nearby Bluetooth devices(LE devices and "Classic"), in order to associate between current visible nearby devices to some functionality my app doing with it. (not a specific device/devices, but all of them!!!)
what I know:
startLeScan() would callback only with BLE devices
the two methods working in different way - while startBLeScan() managed by my code with callbacks while classic scan is managed by the system process, and returns the BluetoothDevice found via broadcasts.
what I don't know for sure:
assuming current device API level is 18+ startScan() will find always both discoverable BLE and classic devices.
BluetoothDevice.connectGatt() added with the new BLE API's, but should work also with classic bluetooth(return GATT Services...).
what I would like to know:
if indeed startScan() returns both types (Classic and BLE), what would be better to use in terms of battery consumption, performances, good practices and other aspects?
my application will perform background scans periodically, so I would like to minimize the battery consumption impact as possible.
You have to start a scan for Classic Bluetooth devices with startDiscovery() and a scan for Bluetooth LE devices with startLeScan(). Caution: Performing device discovery is a heavy procedure for the Bluetooth adapter and will consume a lot of its resources.
Edit:
On LG Nexus 4 with Android 4.4.2 startDiscovery() finds Bluetooth LE devices.
On Samsung Galaxy S3 with Android 4.3 startDiscovery() doesn't find Bluetooth LE devices.
I have an off-market Chinese tablet that has BLE support, however, it always return a BLE equipped device with its name as "null" when I call startLeScan. The issue was resolved by calling startDiscovery. Remember that if your app targets 23 or above, you will need to have location permissions for startDiscovery to work correctly. Hope it helps.