I am using react-native-background-fetch to execute a task when the app is in the background. In that task, I should be able to scan for devices.
I am able to connect, speak with devices, and do anything except for scan for peripherals in the background task I configured. After searching through these issues, I found a related issue here. To confirm that I have all the correct advertised services, in the foreground process I do this:
const my_service = 'c7fcee6f-e7e0-8c8a-b745-fde27c268efd';
manager.startDeviceScan([my_service], {allowDuplicates: true}, (error, device) => {
if (error) {
console.log("Error in device scan: ", JSON.stringify(error));
}
if (device) {
console.log("DEVICE UUIDS: ", device.serviceUUIDs);
}
});
In the console this log is printed:
'DEVICE UUIDS: ', [ '00001805-0000-1000-8000-00805f9b34fb',
'c7fcee6f-e7e0-8c8a-b745-fde27c268efd' ]
Then in the background task, I perform the scanning process with those exact uuids, but without finding any devices this time.
NOTE: the service '00001805...' is the bluetooth current time service. The service id is really just '1805' or '0x1805' but i'm unsure whats the proper way to scan for a service with an assigned number by the bluetooth sig group.
manager.startDeviceScan(['00001805-0000-1000-8000-00805f9b34fb', 'c7fcee6f-e7e0-8c8a-b745-fde27c268efd'], {allowDuplicates: true}, (error, device) => {
console.log("Anything?");
if (error) {
console.log("Error in background device scan: ", JSON.stringify(error));
}
if (device) {
console.log("DEVICE UUIDS: ", device.serviceUUIDs);
console.log("Found device in background scan: ", device.id);
}
});
I am setting log level to verbose. This is the only relevant log I have found:
'CentralManager(10766645056) scanForPeripherals(
withServices: Optional("[00001805-0000-1000-8000-00805F9B34FB, C7FCEE6F-E7E0-8C8A-B745-FDE27C268EFD]"),
options: Optional(["kCBScanOptionAllowDuplicates": true]))'
Library version: 1.0.3
Platform: IOS and Android
I have tried my best to do my due diligence before submitting a bug report. Please let me know what other relevant information I can provide, or what I am missing.
Thank you for your help and excellent library!
As a sidenote, I am pretty unclear on what happens when the app is registered for background modes, and a device or service is reconnected. For instance, in IOS it is recommended to just call connectToDevice(id) when a device disconnects if we want to reconnect. But, lets say, the app performs a data transfer when a component is mounted. If the app is in the background then that component is not mounted and that data transfer is not performed? Because of this confusion is why I am using react-native-background-fetch so I know exactly the code the runs in the background.
Also having this problem on iOS, but on Android it is working well.
I am still interested in understanding more about how to properly use this library with background modes.
There are two relevant pieces of information in the documentation:
A couple of questions I have regarding that:
An example of the proper way to implement background tasks with BLE would probably be very useful for a lot of users, but of course that takes more time to do as all things do.
Thanks again for a great library!
In upcoming days I will research this topic. The result will be a wiki page with all the details.
I have the same issue.I don't understand how can i use this library in background mode on Ios and Android.
I am still interested in understanding more about how to properly use this library with background modes.
There are two relevant pieces of information in the documentation:
- It (the ble manager) should be initialized only once with the new keyword and method destroy() should be called on its instance when the user wants to deallocate all resources.
- In case you want to properly support Background Mode, you should provide restoreStateIdentifier and restoreStateFunction in BleManagerOptions.
A couple of questions I have regarding that:
- Is it correct I need to use a background modes library to use this library in the background?
- If I create a BLE manager in the app, and then a separate one when the background task runs, will that cause an issue if I do not call manager.destroy() on one of them?
- What do the restoreStateIdentifier and Function do, and how should I properly use them?
An example of the proper way to implement background tasks with BLE would probably be very useful for a lot of users, but of course that takes more time to do as all things do.
Thanks again for a great library!
The restoreStateFunction is fired for you ? If yes, can you explain?
@AzRunRCE I have no idea what the restoreStateFunction does or how to use it.
I have had some luck with the restoreStateIdentifier. By using it, I have been able to use the methods manager.devices([id]) to see what devices are connected to the system but not the app, and the method manager.connectedDevices([uuid]).
The first has really only been useful when hot reloading causes stuff the break w/ the ble, but that happens frequently for use during development.
The second returned something one time, but I have never seen it do anything since then.
Specifying both restoreStateIdentifier and restoreStateFunction tells iOS that you are interested in maintaining BLE state (connection as well) in the background. When in background mode, iOS may kill the app after unspecified time, but at the same time operating system will hold BLE connection (if one exists) for you. After this event, when user goes back to the application or it's woken up by a Bluetooth event, it is restored with maintained BLE state. Check argument of restoreStateFunction to get list of connected devices.
Additionally:
null state.Thank you @Cierpliwy, is this along the lines of how you would implement and use restore state identifier and function?
const restore_state_identifier = 'manager';
const restore_state_function = async (restored_state) => {
console.log('Restored State: ', restored_state);
const connected_devices = await restored_state.connectedDevices();
console.log('Connected Devices: ', connected_devices);
// do what you need with the devices_connected
}
const manager = new BleManager({restoreStateIdentifier: restore_state_identifier, restoreStateFunction: restore_state_function});
Please check documentatation when in doubt: https://polidea.github.io/react-native-ble-plx/#blemanageroptionsrestorestatefunction. restored_state may be null and connectedDevices is not a function.
Hello! I added a new entry in the Wiki with an example application to show you all available possibilities around background mode on iOS. Checkout page here: https://github.com/Polidea/react-native-ble-plx/wiki/Background-mode-(iOS).
@Cierpliwy This is incredibly thorough. Thank you for your help, it is much appreciated!
Hello! I added a new entry in the Wiki with an example application to show you all available possibilities around background mode on iOS. Checkout page here: https://github.com/Polidea/react-native-ble-plx/wiki/Background-mode-(iOS).
Hi, thanks for your efforts!
Is background mode supported by Android too?
Hi all, any news about Android?
thanks
Most helpful comment
Hi, thanks for your efforts!
Is background mode supported by Android too?