-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Enables background usage of flutter-blue #210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Android: Swaps activity() calls for context() where only a context is required. The only place an activity is required is when requesting permissions. This patch will return an error when the plugin is used where permissions have not been granted, and there is no activity available to request permissions iOS: To use bluetooth-central background role and continue to processes in the background it is required that a unique ID (CBCentralManagerOptionRestoreIdentifierKey) be set when the CBCentralManager is initialized. (https://developer.apple.com/documentation/corebluetooth/cbcentralmanageroptionrestoreidentifierkey?language=objc). Delays instanciation of the cbcentralmanager to when it is first used, so allow setting of a unique id from dart. When CBCentralManagerOptionRestoreIdentifierKey is set, the CBCentralManagerDelegate must implement centralManager:willRestoreState. The current implmentation is empty as it appears that setting a unique ID is sufficient to stop iOS killing the app once it has been backgrounded, if a bluetooth connection is active, or a scan is in progress. This has a side effect of printing an API-MISUSE warning when CBCentralManagerOptionRestoreIdentifierKey is not used, because the method centralManager:willRestoreState is always implemented. The warning is harmless when not using CBCentralManagerOptionRestoreIdentifierKey. Dart: To support the setting of a unique Id, introduces setUniqueId(String). This should be called before any methods that will instanciate the native instance of the cbcentralmanager.
@rmawatson Thank you for your work on this. There is no way to pass through the application restart reason. But it is possible to run flutter in headless mode an call it with a different entry point - as I read from geofencing service examples: Flutter's reference example for background processes Probably (didn't check in detail) the headless runner would be a good candidate for your empty |
@treyerl Thanks for that info about the restart reason. I think it should be possible to make the restart reason available from iOS so in the flutter main() entry point you can just branch on the startup reason and gracefully exit when its handled the event. Although I never actually got round to trying this with flutter blue (as I didn't need it) something like this https://github.com/rmawatson/flutter_startup for getting the startup type, then just providing a way to get the info passed into the startup reason callback should be enough... all gets a bit messy and platform specific though. |
Is there any holdups in this? I'd really like to use it! |
The same question - any update on when this fix is supposed to be released ? |
Can we get this merged? |
@pauldemarco is this on the roadmap to be merged? Lots of people needing this functionality. |
@rmawatson I tried to merge your branch with the latest from master, but it seems this commit introduces a new issue. My fork: Commit with issue: Any suggestions? Edit: I can remove the Edit2: posted an issue update here (rmawatson/flutter_isolate#19) if anyone can help solve this is the only thing outstanding for flutter_blue working in the background with an isolate. |
Hi guys, I'm needing a background service that runs every 15 minutes periodically that connect with a nearby smartband, fetch its data and send this data to a server without any user interaction. Could someone help me about how should I build this? |
Hi guys, any updates on this? This would be such a useful feature. Thank you for all your work! 👍 |
I stop waiting for this and started to use a new lib called by rx_ble, and for my needs, everything is working fine, here is the link |
@edsonboldrini are you using this with an isolate in the background? |
I'm using this with flutter_workmanager plugin, and it is working fine. |
Note: flutter_blue: |
@boskokg Shouldn't we close this PR then ? |
@xurei I tested setting uniqueId in the production but I did not see any improvements described in this this PR (related to iOS). Other things are already on the latest release of this plugin, so I am not using my branch anymore... |
it is possible with this modification execute the plugin in a headless task? |
Any update here or in #191? |
The iOS app is still getting killed when running in the background. How do you create Bluetooth object again on start up to reconnect to Bluetooth because scanning is not working in the background. @edsonboldrini, the plugin that you using is it working on restoring BLE connection when the app is killed in iOS |
Changed this PR to come from
rmawatson:background_feature
instead ofrmawatson:master
Android:
Swaps activity() calls for context() where only a context is required. The only place an activity is required is when requesting permissions. This patch will return an error when the plugin is used where permissions have not been granted, and there is no activity available to request permissions
iOS:
To use bluetooth-central background role and continue to processes in the background it is required that a unique ID (CBCentralManagerOptionRestoreIdentifierKey) be set when the CBCentralManager is initialized. (https://developer.apple.com/documentation/corebluetooth/cbcentralmanageroptionrestoreidentifierkey?language=objc).
Delays instanciation of the cbcentralmanager to when it is first used, so allow setting of a unique id from dart.
When CBCentralManagerOptionRestoreIdentifierKey is set, the CBCentralManagerDelegate must implement centralManager:willRestoreState. The current implmentation is empty as it appears that setting a unique ID is sufficient to stop iOS killing the app once it has been backgrounded, if a bluetooth connection is active, or a scan is in progress.
This has a side effect of printing an API-MISUSE warning when CBCentralManagerOptionRestoreIdentifierKey is not used, because the method centralManager:willRestoreState is always implemented. The warning is harmless when not using CBCentralManagerOptionRestoreIdentifierKey.
Dart:
To support the setting of a unique Id, introduces setUniqueId(String). This should be called before any methods that will instanciate the native instance of the cbcentralmanager.
Additional Notes:
iOS:
Even when a unique ID is set, the app could still theoretically be killed for other reasons by iOS (although I have not experienced this).
If the app is killed by iOS at any point and bluetooth-tasks are ongoing, iOS will restart the app and willRestoreState method will be called on the CBCentralManagerDelegate. It allows about 10 seconds to handle the event, before the app is killed again. It may be nice to allow registering a handler in flutter that can be called to handle such events. This would be iOS only.
States that can be saved and restored:
https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate/central_manager_state_restoration_options?language=objc
Additionally it would be good to be able to pass through the application restart reason. Currently flutter has no way of knowing why it was started and main() will run if it was started to handle something through willRestoreState. If it was started to handle this callback, the ideal would be run this in a standalone isolate, passing the various restored states to the handler, but allow the main to exit without attempting to run any code by checking the start reason.