I'm trying to create an Android 5 (lollipop) app that acts as a Bluetooth Low Energy (BLE) peripheral. The app runs on a Nexus 9 which supports BLE peripheral mode. So far I've managed to advertise a service and allow another BLE device connect to it successfully. However, it is fails when trying to read the characteristic value.
I've checked that the characteristic has the read property and that the read permission is set.
When using the LightBlue iOS app (https://itunes.apple.com/gb/app/lightblue-bluetooth-low-energy/id557428110?mt=8) I manage to discover and connect to my Nexus and see the characteristic uuid but the value doesn't show.
Any help would be highly appreciated.
First check the characteristic data you are advertising in the peripheral mode usually there are three modes
BluetoothGattCharacteristic.PROPERTY_WRITE, BluetoothGattCharacteristic.PROPERTY_READ,
BluetoothGattCharacteristic.PROPERTY_NOTIFY;
and you can build characteristic with all modes using
BluetoothGattCharacteristic.PROPERTY_WRITE |BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY;
Once done look for onCharacteristicWriteRequest() in BluetoothGattServerCallback() that you gave while building characteristic. When central want to send data it can write data to the characteristic with WRITE mode and you will have onCharacteristicWriteRequest() callback method triggered at peripheral side and you will have data in byte[] and make sure send response using btGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null);
by checking the responseNeeded bool value in callback method. In this way the data is transferred from central to peripheral.
And to send data from peripheral to central use notification charatertertistc
BluetoothGattCharacteristic bgc = bluetoothGattService
.getCharacteristic(chartersticUUID);
bgc.setValue(bnd.data);
btGattServer.notifyCharacteristicChanged(centralbluetoothdevice, bgc, false);
.
Related
I am having a Arduino with BLE which has to send some data to any/all android phones over Bluetooth in it's range. My android phone should have a app which i intend to make will notify about data received.
How can i make such android app which auto-connects to any nearby BLE , if found without pairing even for first time and exchange data. I mean how in any application i can implement auto-connect without key pairing.I found that setting autoconnect=true will do this task , but i am not sure.
Any help, even some resource i will refer and clear my doubts.
The pre-requisites and steps are (code snippets in Java):
HC-XX module or similar BLE-device on the Arduino-side set to security mode 1 and security level 1 (no security AND no pairing)
Android 4.3 (API level 18) with built-in platform support for Bluetooth Low Energy (BLE)
Check on the device (mobile) that BLE is enabled
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Find the BLE device(s). You use the startLeScan() method. This method takes a BluetoothAdapter.LeScanCallback as a parameter. You must implement this callback, because that is how scan results are returned. Because scanning is battery-intensive, you should observe the following guidelines:
As soon as you find the desired device, stop scanning.
Never scan on a loop, and set a time limit on your scan. A device that was previously available may have moved out of range, and continuing to scan drains the battery.
If you want to scan for only specific types of peripherals, you can instead call startLeScan(UUID[], BluetoothAdapter.LeScanCallback), providing an array of UUID objects that specify the GATT services your app supports.
The first step in interacting with a BLE device is connecting to it— more specifically, connecting to the GATT server on the device. To connect to a GATT server on a BLE device, you use the connectGatt() method. This method takes three parameters: a Context object, autoConnect (boolean indicating whether to automatically connect to the BLE device as soon as it becomes available), and a reference to a BluetoothGattCallback.
// Here we set autoconnect to true
bluetoothGatt = device.connectGatt(this, true, gattCallback);
To sum up auto connect alone will not do the job as you want no pairing. So security mode 1 and security level 1 (no security at all) has to be set. So make sure by using software sided encryption/auto sign-in that no unauthorized persons use your device
Read more about BLE in Android in detail here
Read more about BLE security in detail here
BLE and Android, the more characteristics and services the more slowly
Following problem:
I’m working on a project with android (5.0+) and a Nordic BLE chip (NRF52832) to receive values from the chip on the android device.
(I don’t use third party packages)
Connect, readout the services and the characteristics works well and fast, but:
As soon as I set more characteristics (in 2 services) on notify, the values arrive the device very slow, for example:
Notify 1 characteristic = 50ms/value
Notify 1 service 6 characteristic = 150 – 200ms/value
Notify 2 service, 10 characteristics = 400-600ms/value`
RequestConnectionPriority won’t solve my case.
Does anyone have a solution statement or already a solution?
It is a know problem that using multiple services and characteristics can slow down the communication between a BLE center and a peripheral.
Furthermore, each characteristic has an overhead cost in terms of memory consumed on the device.
A solution to this problem is to minimize the number of characteristics you're using.
To do so, you could for instance use only one characteristic and dedicate one octet of the characteristic packet to storing the command id or info type you're sending or receiving from the device.
The same characteristic can then be used to send various command to your device, or to request various type of info from the device.
My Android app is made as a BLE central device. I have a device which is peripheral. I want to send some data from Android app to peripheral device without any request from the peripheral. Can I achieve this ?
In my peripheral device to write data i am using below code :
BluetoothGattCharacteristic charac = Service
.getCharacteristic(UUID.fromString(SampleGattAttributes.LOCAL_TIME));
byte[] value = new byte[1];
String valuetosend = "data from client to server";
value = valuetosend.getBytes();
charac.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
charac.setValue(value);
Log.d("BluetoothLeservice::","Write Status:" + charac.getValue());
boolean status = mBluetoothGatt.writeCharacteristic(charac);
Do I have to do in the same way for central also? Any reference links would be helpful.
I think the process is same, you have to write data to the particular characteristic and service. You should know the value of the characteristic and service. In your case it is SampleGattAttributes.LOCAL_TIME.
We developed a little hardware piece that works with Bluetooth Low Energy. When connecting from an Android 5, all services and their characteristics are discovered successfully.
However, we tried with 3 Android 6 devices, and even though the services are found correctly, their characteristics return null all the time.
I made sure the UUIDs are correct by logging all the discovered services, characteristics & descriptors.
Android 5:
service [uuid]:[00001801-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002a05-0000-1000-8000-00805f9b34fb]
service [uuid]:[00001800-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002a00-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002a01-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002aa6-0000-1000-8000-00805f9b34fb]
service [uuid]:[5765536d-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00005765-0000-1000-8000-00805f9b34fb]
descriptor [uuid]:[00002902-0000-1000-8000-00805f9b34fb]
service [uuid]:[5765536e-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00005764-0000-1000-8000-00805f9b34fb]
descriptor [uuid]:[00002902-0000-1000-8000-00805f9b34fb]
Android 6:
service [uuid]:[00001801-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002a05-0000-1000-8000-00805f9b34fb]
service [uuid]:[00001800-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002a00-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002a01-0000-1000-8000-00805f9b34fb]
characteristic [uuid]:[00002aa6-0000-1000-8000-00805f9b34fb]
service [uuid]:[5765536d-0000-1000-8000-00805f9b34fb]
service [uuid]:[5765536e-0000-1000-8000-00805f9b34fb]
Is there any known issue provoking this? I am using BluetoothAdapter and BluetoothLeScanner.
Thank you.
It worked on Android 6 after we changed the service UUID's from:
5765536d-0000-1000-8000-00805f9b34fb
5765536e-0000-1000-8000-00805f9b34fb
To:
3032454c-426b-7261-5074-72616d536557
3031454c-426b-7261-5074-72616d536557
It also worked when we reduced the UUID's size from 32bits to 16bits, this means, the first four digits being zero 0000XXXX.
We are designing both a BLE device, and the mobile phone app to talk to it. We've defined a characteristic on the BLE device that has the properties
<properties write_no_response="true" notify="true" read="true" write="true" indicate="true"/>
Yes, it's overkill, we're in very early development.
The communication is working fine when I write to a characteristic on the device, but if I switch to Write Without Response:
m_characteristic.WriteType = GattWriteType.NoResponse;
m_characteristic.SetValue (bytes);
m_gatt.WriteCharacteristic (m_characteristic);
the call to WriteCharacteristic() fails.
1) Is it "legal" to have a characteristic that does both write_no_response and write?
2) Is it "legal" to switch from a regular write (GattWriteType.Default) to a write_no_response?
3) Is there any way to ask the BLE library why WriteCharacteristic() failed?