System overview
VantageNotificationListener (Kotlin)
File:android/app/src/main/kotlin/.../VantageNotificationListener.kt
The service extends Android’s NotificationListenerService, which runs in the background even when the Flutter app is killed. It is registered in AndroidManifest.xml with BIND_NOTIFICATION_LISTENER_SERVICE permission — Android prompts the user to grant Notification Access in system settings.
Banking app whitelist
Only notifications from these packages are processed:SHA-256 deduplication
Banking apps sometimes re-post or update notifications (e.g. when the balance refreshes). Without dedup, this would create duplicate transactions.- Compute hash
- Check SharedPreferences — if exists → drop
- If new → store hash, process notification
- Purge all hashes older than 5 days (runs inline on each insert)
Queue storage
Accepted notifications are appended to a JSON array in SharedPreferences under keynotif_queue:
Live channel
If the Flutter app is in the foreground, the service also delivers to anEventChannel:
NotificationService listens to this stream and processes immediately — no need to drain the queue.
Boot persistence
ABroadcastReceiver registered for RECEIVE_BOOT_COMPLETED restarts the listener after device reboot. Notifications received while the Flutter app hasn’t launched yet accumulate in the SharedPreferences queue and are drained on first launch.
NotificationService.dart
The Dart layer bridges the native queue to the parsing pipeline.Queue drain
Called on every app launch and resume:drainQueue on the Kotlin side reads and clears the SharedPreferences array in a single synchronized operation — no item is processed twice.
Processing pipeline
Saving a parsed transaction
Android permissions required
setup/android-setup) guides the user through this step.