Appearance
Mobile App
SafeCall Nav is a Flutter app for indoor navigation using BLE beacons. It supports Android and iOS with a single codebase.
Tech Stack
- Framework: Flutter (Dart ^3.10.3)
- Map Rendering: Flame (^1.35.1) game engine
- BLE:
flutter_blue_plus(^2.1.1) for beacon scanning - QR Scanner:
mobile_scanner(^7.1.4) - State Management:
flutter_riverpod(^3.2.1) - HTTP:
http(^1.6.0) package - Local Storage:
sqflite+path_provider
Architecture
mobile/lib/
├── main.dart # App entry point
├── screens/
│ ├── home_screen.dart # Server connection & sync
│ ├── qr_scanner_screen.dart # QR code scanning
│ └── navigation_screen.dart # Main map & navigation UI
├── services/
│ ├── api_client.dart # HTTP client for server API
│ └── ble_scanner.dart # BLE beacon scanning
├── models/
│ └── navigation_data.dart # Domain models (bundle, floor, node, edge, beacon)
├── core/
│ ├── navigation_graph.dart # Dijkstra pathfinding
│ └── positioning.dart # BLE RSSI → position estimation
└── game/
└── navigation_game.dart # Flame map rendererUser Flow
- Connect: Enter server URL manually or scan QR code
- Authenticate: Login with email/password or navigation token
- Sync: Download navigation bundle (floors, nodes, edges, beacons, maps)
- Navigate: View indoor map, select destination, follow path
Data Flow
QR Code / Manual Input
│
▼
ApiClient
│ authenticate + fetch bundle + download maps
▼
NavigationBundle (saved to disk)
│
├── NavigationGraph (Dijkstra pathfinding)
├── PositioningEngine (BLE → x,y)
│ └── BleScanner (RSSI from WTK beacons)
└── NavigationGame (Flame map renderer)Key Models
| Model | Purpose |
|---|---|
NavigationBundle | Complete navigation data for a location (floors, nodes, edges, beacons) |
NavigationFloor | One floor's graph, beacons, and map images |
FloorData | Floor metadata (compass angle, map scale, ruler calibration) |
NavNode | Graph node with x, y coordinates and optional name |
NavEdge | Graph edge connecting two nodes with a weight |
NavBeacon | BLE beacon with position, MAC, and POI/static flags |
Offline Support
The app caches the navigation bundle to disk as nav_bundle.json. Floor map images are saved as floor_{id}.png. On subsequent launches, the app checks the SHA hash against the server and only re-downloads if the data has changed.
Development
bash
cd mobile
# Get dependencies
flutter pub get
# Run on connected device
flutter run
# Run tests
flutter test
# Analyze code
flutter analyze