abi_beacon 0.1.0 copy "abi_beacon: ^0.1.0" to clipboard
abi_beacon: ^0.1.0 copied to clipboard

PlatformAndroid

Android iBeacon background monitoring with a resilient foreground service, OEM manufacturer detection, and battery/permission state management.

abi_beacon #

pub package License: MIT

Android iBeacon background monitoring plugin for Flutter. Runs a resilient foreground service that keeps scanning when the app is closed, survives OEM battery killers, and handles Android Doze automatically.

Platform support: Android only (API 24+). iOS is not supported yet — the iOS implementation is a stub: its methods are no-ops and events never emits. Do not ship this plugin expecting iOS functionality.


Features #

  • Background monitoring — foreground service keeps scanning even when the app is closed or the screen is off
  • Region detectionEntryEvent / ExitEvent for iBeacon UUID regions, with optional major/minor filter
  • Ranging — continuous RangeEvent with RSSI and estimated distance per beacon per cycle
  • Sealed event stream — type-safe Dart 3 pattern matching across all event subtypes
  • OEM battery management — detects manufacturer family (Xiaomi, Huawei, Samsung, etc.) and deep-links to the right settings screen
  • Permission management — runtime permission requests with per-permission status tracking
  • Battery & power state — query Doze exemption, power save mode, and location services

Getting started #

Installation #

dependencies:
  abi_beacon: ^0.1.0

Your app's minSdkVersion must be 24 or higher (set in android/app/build.gradle).

Android permissions #

Most permissions ship inside the plugin's own manifest and are merged into your app automatically — you do not need to copy them. The plugin already declares: BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_SCAN, BLUETOOTH_CONNECT, ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION, FOREGROUND_SERVICE, FOREGROUND_SERVICE_LOCATION, POST_NOTIFICATIONS, WAKE_LOCK, RECEIVE_BOOT_COMPLETED, and REQUEST_IGNORE_BATTERY_OPTIMIZATIONS.

The foreground service runs with foregroundServiceType="location", so on Android 14+ it requires FOREGROUND_SERVICE_LOCATION — already declared by the plugin.

The only permission you must add yourself is background location, because it is sensitive and cannot be granted implicitly. Add it to your android/app/src/main/AndroidManifest.xml (inside <manifest>) if you need to keep scanning while the app is not in the foreground:

<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Background location runtime flow (Android 11+)

ACCESS_BACKGROUND_LOCATION cannot be requested in the same dialog as foreground location. The required flow is:

  1. Request foreground location first (AbiBeacon.requestPermissions() handles the standard permissions).
  2. Then request background location separately — on Android 11+ the OS does not show a dialog and instead sends the user to the app settings screen, where they must choose "Allow all the time". Explain this to the user before sending them there.

Without "Allow all the time", monitoring still works while the app is open but stops when it goes to the background.


Usage #

Basic setup #

import 'package:abi_beacon/abi_beacon.dart';

// 1. Request permissions
final perms = await AbiBeacon.requestPermissions();
if (!perms.allGranted) {
  // perms.deniedPermissions — list of what is still missing
  return;
}

// 2. Initialize with your beacon UUID
await AbiBeacon.initialize(BeaconConfig(
  uuid: 'B9407F30-F5F8-466E-AFF9-25556B57FE6D',
  // major: 100,   // optional — null = any
  // minor: 200,   // optional — null = any
  scanPeriod: const Duration(milliseconds: 1100),
  exitPeriod: const Duration(seconds: 4),
  notificationTitle: 'Beacon Monitor',
  notificationText: 'Scanning for beacons...',
));

// 3. Start the foreground service
await AbiBeacon.startMonitoring();

// 4. Listen to events
AbiBeacon.events.listen((event) => switch (event) {
  EntryEvent(:final timestamp)       => print('Entered region at $timestamp'),
  ExitEvent(:final timestamp)        => print('Exited region at $timestamp'),
  RangeEvent(:final beacons, :final nearest) => print('${beacons.length} beacons — nearest: $nearest'),
  ServiceStartedEvent()              => print('Service started'),
  ServiceStoppedEvent()              => print('Service stopped'),
  ErrorEvent(:final message)         => print('Error: $message'),
  UnknownEvent(:final rawType)       => print('Unknown event: $rawType'),
});

OEM battery optimization #

Manufacturers like Xiaomi, Huawei, Samsung, and OnePlus apply proprietary battery restrictions that can kill background services even when Android Doze exemption is granted. Use DeviceInfo to guide users to the right screen:

final info = await AbiBeacon.getDeviceInfo();

if (info.oem.isAggressive) {
  // Show a dialog explaining why the user needs to whitelist the app
  await AbiBeacon.openOemSetting(OemSettingType.autostart);
  await AbiBeacon.openOemSetting(OemSettingType.batterySaver);
}

// Also request standard Android Doze exemption
final isExempt = await AbiBeacon.isBatteryOptimizationDisabled();
if (!isExempt) {
  await AbiBeacon.requestDisableBatteryOptimization();
}

Checking current status #

final status = await AbiBeacon.getCurrentStatus();

