adonna 0.1.1+1
adonna: ^0.1.1+1 copied to clipboard
Flutter plugin that wraps FeasyBeacon Android/iOS SDKs (scan/connect/control beacons).
Adonna – FeasyBeacon Flutter Plugin #
Adonna is a Flutter plugin that wraps Feasycom’s FeasyBeacon SDKs for Android and iOS, providing a clean Dart API to scan, configure, and update BLE beacons (iBeacon, Eddystone, AltBeacon). It also includes an Android background monitor that detects the beacon button press pattern (fast advertising interval) and triggers a local notification with the phone’s last-known location.
- FeasyBeacon Android SDK docs: https://document.feasycom.com/web/#/130/955
- FeasyBeacon iOS SDK docs: https://document.feasycom.com/web/#/130/954
Status: actively developed. Android supports scan, background monitor, device params, CRUD, OTA, and streams. iOS supports scan, connect/disconnect, parameters, CRUD, OTA, packets, device info streams.
Supported platforms #
| Platform | Scanning | Background monitor | Connect/Config | Beacon CRUD | OTA | Streams (scan/ota/device/packet) |
|---|---|---|---|---|---|---|
| Android | Yes | Yes (foreground service) | Yes | Yes | Yes | Yes |
| iOS | Yes | Not implemented | Yes | Yes | Yes | Yes |
Features #
- Scan for beacons (Android + iOS)
- Android background monitoring service (foreground notification)
- Detects faster advertising interval (~100 ms) after a button press, for ~35 seconds
- Emits events and shows a notification with last-known location
- Device connectivity and configuration (Android)
- connect/disconnect, set name, pin, interval, TLM, broadcast extensions, firmware/app keys, save
- beacon config add/delete/save; fetch broadcast parameters
- OTA firmware (Android)
- Validate DFU file; start OTA; progress stream
- Streams (Android + iOS where applicable)
- scanStream, packetStream, deviceInfoStream, otaProgressStream
- iOS helpers
- Decrypt key setup (128-bit)
- iBeacon UUID filter get/set
Install #
Add to your app’s pubspec.yaml:
dependencies:
adonna: ^0.1.0
permission_handler: ^11.3.1 # Recommended for runtime permissions
Quick Start #
import 'package:adonna/adonna.dart';
// Start scanning (Android + iOS)
await FeasyBeacon.startScan();
final scanSub = FeasyBeacon.scanStream.listen((e) {
// e: {address?, name?, rssi, hasIBeacon, hasEddystone, hasAltBeacon}
});
// Android background monitoring
await FeasyBeacon.startBackgroundMonitoring(config: {
'fastThresholdMs': 300,
'slowBaselineMs': 800,
'notificationTitle': 'Adonna Monitoring',
'notificationText': 'Listening for beacon button press',
});
final bgSub = FeasyBeacon.backgroundEvents.listen((e) {
// e: {address?, name?, rssi?, latitude?, longitude?}
});
// Connect and read device info (platform-supported)
final connected = await FeasyBeacon.connect(address: 'AA:BB:CC:DD:EE:FF', pin: '000000');
if (connected) {
final info = await FeasyBeacon.getDeviceInfo();
}
Android Setup #
- Target Android 12+ permissions as needed:
BLUETOOTH_SCAN,BLUETOOTH_CONNECTACCESS_COARSE_LOCATIONand/orACCESS_FINE_LOCATIONPOST_NOTIFICATIONS(Android 13+)- For background monitoring:
ACCESS_BACKGROUND_LOCATIONrecommended
- Background monitoring runs as a foreground service and displays a persistent notification.
Permissions example (manifest excerpt):
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Request runtime permissions (example using permission_handler):
await [
Permission.bluetoothScan,
Permission.bluetoothConnect,
Permission.location,
Permission.notification,
].request();
iOS Setup #
- Add the following keys to your
Info.plist:NSBluetoothAlwaysUsageDescriptionNSBluetoothPeripheralUsageDescriptionNSLocationWhenInUseUsageDescriptionNSLocationAlwaysAndWhenInUseUsageDescription
- Background monitoring is not implemented on iOS (API returns NotImplemented).
- iOS helpers:
// Optional: set 128-bit decrypt key
final ok = await FeasyBeacon.setupDecryptKey(your16ByteKey);
// Optional: filter iBeacon UUIDs
await FeasyBeacon.setIBeaconUUIDs(['xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx']);
final uuids = await FeasyBeacon.getIBeaconUUIDs();
API Overview #
Scanning
startScan(),stopScan()scanStream: emits{ address?, name?, rssi, hasIBeacon, hasEddystone, hasAltBeacon }
Background monitor (Android)
startBackgroundMonitoring({ fastThresholdMs, slowBaselineMs, notificationTitle, notificationText })stopBackgroundMonitoring()backgroundEvents: emits{ address?, name?, rssi?, latitude?, longitude? }
Connectivity & Parameters (Android + iOS*)
connect(address, { pin = '000000' }),disconnect(),isConnected()setDeviceName(name),setDevicePin(pin)setBroadcastInterval(intervalHex)setTlm(enabled)setBroadcastExtensions(enabled)setFirmwareKey(command),setAppKey(key)(Android)setTxPower(value),setGsensor(enabled),setKey(enabled),setPhy(value),setLongRange(enabled),setConnectable(on)saveBeaconInfo()
Beacon configuration (Android + iOS*)
addBeaconInfo({...})// supports iBeacon/Eddystone/AltBeacon fieldsdeleteBeaconInfo(index)beaconBroadcastParameters()getDeviceInfo(isTxPower: true|false)restore()
OTA (Android + iOS*)
checkDfuFile(dfuBytes)→ boolstartOtaUpdate(dfuBytes, { reset = false })→ boolotaProgressStream→ int (0..100)
Streams (Android + iOS)
packetStream:{ str, hex, raw, timestamp }deviceInfoStream:{ name, value }
iOS helpers
setupDecryptKey(key128)→ boolsetIBeaconUUIDs(uuids)/getIBeaconUUIDs()
Example App #
An example app is included under example/. It shows scan controls, background monitoring (Android), connect/disconnect, device info loading, and an OTA starter.
Expected test flow:
- Start Scan → tap a device in the list to select it (name often shows as “Unknown”), Stop Scan to keep the list stable
- Enter PIN (default
000000) → Connect → Get Info - Start Background → briefly press the beacon’s button (fast interval ~100ms for ~35s) → observe a local notification with location and an event in the app
- Stop Background → Disconnect
Notes:
- The scan list updates frequently and may reorder while scanning; Stop Scan before connecting for a stable list.
- iOS background monitoring is intentionally unimplemented and returns
unimplemented.
API Table (condensed) #
| Group | Method | Platforms |
|---|---|---|
| Scan | startScan(), stopScan(), scanStream |
Android, iOS |
| Background | startBackgroundMonitoring(config), stopBackgroundMonitoring(), backgroundEvents |
Android (iOS: unimplemented) |
| Connect | connect(address, {pin}), disconnect(), isConnected() |
Android, iOS |
| Params | setDeviceName, setDevicePin, setBroadcastInterval, setTlm, setBroadcastExtensions, setTxPower, setGsensor, setKey, setPhy, setLongRange, setConnectable |
Android, iOS* (some platform-specific) |
| Beacon CRUD | addBeaconInfo(map), updateBeaconInfo(map, index), deleteBeaconInfo(index), getBeaconInfo(index), beaconBroadcastParameters() |
Android, iOS |
| OTA | checkDfuFile(bytes), startOtaUpdate(bytes, {reset}), otaProgressStream |
Android, iOS |
| Streams | packetStream, deviceInfoStream |
Android, iOS |
| iOS Helpers | setupDecryptKey(key128), setIBeaconUUIDs(uuids), getIBeaconUUIDs() |
iOS |
* Some setters are not supported on iOS (e.g., setConnectable) and will return an unimplemented error.
Roadmap #
- iOS: expand optional setters support where applicable
- Vendor native binaries for pub.dev distribution and finalize packaging
- Expand tests and documentation
Troubleshooting #
- Android 12+: ensure
BLUETOOTH_SCANandBLUETOOTH_CONNECTpermissions are granted at runtime. - Background monitoring requires a foreground service notification and may require
ACCESS_BACKGROUND_LOCATIONdepending on OEM policies. - iOS background monitoring is not supported by this plugin and will return an
unimplementederror. - If
permission_handlerreports denied permissions, guide users to system settings.
Android Gradle Plugin 8.x and vendored AARs:
- AGP 8.x warns about direct local AARs in library modules. The plugin compiles with vendored SDKs, but some app builds may require explicit inclusion of AARs at the app level.
- If you see “Could not find :FeasyBeaconLibrary-release:” in your app, add the AARs/JAR to your app module as files() dependencies (see the example app
android/app/build.gradle.kts).
License #
- Plugin code: MIT (see LICENSE)
- Feasycom native SDKs are property of Feasycom. Verify licensing before redistribution in your app or a redistributed package.