Closed msd05keisuke closed 1 year ago
This should work without introducing iBeacons: your app initiates scanning for nearby devices using FlutterReactiveBle.scanForDevices(), and iOS automatically resumes your app to deliver the related events. After this, if your app connects to the discovered nearby devices, it will be able to receive incoming BLE packets. No 10-second timeout applies here.
Now, this only works until your user decides to swipe-kill the iOS app. When that happens, your app won't receive any BLE events until the user manually restarts the app. This is where iBeacons become useful, as iBeacon location events are delivered to terminated apps as well, and iOS will restart your app after swipe-kills or even after the phone is rebooted. iBeacon functionality is not included in this library though, you'll need a separate package for that. We are using flutter_beacon for this.
@akospwc
I'm coding like this, but I can't scan in the background. Can you tell me the solution? I'm not good at English, so I'm sorry if there is a part that I can't communicate well.
// monitoring(use flutter_beacon)
StreamSubscription streamMonitoring =
flutterBeacon.monitoring(regions).listen((result) async {
if (result.region.proximityUUID!.toLowerCase() ==
BEACON_UUID.toLowerCase() &&
result.monitoringState == MonitoringState.inside) {
debugPrint("IN");
// scan ble(use flutter_reactive_ble)
flutterReactiveBle.scanForDevices(withServices: []).listen((device) {
//code for handling results
print(device.id + device.name);
});
} else if (result.monitoringState == MonitoringState.outside ||
result.monitoringState == MonitoringState.unknown) {
debugPrint("OUT");
}
});
Your English is perfectly understandable, don't worry about that even for a second.
Which part of the code is never getting called? Is the problem that the beacon is not found, or that the BLE scan is not working? How are you testing the background execution?
As I said earlier, I'd leave the beacon part out of the equation for now, as it is only needed if your app is explicitly killed by the user. Solve that problem later. As the first step, I'd recommend focusing on the 'happy path', e.g.
Test that the scanning finds your device when the app is running in the foreground. Then send the app to the background (do not swipe kill it, just return to the home screen) and test the scanning again (I recommend sending local notifications to debug these flows - we're using the flutter_local_notifications
package for this).
If these flows work, then you can introduce iBeacons to the mix. Apologies if I'm stating the obvious, but iBeacons are completely different animals from regular BLE services, so your communication partner (the sensor) has to advertise itself as iBeacon as well as a regular BLE service for this to work.
I will close this issue, because it appears not related to library
Hello @Taym95 @akospwc
I'm also encoutering this kind of issue.
Here is my dart provider:
class BleScanDevicesNotifier extends StateNotifier<List<DiscoveredDevice>> {
final Ref ref;
StreamSubscription<DiscoveredDevice>? subscription;
BleScanDevicesNotifier(this.ref) : super([]) {
Timer.periodic(const Duration(seconds: 1), (timer) {
debugPrint('tick ${timer.tick.toString()}');
});
init();
}
init() {
print('init');
subscription?.cancel();
subscription =
ref.read(bleProvider).scanForDevices(withServices: []).listen((device) {
final knownDeviceIndex = state.indexWhere((d) => d.id == device.id);
print('received device ${device.id}');
if (knownDeviceIndex >= 0) {
state[knownDeviceIndex] = device;
} else {
state.add(device);
}
state = [...state];
}, onError: (err) {
print(err);
throw err;
});
}
}
final bleScanDevicesProvider =
StateNotifierProvider<BleScanDevicesNotifier, List<DiscoveredDevice>>(
(ref) => BleScanDevicesNotifier(ref));
When I start the app I have many received device ...
logs
and tick 1
, 'tick 2`... logs
As soon as I switch to another app, without killing it, received device...
logs stop, but I still have tick 10
, tick 11
coming (to ensure my provider keeps running in background)
I also tried to detect when app goes in background a call init()
again; no luck.
As soon as the app comes back to foreground, received device...
logs come back again.
Here is my UIBackgroundModes
:
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>location</string>
<string>bluetooth-central</string>
<string>bluetooth-peripheral</string>
</array>
Any ideas?
Thanks for your help :)
I also reproduce it simply on the example project :
Thanks for your help :)
@msd05keisuke Did you find a way to get it working since 2022 ? 😇
Hello.
do not working Background mode in BLE For flutter_reactive_ble 5.3.1 IOS flutter
But I can't do it at the moment. Is there any solution?
i am using permission
@expoders8 , scanning in the background without explicitely specifying the withServices
parameter is not possible on iOS and usually also not on current Android versions (maybe on on some older Android versions). Also passing an empty list does not work. (But if it helps: you can connect to the device in the background if you already know its UUID
@BenelliFurtado Hello
I don't need to use UUID
Please give me correct solution with code.
Hello @expoders8 ,
in Apples Documentation it sais, that the use of UUDIs is necessary for background scanning:
Your app can scan for Bluetooth devices in the background by specifying the bluetooth-central background mode. To do this, your app must explicitly scan for one or more services by specifying them in the serviceUUIDs parameter. The CBCentralManager scan option has no effect while scanning in the background.
So it will work if you uncomment the line from your example code:
scanSubscription = instance
.scanForDevices(
requireLocationServicesEnabled: false,
withServices: [Uuid.parse(Constants.UUID_RF_IDEAS_SERVICE_ID)],
scanMode: ScanMode.lowLatency)
.listen((scanResult) async {...});
But of course it works only if your BLE device is advertising at least one of the UUIDs you are filtering for (in its advertising packets). So if your BLE device does not advertise any services, you cannot find it from a background scan on iOS.
Hello.
I would like to do a BLE scan on an iOS device in background state.
But I can't do it at the moment. Is there any solution?
I am assuming the following case.
1, iBeacon region in 2, state suspend -> background (10sec) 3, connect to sensor during 10sec and upload sensed information to cloud
By doing this, I would like to achieve sensor-driven sensing, not user-driven.
info.plist