print('Service running: ${status.isRunning}');
print('Region state: ${status.regionState}');   // inside / outside / unknown
print('Last event: ${status.lastEventTime}');
print('Nearest beacon: ${status.nearestBeacon}');

Stopping #

await AbiBeacon.stopMonitoring();

API reference #

AbiBeacon (static API) #

Lifecycle

Method Returns Description
initialize(BeaconConfig) Future<void> Persist beacon configuration. Call before startMonitoring.
startMonitoring() Future<bool> Start the foreground service. Returns true on success.
stopMonitoring() Future<bool> Stop the foreground service.
isMonitoring() Future<bool> true if the service is currently running.
getCurrentStatus() Future<MonitoringStatus> Snapshot of service state, region, and nearest beacon.
events Stream<BeaconEvent> Real-time stream of monitoring events.

Device state

Method Returns Description
getDeviceInfo() Future<DeviceInfo> Device info and detected OEM family.
getRequiredPermissions() Future<List<String>> Permissions required for this Android version.
checkPermissions() Future<PermissionsSnapshot> Current permission state without requesting.
requestPermissions() Future<PermissionsSnapshot> Request all required permissions from the user.
isBatteryOptimizationDisabled() Future<bool> true if Doze exemption is granted.
requestDisableBatteryOptimization() Future<void> Open system Doze exemption dialog.
isPowerSaveModeEnabled() Future<bool> true if global power save mode is active.
isLocationServiceEnabled() Future<bool> true if device location services are on.
openOemSetting(OemSettingType) Future<bool> Open a manufacturer settings screen. Returns true if opened.

BeaconEvent subtypes #

All events extend the sealed class BeaconEvent. Use Dart 3 pattern matching:

Subtype Key properties Triggered when
EntryEvent timestamp, regionId Device enters the monitored region
ExitEvent timestamp, regionId Device exits the monitored region
RangeEvent timestamp, beacons, nearest Ranging cycle completes (every scanPeriod)
ServiceStartedEvent timestamp Foreground service starts
ServiceStoppedEvent timestamp Foreground service stops
ErrorEvent timestamp, message Native layer reports an error
UnknownEvent timestamp, rawType Unrecognized event type (forward compat)

BeaconConfig #

Parameter Type Default Description
uuid String required iBeacon proximity UUID
major int? null Major filter. null = match any.
minor int? null Minor filter. null = match any.
scanPeriod Duration 1100ms Duration of each BLE scan cycle
exitPeriod Duration 4s No-signal time before firing ExitEvent. Min recommended: 3s
notificationTitle String 'iBeacon Monitor' Foreground service notification title
notificationText String 'Buscando beacon...' Foreground service notification body
notificationIcon String? null Drawable/mipmap resource name (e.g. 'ic_launcher')

OEM support #

Manufacturer OemFamily value isAggressive Notes
Xiaomi / MIUI xiaomi true Requires autostart + no battery restrictions
Huawei / EMUI huawei true Requires protected apps setting
Honor honor true Similar to Huawei
Samsung / One UI samsung true Requires disabling battery optimization
OnePlus oneplus true Requires autostart
OPPO / ColorOS oppo true Requires autostart
Realme realme true Requires autostart
Vivo / FuntouchOS vivo true Requires autostart
ASUS / ZenUI asus true Requires autostart
Stock Android stock false Standard Doze exemption is sufficient

Why abi_beacon? #

Most Flutter beacon packages wrap the AltBeacon Android library or similar native SDKs, which introduces two problems in production:

1. OEM battery killers are not handled #

Standard Android Doze exemption is not enough. Manufacturers like Xiaomi, Huawei, Samsung, and OnePlus ship proprietary battery managers that kill background services independently of Android's own Doze. This is the real reason beacon monitoring "works in the demo but fails for real users."

abi_beacon is the only Flutter beacon plugin that addresses this at the API level:

Other packages abi_beacon
Background foreground service Most do
Request Doze exemption Some do
Detect OEM manufacturer
Know if OEM is aggressive (isAggressive)
Deep-link to OEM autostart settings
Deep-link to OEM protected apps (Huawei/Honor)
Permissions + battery state in one package

2. License — MIT with AltBeacon notice #

abi_beacon is MIT licensed. However, the Android layer wraps AltBeacon android-beacon-library (org.altbeacon:android-beacon-library:2.20.5), which is Apache License 2.0.

This is the same situation as every other Flutter beacon plugin that uses AltBeacon. Apache 2.0 does not restrict commercial use, but it does require:

  • Including a copy of the Apache 2.0 license in your app's distribution
  • Including an attribution notice for AltBeacon

This is a known, well-understood requirement in the beacon ecosystem. Most enterprise legal teams approve Apache 2.0 dependencies without escalation.


Additional information #

0
likes
160
points
42
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Android iBeacon background monitoring with a resilient foreground service, OEM manufacturer detection, and battery/permission state management.

Repository (GitHub)
View/report issues

Topics

#ibeacon #bluetooth #beacon #background-service #ble

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on abi_beacon

Packages that implement abi_beacon