bearound_flutter_sdk 3.6.2
bearound_flutter_sdk: ^3.6.2 copied to clipboard
Bearound Flutter SDK - Beacon detection and proximity tracking
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased] #
3.6.2 - 2026-07-25 #
Changed #
- Native SDKs bumped to the 3.6 line — iOS
BearoundSDK3.6.2 and Androidbearound-android-sdkv3.6.1, carrying the full background/reliability package:- iOS — background detection unlocked: state-dependent BLE scan filter (
nilforeground /0xBEADbackground, pairs with beacon firmware v6) plus presence integrity — kernel region exits are confirmed before being propagated (no more false "left the zone" while parked next to a beacon),CLRegionState.unknownis preserved, cold relaunches survive until the region state resolves, and the Location-only permission profile (no Bluetooth) now detects and syncs end-to-end. - iOS — coordinated sync: single funnel for all triggers, detection-driven uploads (~seconds after entering a zone), 5 s foreground fast-path for changed samples, 1 s background batch window, and a 60 s per-beacon re-report that cuts steady-state volume ~4× without changing the ingest contract.
- iOS — device floor back to iOS 15 and honest platform-guarantees documentation.
- Android — ghost-beacon fixes: controller "fossil replay" guard (MediaTek batch-buffer re-delivery), zombie synced-card release, and a periodic scan watchdog that keeps recovering the scan instead of dying with it.
- iOS — background detection unlocked: state-dependent BLE scan filter (
3.5.2 - 2026-07-22 #
Changed #
- Android native SDK v3.5.0 → v3.5.2 (3.5.1 was never published for this wrapper; this release carries both). Scan reliability on modern Android 13+ (anti-downgrade refresh, pure-0xBEAD batch filter, PendingIntent kept armed in foreground), continuous hardware-managed duty for MEDIUM/LOW (no more scan-start-quota starvation), adaptive foreground boost (LOW_LATENCY whenever the app is in use — best detection automatically with the MEDIUM default), smooth beacon presence (10 s stale fade / 15 s eviction), weak-receiver SoC profile (Unisoc/Spreadtrum devices get doubled retention windows automatically), ghost-beacon fixes and precision-apply fix. No Dart API changes.
- iOS native pin stays on 3.5.1 (same 3.5.x line — the Android patches are platform-specific).
- Android native SDK v3.5.0 → v3.5.1. Scan reliability on modern Android 13+ (periodic anti-downgrade scan refresh, batch-scan filter for pure-0xBEAD frames from firmware v4 beacons, PendingIntent scan kept armed in foreground), ghost-beacon fixes on the host list (expirations now reach the listener, including the empty list) and scan-precision changes now apply immediately on reconfigure. No Dart API changes — all fixes live in the embedded native SDK. See the native SDK CHANGELOG for full details.
3.5.0 - 2026-07-14 #
Added #
- Silent-push wake-up bridge (Android): new
BearoundFlutterSdk.handleRemoteMessage(Map<String, String> data)— forward the FCM data message from yourfirebase_messagingbackground handler and the SDK triggers an on-demand scan + sync (returnstrueonly for Bearound wake-ups, markedbearound). See README → Silent-push wake-up (Android).
Changed #
- Wraps native iOS 3.5.0 (BLE scan fix:
withServices: nil+ Service Data0xBEADmatch — beacons detect again; regression since 2.3.2) and Android v3.5.0 (silent-push wake-up + never-crash-the-host hardening).
3.4.5 - 2026-07-04 #
Added #
- Dart-layer error telemetry (
ErrorReporter). The plugin now captures uncaught Dart/Flutter errors originating inpackage:bearound_flutter_sdk(via chainedFlutterError.onError+PlatformDispatcher.onError) and ships them fire-and-forget toPOST https://ingest.bearound.io/sdk-errors, matching the Android nativeErrorReportercontract (sdk.platform: "flutter"). Installed automatically onconfigure(). Ownership is decided by the first application frame (skipping thedart:/package:flutterruntime and the telemetry file itself) — only errors that ORIGINATE in the plugin are reported; a host error that merely passes through an SDK callback is never captured. Isolated transport (dart:io HttpClient, 5 s timeouts), in-memory rate limit (20/h) + 5 min dedupe, stack capped at 8000 chars, permission snapshot viapermission_handler(read without prompting). The handlers are always chained (the previousFlutterError.onErroris kept and invoked;PlatformDispatcher.onErrorreturnsfalse) so the host's error flow is never hijacked or broken. Native crashes keep being captured by the embedded native SDKs — this only adds the Dart layer they cannot see. No new dependency. BearoundFlutterSdk.setErrorReportingEnabled(bool)— public opt-out for the Dart-layer telemetry (default: enabled). No-op for native crash capture, which is independent.- Background-reliability API (Android):
isIgnoringBatteryOptimizations(),openBatteryOptimizationSettings(),isAutostartManageable(),openManufacturerAutostartSettings()— exposes the native helpers to keep the process eligible to wake under Doze and aggressive OEM battery managers (Xiaomi/Huawei/Oppo/Vivo/OnePlus/Letv). No location, no Google Play policy impact (uses the Settings screen, not the restricted permission). No-op on iOS (no equivalent restriction). errorStreamreplay buffer. The wrapper now eagerly subscribes to the native error channel on the firsterrorStreamaccess and buffers up to 16 errors emitted before the app's firstlisten(); the first listener receives them replayed in order. Fixes the class of bug where an error on the very firststartScanning()(e.g. a permission/configuration failure) fired before the app attached its listener and was lost forever.setDebugNotificationsEnabled(bool)+configure(debugNotifications:)(iOS-only, defaultfalse) — QA aid that posts a visible local notification per silent-push-triggered scan. Silent no-op on Android. Keepfalsein production.
Fixed #
- Never-crash-the-host hardening (Dart layer). Three fixes from the cross-platform crash-safety audit: (1)
PlatformDispatcher.onErrornow CHAINS a pre-existing host handler (e.g. Crashlytics) instead of silently replacing it — the previous handler is captured, always delegated to, and its return value honored; (2) the plugin's internal error-stream subscription gained anonErrorguard — anEventChannelfailure no longer surfaces as an unhandled async error attributed to the SDK inside the host app (it is swallowed and reported to error telemetry via the newErrorReporter.reportCaught); (3) telemetry reports were labeled with the previous version (3.4.4) — now 3.4.5. Doctrine: the SDK may fail silently, but it must NEVER crash the host — and every silent failure is reported toPOST /sdk-errors. - Never-crash-the-host hardening (bridge + edge paths), from the pre-merge review. (1) The Android
onMethodCalldispatch is now wrapped in acatch (Throwable)— the Flutter engine only convertsRuntimeExceptioninto aPlatformException, so a linkageError(e.g.NoSuchMethodErrorwhen the host's Gradle resolution downgrades the native SDK) used to kill the host process; it now surfaces as a catchablePlatformException(BEAROUND_INTERNAL). Same guard ononAttachedToEngine. (2)setDebugNotificationsEnabledgained the missing Android stub — it was documented as a silent no-op but actually threwMissingPluginExceptioninto the host. (3)getPersistedLog()/getPersistedLogRaw()no longer throwFormatExceptionon malformed JSON from the native side (degrade to[]+ report). (4) The Dart telemetry is installed BEFORE the nativeconfigure()call, so the session where configure itself fails — exactly the one that needs visibility — is covered. (5)PermissionServicefailures now report to/sdk-errorsbefore returningfalse(silent for the host, visible to us). (6) The telemetry origin markers are anchored to the fullpackage:bearound_flutter_sdk/URI — a host file merely named after the SDK (e.g.bearound_flutter_sdk_helper.dart) can no longer have its errors misattributed to (and collected by) the SDK. AuthorizationStatusparsing (Android). The native side reports snake_case statuses (always,when_in_use,not_determined…); the Dart enum now parses them correctly instead of falling back tonotDetermined, sogetAuthorizationStatus()reflects the real permission state on Android.
Changed #
-
requestPermissions()/checkPermissions()semantics on Android 12+ (behavior change). Both now mirror the native 3.4.5 scan gate: onlyBLUETOOTH_SCAN("Nearby devices") unlocks detection — location alone is no longer treated as sufficient, so an app that only holds location permissions now getsfalsewhere it previously gottrue. This reflects reality: since the manifest assertsneverForLocation, the OS never delivered scan results to the location-only path anyway; the oldtruewas a false positive that masked "no beacons detected" complaints. On Android <12 the legacy location-based gate is unchanged. -
Bumped native SDKs to 3.4.5 (Android + iOS). Android: DX audit + error telemetry + never-crash-the-host hardening (safe no-op on blank token; graceful degradation on devices without a Bluetooth radio) + two crash/robustness fixes — (1) a second FGS crash mode (
ForegroundServiceStartNotAllowedException, started from the background on Android 14+; the 3.4.4 fix only covered the permission-missingSecurityException); (2)checkPermissionsnow requiresBLUETOOTH_SCANon Android 12+, so the location-only path stops attempting a scan the OS blocks (no more caught-SecurityExceptionlog spam). iOS: DX audit + error telemetry + never-crash-the-host hardening (CoreBluetooth state restoration gated on the host'sbluetooth-centralbackground mode) (BearoundSDK pin 3.4.2 → 3.4.5).
3.4.4 - 2026-07-01 #
Changed #
- Bumped native Android SDK to 3.4.4. Brings two Android improvements to Flutter apps: (1) a crash fix — the SDK no longer crashes with
SecurityException/crash-loop when the user denies "Nearby devices" while foreground scanning is enabled on Android 14+; (2) background-reliability helpers (battery-optimization exemption + OEM autostart deep-links, no location, no Google Play policy impact). The crash fix is automatic (no Dart change); the reliability helpers are native-only for now (not yet exposed on the Flutter method channel).
3.4.3 - 2026-07-01 #
Added #
- iOS: notificação local ao processar silent push. O plugin agora exibe uma notificação "Push → Scan" quando o SDK trata um silent push do backend (callback
didCompletePushScan), espelhando o app nativoBeAroundScan. Depende da configuração de push no app cliente — ver a seção "Push notifications & background wakeup" no README.
Changed #
- README: guia de setup de push notifications & background wakeup (iOS). Documenta como habilitar silent push e region/beacon wakeup no Flutter 3.41+: entitlement
aps-environment,remote-notificationnoUIBackgroundModes, a desativação da UIScene (_UIApplicationSceneManifest) e o override dodidReceiveRemoteNotificationque contorna o flutter#155479. Oexample/é a implementação de referência (validada em device iOS 26). SDK nativo inalterado (BearoundSDK 3.4.2).
3.4.2 - 2026-06-27 #
Fixed #
- Android: removidas
USE_EXACT_ALARMeSCHEDULE_EXACT_ALARM(via SDK nativo 3.4.2). O SDK não é app de "agenda"/"despertador" e não qualifica para alarme exato no Google Play (a Play Console exige a remoção, senão pede a declaração de "Alarmes exatos"). O watchdog de scan passou a usar alarme inexato (setAndAllowWhileIdle) — o scan periódico (WorkManager + watchdog) continua funcionando, sem permissão de alarme exato. iOS não afetado.
3.4.1 - 2026-06-27 #
Fixed #
- Push token à prova de ordem (SDKs nativos iOS/Android 3.4.1).
setPushToken, quando o scan já está ativo e o token ainda não foi enviado, força um register na hora (beacons:[]+ token) em vez de esperar o próximo sync. O token chega ao backend independente de o app chamarsetPushTokenantes ou depois destartScanning— antes, se o register-on-init já tivesse ocorrido, o device ficava sem push até o próximo register (TTL) ou até detectar um beacon. - Android: push token agora é encaminhado ao SDK nativo. O handler
setPushTokendo wrapper Android descartava o token (no-op herdado de quando o SDK Android não tinha o setter); agora chamaBeAroundSDK.setPushToken(disponível no nativo Android ≥ 3.4.0), então o token fornecido pelo app chega ao backend. iOS já encaminhava. - Doc de
setPushToken: no iOS, prefira o token APNs cru (getAPNSToken()) — é o que o backend usa; o swizzle automático falha quando o Firebase está presente.
3.4.0 - 2026-06-26 #
Added #
- Device register on init (via native SDKs 3.4.0). The device reports to the backend on
startScanning()even before detecting a beacon, so it appears in the Control Hub on first launch. No API change — handled by the native SDK. - Scan modes documentation. README documents the two Android background-scan strategies (opportunistic vs
connectedDeviceforeground service) with trade-offs, scan-window cadence, and a WorkManager note.
Changed #
- Foreground-service notification. Title defaults to the host app's own name (
android:label, localized by the device); subtitle is a generic, localized string ("Atualizando conteúdo" / "Updating content") — no Bluetooth or "reading data" wording. Clients can still override both. - Bumped native SDKs to 3.4.0 (Android
bearound-android-sdk, iOSBearoundSDK).
3.3.1 - 2026-06-11 #
Changed #
-
Native SDKs bumped to 3.3.1 (both platforms). Three correctness fixes around BLE zone presence:
- Phantom zone exit→enter flap (~1ms apart, every 5-10 min, device stationary inside zone) — cleanup-immune
lastBeaconSeenAt+ grace bumped 60s → 300s. - iOS-only: CoreLocation daemon churn → BLE delivery stalls. Five
CLLocationManager()throwaways replaced with a single lifetime-scoped instance. - Phantom ENTER after OS termination + state restoration (iOS) / PendingIntent wake (Android). Zone state persisted to UserDefaults / SharedPreferences and restored on cold start; snapshots > 1h are stale and ignored.
Pins:
- iOS:
BearoundSDK 3.3.1 - Android:
com.github.Bearound:bearound-android-sdk:3.3.1
No bridge-level changes — pure native bump. See native CHANGELOGs for root-cause details.
- Phantom zone exit→enter flap (~1ms apart, every 5-10 min, device stationary inside zone) — cleanup-immune
3.3.0 - 2026-06-10 #
Added #
sdk.technologyfield in the/ingestpayload, identifying the originating SDK across the suite (ios-native|android-native|react-native|flutter). The Flutter bridge always reportsfluttervia a hardcoded native constant — it is not aconfigure()parameter and is not versioned.
Changed #
- Native SDKs aligned to v3.3.0 ("two eyes" alignment across the suite):
- Android:
com.github.Bearound:bearound-android-sdk:3.3.0 - iOS:
BearoundSDK 3.3.0
- Android:
- Version is now a single source of truth: the iOS podspec
(
ios/bearound_flutter_sdk.podspec) readss.versiondirectly frompubspec.yaml— there is no longer a version literal to keep in sync in the podspec.
2.4.0 - 2026-05-22 #
⚠️ Breaking Changes #
configure()API: replacedforegroundScanIntervalandbackgroundScanInterval(ForegroundScanInterval/BackgroundScanIntervalenums) with a single unifiedscanPrecision: ScanPrecisionparameter, matching the native iOS/Android v2.4.0 API.- Before:
BearoundFlutterSdk.configure(businessToken: ..., foregroundScanInterval: ForegroundScanInterval.seconds15, backgroundScanInterval: BackgroundScanInterval.seconds30, maxQueuedPayloads: ...) - After:
BearoundFlutterSdk.configure(businessToken: ..., scanPrecision: ScanPrecision.medium, maxQueuedPayloads: ...)
- Before:
- The
ForegroundScanIntervalandBackgroundScanIntervalenums have been removed. Migrate toScanPrecision.high/medium/low.
Changed #
- Native SDKs bumped to v2.4.0:
- Android:
com.github.Bearound:bearound-android-sdk:2.4.0(dropped legacyvprefix per JitPack cache compat) - iOS:
BearoundSDK ~> 2.4.0
- Android:
- Location is now strictly beacon-gated (mirrors native v2.4.0 doctrine). GPS and active BLE scanning only run while the device is inside a beacon region. Outside the region, only kernel-level region monitoring stays on — effectively zero battery cost.
Added #
- 3 new event channels surfaced from the native SDKs:
bearound_flutter_sdk/beacon_region— region enter/exit transitionsbearound_flutter_sdk/active_scan— active scanning toggle statebearound_flutter_sdk/location_capture— beacon-triggered GPS window lifecycle (started/completed)
- 3 new Dart streams on
BearoundFlutterSdk:beaconRegionStream→Stream<BeaconRegionEvent>(withisEnter/isExithelpers)activeScanStream→Stream<ActiveScanEvent>(isActiveboolean)locationCaptureStream→Stream<LocationCaptureResult>(discriminated byisStarted/isCompleted)
- New models:
LocationCaptureResult,CapturedLocation,BeaconRegionEvent,ActiveScanEvent,ScanPrecision. - Example app gains a Debug Geofence card (visible in the Status tab) showing GPS policy banner (green ✅ / red ⛔), live entry/exit timestamps with 1Hz ticking ages, capture counter, last fix coordinates, and a rolling 30-event log with color-coded chips.
Battery impact #
For apps that spend most of their time outside any beacon region, this release drops CoreLocation + BLE active duty cycle to ~0 outside the region. Expect noticeable battery savings on users who carry the app but rarely encounter beacons.
2.3.7 - 2026-02-26 #
Changed #
- Native SDKs Updated to v2.3.7:
- Android:
com.github.Bearound:bearound-android-sdk:v2.3.7 - iOS:
BearoundSDK ~> 2.3.7
- Android:
2.3.6 - 2026-02-20 #
Changed #
- Native SDKs Updated to v2.3.6:
- Android:
com.github.Bearound:bearound-android-sdk:v2.3.6 - iOS:
BearoundSDK ~> 2.3.6
- Android:
2.3.5 - 2026-02-19 #
Changed #
- Native SDKs Updated to v2.3.5:
- Android:
com.github.Bearound:bearound-android-sdk:v2.3.5 - iOS:
BearoundSDK ~> 2.3.5
- Android:
- Documentation: Updated README to reflect native SDK v2.3.5 alignment and package version.
2.3.2 - 2026-02-19 #
Changed #
- Native SDKs Updated to v2.3.2:
- Android:
com.github.Bearound:bearound-android-sdk:v2.3.2 - iOS:
BearoundSDK ~> 2.3.2
- Android:
- Documentation: Updated README to reflect native SDK v2.3.2 alignment and package version.
2.3.1 - 2026-02-18 #
Changed #
- Native SDKs Updated:
- Android:
com.github.Bearound:bearound-android-sdk:v2.3.0 - iOS:
BearoundSDK ~> 2.3.0
- Android:
Added #
- Bluetooth-only (BT) proximity fallback: New
BeaconProximity.btvalue for beacons detected via Bluetooth scanning only, without CoreLocation/distance estimation.
Technical Details #
- Native SDK v2.3.0 Changes:
- Added BT proximity for bluetooth-only fallback detection
- Improved beacon structure with discovery source tracking
2.2.3 - 2026-01-22 #
Changed #
- Native SDKs Updated:
- Android:
com.github.Bearound:bearound-android-sdk:v2.2.2 - iOS:
BearoundSDK ~> 2.2.2
- Android:
Fixed #
- iOS Podspec Version Sync: Fixed podspec version that was out of sync with the package version.
Technical Details #
- Native SDK v2.2.2 Changes:
- Removed 1-second foreground scan interval option (minimum is now 5 seconds)
- 5-second foreground scan interval now uses continuous scanning (no pause between scans)
- Beacons are no longer cleared from internal state after being sent to the API
2.2.2 - 2026-01-21 #
Changed #
- iOS Permission Handling: Permissions are now requested via native Swift code using
CLLocationManager.requestAlwaysAuthorization(), matching the behavior of the iOS native SDK and React Native SDK. This eliminates the blue GPS indicator that appeared when using thelocationFlutter package.
Fixed #
-
iOS: Blue GPS indicator no longer appears: Removed dependency on the
locationFlutter package for iOS. Permissions are now handled natively via MethodChannel, which prevents the continuous location updates that caused the blue GPS indicator to appear. -
iOS: Permission flow aligned with native SDKs: The permission request now goes directly to "Always" authorization (like React Native and iOS native SDKs) instead of first asking for "When In Use" and then upgrading.
Removed #
- Removed
locationpackage dependency: Thelocationpackage is no longer used. iOS permissions are handled via native Swift code, and Android permissions continue to usepermission_handler.
Technical Details #
-
iOS Plugin (
BearoundFlutterSdkPlugin.swift):- Added
CLLocationManagerDelegateconformance - Added
requestPermissionsmethod that callsrequestAlwaysAuthorization()directly - Added
checkPermissionsmethod to verify current authorization status - Both methods mirror the React Native SDK's
RNBearoundBridge.swiftimplementation
- Added
-
Permission Service (
permission_service.dart):- iOS: Now uses
MethodChannelto call native Swift permission methods - Android: Continues using
permission_handlerpackage - Added
checkPermissions()method to the public API
- iOS: Now uses
2.2.1 - 2026-01-20 #
⚠️ Breaking Changes #
- Removed
syncStream: The countdown updates (secondsUntilNextSync,isRanging) have been removed to save battery. The native iOS SDK removed this callback, and we're aligning all SDKs. - Removed
SyncStatusmodel: No longer needed withoutsyncStream.
Fixed #
- iOS/Android: Auto-restored scan not respecting configuration: Fixed critical bug where if the SDK auto-restored scanning from a previous session, it would continue with the old configuration (continuous scan) instead of using the new configuration. The plugin now detects if SDK was already scanning during
configure(), stops it, applies the new configuration, and restarts with correct periodic scan settings. - Android: No beacons appearing: Fixed critical bug where the listener was not being properly set in
configure()andstartScanning()methods. The Android plugin now correctly redefines the listener to ensure beacon events are received even when the listener was previously overwritten by the Application class. - Android: Example app beacon detection blocked: Removed
android:usesPermissionFlags="neverForLocation"fromBLUETOOTH_SCANpermission in example app manifest. This flag was blocking iBeacon detection since beacons require location services. - iOS: App state synchronization: Added workaround to force the SDK to recognize the correct foreground state by posting
willEnterForegroundNotificationwhen starting scan in active state. This addresses a potential race condition where the BeaconManager might have been initialized with incorrect foreground state. - Flutter Example: Duplicate scan initialization: Removed duplicate
configure()call in_startScan()method that was causing the scan to restart twice in rapid succession.
Changed #
- Native SDKs Updated:
- Android:
com.github.Bearound:bearound-android-sdk:v2.2.1 - iOS:
BearoundSDK ~> 2.2.1
- Android:
Technical Details #
-
Both iOS and Android Plugins:
- Added logic in
configure()to detect if SDK was already scanning (auto-restored) - If SDK was scanning, stops it, applies new config, and restarts with correct settings
- This ensures periodic scan configuration is always applied correctly
- Cleaned up diagnostic logs - keeping only essential error logging
- Added logic in
-
Android Plugin:
- Re-assigns listener in both
configure()andstartScanning()methods - This ensures Flutter plugin always receives callbacks even if Application class overwrites listener
- Maintains error logging for debugging
- Re-assigns listener in both
-
iOS Plugin:
- Posts
willEnterForegroundNotificationwhen starting scan in active state - This forces SDK to correctly recognize foreground state and apply periodic scan configuration
- Syncs
isActiveScanwith SDK state to handle auto-restored scanning
- Posts
2.2.0 - 2026-01-20 #
⚠️ Breaking Changes #
Simplified Configuration: Bluetooth metadata and periodic scanning are now automatic. The enableBluetoothScanning and enablePeriodicScanning parameters have been removed from the configure() method.
Added #
-
NEW Streams for Better Control:
syncLifecycleStream: Notifies when sync operations start and completeonSyncStarted(beaconCount): Called before starting a synconSyncCompleted(beaconCount, success, error): Called after sync completes
backgroundDetectionStream: Notifies when beacons are detected in backgroundonBeaconDetectedInBackground(beaconCount): Called when beacons detected while app is in background
-
New Models:
SyncLifecycleEvent: Represents sync lifecycle events with type, beaconCount, success, and error fieldsBackgroundDetectionEvent: Represents background detection events with beaconCount
Changed #
-
Automatic Features:
- Bluetooth metadata collection is now always enabled (no need to configure)
- Periodic scanning is automatic:
- Foreground: Enabled (saves battery)
- Background: Continuous (maximum detection)
-
Native SDKs Updated:
- Android:
com.github.Bearound:bearound-android-sdk:v2.2.1 - iOS:
BearoundSDK ~> 2.2.1
- Android:
-
Platform Improvements:
- Android: Renamed
BeAroundSDKDelegatetoBeAroundSDKListener(Android naming convention) - Android: Changed callback prefix from
did*toon*(e.g.,didUpdateBeacons→onBeaconsUpdated) - iOS: Added new callbacks while maintaining
did*prefix (iOS convention)
- Android: Renamed
Removed #
enableBluetoothScanningparameter fromconfigure()method (now automatic)enablePeriodicScanningparameter fromconfigure()method (now automatic)setBluetoothScanning()method (no longer needed)
Migration #
Before (v2.1.0):
await BearoundFlutterSdk.configure(
businessToken: 'your-token',
enableBluetoothScanning: true,
enablePeriodicScanning: true,
);
After (v2.2.0):
// Simpler configuration
await BearoundFlutterSdk.configure(
businessToken: 'your-token',
// Bluetooth metadata and periodic scanning are automatic
);
// NEW: Listen to sync lifecycle
BearoundFlutterSdk.syncLifecycleStream.listen((event) {
if (event.isStarted) {
print('📤 Sync started: ${event.beaconCount} beacons');
} else if (event.isCompleted) {
if (event.success == true) {
print('✅ Sync success: ${event.beaconCount} beacons sent');
} else {
print('❌ Sync failed: ${event.error}');
}
}
});
// NEW: Listen to background detections
BearoundFlutterSdk.backgroundDetectionStream.listen((event) {
print('🌙 Background: ${event.beaconCount} beacons detected');
});
Technical Details #
- Improved code deduplication in native Android SDK
- Better async handling for device info collection
- iOS SDK updated with new callback structure
- All callbacks now have debug logging support
2.1.0 - 2026-01-13 #
⚠️ Breaking Changes #
Configurable Scan Intervals: SDK now supports separate foreground and background scan intervals with configurable retry queue.
Added #
-
Configurable Scan Intervals: New enums for fine-grained control over scan behavior
ForegroundScanInterval: Configure foreground scan intervals from 5 to 60 seconds (in 5-second increments)BackgroundScanInterval: Configure background scan intervals (15s, 30s, 60s, 90s, or 120s)- Default: 15 seconds for foreground, 30 seconds for background
-
Configurable Retry Queue: New
MaxQueuedPayloadsenum to control retry queue size.small(50 failed batches).medium(100 failed batches) - default.large(200 failed batches).xlarge(500 failed batches)- Replaces fixed limit with configurable options
- Each batch can contain multiple beacons from a single sync
Changed #
-
Configuration API:
configure()method now accepts enum parameters instead ofDurationforegroundScanInterval: ForegroundScanInterval = ForegroundScanInterval.seconds15backgroundScanInterval: BackgroundScanInterval = BackgroundScanInterval.seconds30maxQueuedPayloads: MaxQueuedPayloads = MaxQueuedPayloads.medium- Old
syncIntervalparameter removed in favor of separate foreground/background intervals
-
Dynamic Interval Switching: SDK now automatically switches between foreground and background intervals based on app state (iOS only for now)
-
Improved Resilience: Increased default retry queue from fixed size to 100 failed batches
-
Native SDKs: Updated to version 2.1.0
- iOS:
BearoundSDK ~> 2.1.0 - Android:
com.github.Bearound:bearound-android-sdk:v2.1.0
- iOS:
Migration #
Before (v2.0.1):
await BearoundFlutterSdk.configure(
businessToken: 'your-business-token-here',
syncInterval: const Duration(seconds: 30),
);
After (v2.1.0):
// Using defaults (recommended)
await BearoundFlutterSdk.configure(
businessToken: 'your-business-token-here',
);
// Custom configuration
await BearoundFlutterSdk.configure(
businessToken: 'your-business-token-here',
foregroundScanInterval: ForegroundScanInterval.seconds30,
backgroundScanInterval: BackgroundScanInterval.seconds90,
maxQueuedPayloads: MaxQueuedPayloads.large,
);
Platform Support #
- ✅ iOS: Fully supports all new features with native SDK 2.1.0
- ✅ Android: Fully supports all new features with native SDK 2.1.0
Technical Details #
- Scan duration formula unchanged:
scanDuration = max(5, min(syncInterval / 3, 10)) - Backoff retry logic unchanged: exponential backoff with max 60s delay
- All existing scanning and sync behaviors preserved
- Type-safe enum-based configuration for better developer experience
2.0.1 - 2026-01-07 #
⚠️ Breaking Changes #
Authentication Update: SDK now requires business token instead of appId for authentication.
Changed #
- API:
configure()now requiresbusinessTokenparameter (replacesappId) - Auto-detection:
appIdautomatically extracted from package/bundle identifier - Authorization: Business token sent in
Authorizationheader for all API requests - Native SDKs: Updated to version 2.0.1
- Android:
com.github.Bearound:bearound-android-sdk:v2.0.1 - iOS:
BearoundSDK ~> 2.0.1
- Android:
Migration #
Before (v2.0.0):
await BearoundFlutterSdk.configure(
appId: 'com.example.app',
syncInterval: const Duration(seconds: 30),
);
After (v2.0.1):
await BearoundFlutterSdk.configure(
businessToken: 'your-business-token-here',
syncInterval: const Duration(seconds: 30),
);
// Note: appId is now automatically extracted from package/bundle identifier
2.0.0 - 2026-01-15 #
Added #
- New Flutter API aligned to the native SDK 2.0.0 (
configure,startScanning,stopScanning). - Streamed updates for beacons, sync status, scanning state, and errors.
- New beacon/metadata models matching native SDK fields.
- User properties support (
setUserProperties,clearUserProperties).
Changed #
- Updated Android native dependency to
com.github.Bearound:bearound-android-sdk:2.0.0. - Updated iOS native dependency to
BearoundSDK ~> 2.0.0. - Android minimum SDK is now 23; iOS minimum is 13.0.
- Plugin channel payloads updated to match v2 delegate events.
Removed #
- Legacy 1.x API surface (client token initialization, backup size, legacy sync success/error events, region events).
1.3.1 - 2025-12-22 #
Added #
- Configurable Scan Interval: Set beacon scan frequency from 5 to 60 seconds via
setSyncInterval()- Balance between battery consumption and detection speed
- Available intervals: TIME_5, TIME_10, TIME_15, TIME_20 (default), TIME_25, TIME_30, TIME_35, TIME_40, TIME_45, TIME_50, TIME_55, TIME_60
- Configurable Backup Size: Set failed beacon backup list size from 5 to 50 beacons via
setBackupSize()- Control how many failed beacon detections are stored for retry
- Available sizes: SIZE_5 through SIZE_50, default SIZE_40
- Configuration Methods: Added
getSyncInterval()andgetBackupSize()to retrieve current settings - Settings UI: Added comprehensive settings screen in example app with gear icon in app bar
- Visual configuration of scan intervals and backup sizes
- Usage recommendations for different scenarios (real-time tracking, battery optimization, offline-first)
- Real-time feedback and configuration updates
- Configuration Enums: New
SyncIntervalandBackupSizeenums for type-safe configuration - Smart Beacon Filtering: Automatically filters invalid beacons (RSSI = 0) to improve data quality
- Improved iOS Integration: Updated to use singleton pattern with
Bearound.configure()method
Changed #
- Updated iOS BearoundSDK dependency to version 1.3.1 with:
- 🎨 Modular Architecture: Complete project reorganization for better maintainability
- 📊 Enhanced Telemetry: Comprehensive device information collection
- 🔋 Battery Optimized: Smart location accuracy settings
- ✅ RSSI Validation: Improved beacon filtering (-120 to -1 dBm)
- 🧪 Full Test Coverage: Comprehensive unit test suite
- Updated Android BearoundSDK dependency to version 1.3.1 with:
- 🔍 Smart Beacon Filtering: Automatically filters invalid beacons (RSSI = 0)
- ⚙️ Configurable Scan Intervals: Customizable beacon scan frequency
- 📦 Configurable Backup List Size: Control failed beacon storage
- 🎉 Enhanced Event Listener System: BeaconListener, SyncListener, RegionListener
- iOS SDK Initialization: Changed from
Bearound(clientToken:isDebugEnable:)toBearound.configure(clientToken:isDebugEnable:)(singleton pattern) - iOS Plugin Architecture: Implemented Task-based async initialization for reliable permission handling
- Enhanced example app with interactive configuration UI featuring:
- Current settings display with visual indicators
- Quick selection chips for all interval and backup size options
- Usage recommendations for different scenarios
- Real-time configuration updates
Performance Improvements #
- iOS: Async/await pattern ensures proper initialization sequence and reliable beacon detection
- Memory Management: Removed all debug print statements from iOS plugin to reduce overhead
- Event Handling: Optimized listener callbacks to dispatch events efficiently on main thread
Technical Details #
- iOS:
- Supports sync intervals from 5-60 seconds and backup sizes from 5-50 beacons
- Both configurable at runtime (can be changed dynamically)
- Configuration persisted across app restarts
- SDK now uses singleton pattern for better lifecycle management
- Android:
- Supports sync intervals from 5-60 seconds and backup sizes from 5-50 beacons
- Sync interval can be changed dynamically at runtime
- Backup size must be set before
initialize()on Android - Configuration persisted across app restarts
Configuration Recommendations #
| Scenario | Sync Interval | Backup Size | Reason |
|---|---|---|---|
| Real-time tracking | TIME_5 - TIME_10 | SIZE_15 - SIZE_20 | Immediate updates, lower backup needed |
| Standard monitoring | TIME_20 - TIME_30 (⭐ default) | SIZE_30 - SIZE_40 | Balanced performance and battery |
| Battery-optimized | TIME_40 - TIME_60 | SIZE_40 - SIZE_50 | Longer intervals, larger backup for reliability |
| Offline-first apps | TIME_30 - TIME_60 | SIZE_50 | Handle poor network conditions |
API Changes #
- Added
BearoundFlutterSdk.setSyncInterval(SyncInterval)- Configure scan frequency - Added
BearoundFlutterSdk.setBackupSize(BackupSize)- Configure backup list size - Added
BearoundFlutterSdk.getSyncInterval()- Get current sync interval - Added
BearoundFlutterSdk.getBackupSize()- Get current backup size
Fixed #
- Critical iOS Initialization Bug: Fixed beacon detection issue where
startServices()was called before permissions were granted- SDK now properly waits for
requestPermissions()to complete using async/await pattern - Matches the working pattern from native iOS SDK example
- Ensures CoreLocation and CoreBluetooth are properly authorized before starting services
- Resolves issue where beacons were not being detected on iOS despite successful initialization
- SDK now properly waits for
- iOS Event Listeners: Improved listener registration to ensure events are properly captured from native SDK
Breaking Changes #
- None - This release is backward compatible with 1.2.x versions
1.2.0 - 2025-12-08 #
Changed #
- Updated iOS BearoundSDK dependency to version 1.2.0
- Updated Android BearoundSDK dependency to version 1.2.0
1.0.0 TBD #
Added #
- Initial release of Bearound Flutter SDK
- Beacon scanning functionality for Android and iOS
- Permission management for location and Bluetooth
- Comprehensive unit test suite
- CI/CD pipeline with GitHub Actions
- Automatic release workflow
Features #
- BearoundFlutterSdk: Main facade for SDK operations
- BeaconScanner: Core beacon scanning functionality
- PermissionService: Cross-platform permission handling
- Beacon Model: Data model for beacon information
- Method Channel: Native platform communication
Documentation #
- API documentation with dart doc
- Usage examples
- Setup instructions
Testing #
- Unit tests with 25 test cases
- CI pipeline validation
- Code coverage reporting
1.0.1 - 2024-09-11 #
Added #
- Comprehensive pre-commit hooks configuration
- Automated code quality enforcement (format, analyze, test)
- Security checks with detect-secrets
- Conventional commit message validation
- Setup script for easy pre-commit installation
Changed #
- Updated Flutter version to 3.35.2 in CI/CD pipelines
- Enhanced documentation with pre-commit hooks guide
- Improved developer workflow with quality automation
Fixed #
- Removed references to unimplemented stream functionality from README
- Corrected API documentation to match actual implementation
1.0.3 - 2025-09-17 #
Changed #
- Migrated iOS dependency from xcframework to official CocoaPods repository
- Updated BeAround dependency to use official CocoaPods spec
- Migrated Android dependency from local .aar files to official JitPack Maven repository
- Updated Android SDK dependency to use
com.github.Bearound:bearound-android-sdk:v1.0.3 - Improved iOS and Android integration with standardized dependency management
Fixed #
- Resolved iOS build issues related to framework distribution
- Resolved Android build issues related to local .aar dependencies
- Enhanced compatibility with standard CocoaPods and Maven workflows
1.1.0 - 2025-10-24 #
Added #
- Event Listeners System: Comprehensive event listener architecture aligned with native iOS and Android SDKs
BeaconListener- Real-time beacon detection callbacks with event types (enter/exit/failed)SyncListener- API synchronization status monitoring (success/error events)RegionListener- Beacon region entry/exit notifications
- EventChannel Streams: Three dedicated EventChannels for real-time event streaming
beaconsStream- Stream of detected beacons with event typessyncStream- Stream of API sync success/error eventsregionStream- Stream of region enter/exit events
- Enhanced Beacon Model: Added
lastSeenfield (timestamp in milliseconds) - Detailed Debug Logging: Added comprehensive logging in Android plugin for easier troubleshooting
- Redesigned Example App: New tabbed interface with three sections:
- Beacons tab: Real-time beacon list with region status
- Sync tab: API synchronization status display
- Logs tab: Console with timestamped event logs (max 50 entries)
Changed #
- Region Events Structure:
BeaconRegionEnterEventandBeaconRegionExitEventnow useregionNameinstead of beacon list - Sync Events Enhancement:
SyncSuccessEventnow includesmessagefield with server responseSyncErrorEventnow includes optionalerrorCodefield
- Android Permission Handling: More flexible permission logic - requires location OR bluetooth (not both)
- Android SDK Manifest: Declared all required permissions in SDK manifest for proper merge
- iOS Beacon Parsing: Implemented Mirror-based reflection to safely access internal Beacon properties
- Type Casting: Improved type safety with explicit
Map<String, dynamic>.from()conversions
Fixed #
- iOS UUID Conversion: Fixed UUID type casting by converting
Foundation.UUIDtoStringusing.uuidString - iOS Distance Conversion: Fixed
Optional<Float>toDoubleconversion fordistanceMeters - iOS Major/Minor Types: Handle both
StringandInttypes from native SDK - Android Bluetooth Permissions: Added missing
BLUETOOTHandBLUETOOTH_ADMINpermissions to SDK manifest - Android Beacon Scanning: Removed
neverForLocationflag that was blocking beacon detection - Android Permission Inspector Errors: Resolved all permission-related warnings in beacon scanning
- Type Cast Errors: Fixed
Map<Object?, Object?>toMap<String, dynamic>casting issues in event streams
Infrastructure #
- Git Cleanup: Removed
.idea/directories from repository and added to.gitignore - Android Gitignore: Updated to ignore entire
.idea/directory instead of individual files - Root Gitignore: Added comprehensive IDE exclusions (IntelliJ IDEA, VSCode)
Documentation #
- API Documentation: Added comprehensive documentation for all new stream getters
- Usage Examples: Included examples for all three listener types in code comments
- BeaconData Model: Documented all fields including new
lastSeentimestamp
1.1.1 - 2025-11-24 #
Fixed #
- State Synchronization Bug: Fixed critical issue where app state became desynchronized with native SDK after closing and reopening the app
- Android plugin now checks
BeAround.isInitialized()before re-initializing, preventing initialization errors - When SDK is already initialized, plugin reuses existing instance and re-registers listeners
- Added
isInitialized()method to query SDK state from Flutter - Example app now implements
WidgetsBindingObserverto sync UI state when app resumes - Background notification now stays consistent with UI state
- Android plugin now checks
- Native Listeners Reconnection: Fixed issue where beacon events stopped being received after reopening the app
- Native listeners are now properly re-registered when app detects SDK running in background
_syncStateWithNative()callsstartScan()again to restore native event flow- Both Flutter streams and native listeners are reconnected seamlessly
Added #
- State Query Method: New
BearoundFlutterSdk.isInitialized()method to check if SDK is currently running- Useful for restoring correct UI state when app is reopened
- Example usage in app lifecycle management
- Lifecycle Management: Example app demonstrates proper state synchronization using
WidgetsBindingObserver
Changed #
- Android Initialization Logic:
initializemethod now handles already-initialized state gracefully- Logs warning when reusing existing instance
- Re-registers event listeners to ensure Flutter receives events
- No error thrown on re-initialization attempts
1.1.2 - 2025-11-26 #
Changed #
- iOS Native SDK Update: Updated BearoundSDK iOS dependency from 1.1.0 to 1.1.1
- iOS Permission Handling: Added automatic
requestPermissions()call during SDK initialization- Permissions are now requested automatically when initializing the SDK on iOS
- Improves user experience by ensuring proper permissions setup
Infrastructure #
- Updated Flutter SDK version to 1.1.2
- Updated podspec version to align with SDK versioning
[Unreleased] #
Planned #
- Advanced beacon filtering options
- Enhanced background scanning capabilities
- Performance optimizations
- Battery optimization strategies