adonna 0.1.2
adonna: ^0.1.2 copied to clipboard
A Flutter plugin that wraps the Feasycom FeasyBeacon SDK for Android and iOS, providing cross-platform BLE beacon functionality with background monitoring capabilities.
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.
Features #
✅ 100% SDK Implementation: Complete parity with native Android and iOS SDKs
✅ Cross-Platform: Unified Dart API for both platforms
✅ BLE Scanning: Discover nearby FeasyBeacon devices
✅ Device Management: Connect, configure, and control beacons
✅ Beacon Configuration: Full CRUD operations for iBeacon, Eddystone, and AltBeacon
✅ OTA Updates: Over-the-air firmware updates
✅ Background Monitoring:
- Android: Foreground service with interval detection
- iOS: Core Location region monitoring with fast connection
✅ Real-time Events: Streams for scan results, background events, OTA progress, and device data
✅ Comprehensive Example App: Tabbed interface with device management and monitoring
Platform Support Matrix #
| Feature | Android | iOS | Notes |
|---|---|---|---|
| BLE Scanning | ✅ | ✅ | Full support |
| Device Connection | ✅ | ✅ | Full support |
| Parameter Setting | ✅ | ✅ | All setters implemented |
| Beacon CRUD | ✅ | ✅ | Full support |
| OTA Updates | ✅ | ✅ | Full support |
| Background Monitoring | ✅ | ✅ | Android: service, iOS: region-based |
| Low-level Communication | ✅ | ✅ | Packet streaming |
| Device Info | ✅ | ✅ | Parameter loading |
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 #
The included example app demonstrates all plugin features with a modern, tabbed interface:
🕵️ Devices Tab #
- Live BLE Scanning: Start/stop scanning with real-time device discovery
- Device Information: Display device name, MAC address, RSSI, and beacon types
- Connection Controls: Connect to devices with automatic scan stopping
- Favorite Management: Add/remove devices from favorites with heart icons
❤️ Favorites Tab #
- Persistent Storage: Devices saved using SharedPreferences
- Swipe to Delete: Remove favorites with swipe gestures
- Quick Access: Connect to favorite devices directly
- Auto-Add: Devices automatically added to favorites when connected
⚙️ Background Tab #
- Android Background Monitoring: Foreground service with interval detection
- iOS Background Monitoring: Core Location region monitoring configuration
- Parameter Configuration: UUID, major, and threshold settings
- Event Logging: Real-time display of background detection events
🔧 Connected Device Features #
- Device Info: Load and display all device parameters
- OTA Updates: Trigger firmware updates with file picker
- Parameter Setting: Configure device name, interval, power, and more
- Status Display: Connected device information in bottom bar
🎯 Key Features #
- Material 3 Design: Modern UI with improved user experience
- State Management: Proper handling of connection states and UI updates
- Permission Handling: Automatic request for Bluetooth, location, and notifications
- Error Handling: User-friendly error messages and status updates
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.