Using mobile phones as BLE central and peripheral device in react native

53 Views Asked by At

I want to create an application where a mobile phone transmits data wirelessly and automatically to all nearby mobile phones. Sort of broadcast and read system. Where each device is broadcasting it's data while also receiving data from other nearby devices.

I decided to try BLE as this allows low power consuming wireless data transfer without having to manually 'pair' with each device.

I want to simultaneously transmit and receive data to/from all nearby devices without active participation from the user ( without having to pair, share pins... ) Or is there some better way to achieve my goal? I don't want to rely on internet connection to allow usage in areas with no network.

However I am facing difficulty turning a device into peripheral since libraries like react-native-ble-plx and react-native-ble-manager only support BLE center mode. How can I achieve this?

I found a flutter package that seems to do what I need - github link here. Is there a react native alternative or should I switch to flutter? ( not preferred because I have no experience with flutter or dart )

1

There are 1 best solutions below

0
Renzo Sampietro On

I suggest you consult the following websites: https://developer.android.com/develop/connectivity/bluetooth/ble/ble-overview https://developer.android.com/develop/connectivity/bluetooth/ble/find-ble-devices https://developer.android.com/develop/connectivity/bluetooth/ble/connect-gatt-server https://developer.android.com/develop/connectivity/bluetooth/ble/transfer-ble-data https://medium.com/@martijn.van.welie/making-android-ble-work-part-1-a736dcd53b02 By Martijn van Welie

https://bignerdranch.com/blog/bluetooth-low-energy-on-android-part-1/ https://bignerdranch.com/blog/bluetooth-low-energy-on-android-part-2/ By Andrew Lunsford

These are the steps I followed in my app (see my answer for details How do I connect two android devices instantaneously based on proximity?)

step 1 The BLE app provides an activity (Game1BleActivity) to connect to Bluetooth device. Based on user input, this activity communicates with a Service called BluetoothLeService, which interacts with the BLE device via the BLE API. The communication is performed using a bound service which allows the activity to connect to the BluetoothLeService and call functions to connect to the devices. The BluetoothLeService needs a Binder implementation that provides access to the service for the activity.

step 2 The BluetoothLeService needs a Binder implementation that provides access to the service for the activity.

step 3 A client binds to a service by calling bindService(). When it does, it must provide an implementation of ServiceConnection, which monitors the connection with the service. The return value of bindService() indicates whether the requested service exists and whether the client is permitted access to it.

step 4 Once the service is bound to, it needs to access the BluetoothAdapter. It should check that the adapter is available on the device. The following example wraps this setup code in an initialize() function that returns a Boolean value indicating success.

step 5 The activity calls this function within its ServiceConnection implementation. Handling a false return value from the initialize() function depends on your application. You could show an error message to the user indicating that the current device does not support the Bluetooth operation or disable any features that require Bluetooth to work. In the following example, finish() is called on the activity to send the user back to the previous screen.

step 6 Scan settings

step 7 setup Gatt Server

step 8 : what to do when a write request is received

step 9 Start Advertising

step 10 Bluetooth scan

step 11 Bluetooth scan callback

step 12 Once the BluetoothService is initialized, it can connect to the BLE device. The activity needs to send the device address to the service so it can initiate the connection. The service will first call getRemoteDevice() on the BluetoothAdapter to access the device. If the adapter is unable to find a device with that address, getRemoteDevice() throws an IllegalArgumentException.

step 13 Once the activity tells the service which device to connect to and the service connects to the device, the service needs to connect to the GATT server on the BLE device. This connection requires a BluetoothGattCallback to receive notifications about the connection state, service discovery, characteristic reads, and characteristic notifications. This topic focuses on the connection state notifications. See Transfer BLE data for how to perform service discovery, characteristic reads, and request characteristic notifications. The onConnectionStateChange() function is triggered when the connection to the device’s GATT server changes. The callback is defined in the Service class so it can be used with the BluetoothDevice once the service connects to it.

step 14 When the server connects or disconnects from the GATT server, it needs to notify the activity of the new state. There are several ways to accomplish this. We use broadcasts to send the information from the service to activity. The service declares a function to broadcast the new state. This function takes in an action string which is passed to an Intent object before being broadcast to the system.

step 15 : see step 12 Once the BluetoothGattCallback is declared, the service can use the BluetoothDevice object from the connect() function to connect to the GATT service on the device. The connectGatt() function is used. This requires a Context object, an autoConnect boolean flag, and the BluetoothGattCallback. In this example, the app is directly connecting to the BLE device, so false is passed for autoConnect.

step 16 -> BluetootLeService Once the service broadcasts the connection updates, the activity needs to implement a BroadcastReceiver. Register this receiver when setting up the activity, and unregister it when the activity is leaving the screen. By listening for the events from the service, the activity is able to update the user interface based on the current connection state with the BLE device. In Transfer BLE data, the BroadcastReceiver is also used to communicate the service discovery as well as the characteristic data from the device.

step 17 service discovery: see step 13 The first thing to do once you connect to the GATT Server on the BLE device is to perform service discovery. This provides information about the services available on the remote device as well as the service characteristics and their descriptors. Once the service successfully connects to the device (indicated by the appropriate call to the onConnectionStateChange() function of the BluetoothGattCallback), the discoverServices() function queries the information from the BLE device. The service needs to override the onServicesDiscovered() function in the BluetoothGattCallback. This function is called when the device reports on its available services.

step 18 This function is part of bluetoothGattCallback and is called when the device reports on its available services.

step 19 These functions are part of bluetoothGattCallback. If the discovery services was successful and the MTU has been agreed, we can now look for our Characteristic. Since we know the full UUID of both the Service and the Characteristic, we can access them directly.

step 20 One important step when dealing with Bluetooth connections is to close the connection when you are finished with it. To do this, call the close() function on the BluetoothGatt object. In the following example, the service holds the reference to the BluetoothGatt. When the activity unbinds from the service, the connection is closed to avoid draining the device battery.

step 21 set the value on the Characteristic and our message will be sent

This answer to the question was very laborious. I hope it's useful