EchoNode is an Android hackathon MVP for school threat response. It runs a foreground audio sensor, performs on-device gunshot-like audio inference, and propagates alerts across nearby Android devices using Google Nearby Connections.
- Platform: Android-only MVP
- Detection: On-device YAMNet (
yamnet.tflite) + activity gate - Mesh: Nearby Connections
P2P_CLUSTER - State UI:
LISTENING,BARRICADE,EVACUATE - Goal: sub-second local trigger + rapid peer propagation
- Team split: see
WORKSTREAMS.mdfor 3-way ownership map
If you are an AI agent picking up this repository:
- Start with
MainActivity.kt,MainViewModel.kt,AudioSensorService.kt,MeshNetworkManager.kt. - Detection logic runs in
AudioSensorServiceand publishes viaSystemEventFlow. - Mesh propagation and dedupe IDs are in
MeshNetworkManager. - UI consumes
MainViewModel.UiStateinScreens.kt. - Model assets are in
app/src/main/assets/:yamnet.tfliteyamnet_class_map.csv
AudioRecordcaptures PCM 16-bit mono at 44.1kHz.- Audio is downsampled to 16k and stored in a rolling 15600-sample buffer.
- YAMNet inference runs periodically (gated by amplitude/activity).
- If gunshot confidence crosses threshold, service emits
LOCAL_TRIGGER. - ViewModel transitions to
BARRICADEand broadcasts to mesh peers.
- Threat:
ALERT:THREAT_DETECTED|<messageId>|<zone> - Evacuate:
ALERT:EVACUATE|<messageId>|<route> - Clear:
ALERT:ALL_CLEAR|<messageId>
- Nearby on emulator is unreliable. Use real Android devices for mesh demos.
- Detection is pretrained YAMNet class score gating, not yet custom fine-tuned school-specific classifier.
- iOS parity requires backend relay architecture due to iOS background constraints.
┌─────────────────────────────────────────────────────────────┐
│ EchoNode App │
├─────────────────────────────────────────────────────────────┤
│ MainActivity │
│ ├── Runtime permissions │
│ └── Compose root + screen routing │
├─────────────────────────────────────────────────────────────┤
│ MainViewModel │
│ ├── UiState + app transitions │
│ ├── Observes SystemEventFlow │
│ └── Observes MeshNetworkManager │
├─────────────────────────────────────────────────────────────┤
│ AudioSensorService (Foreground) │
│ ├── AudioRecord capture │
│ ├── YAMNet inference via GunshotClassifier │
│ └── Emits LOCAL_TRIGGER │
├─────────────────────────────────────────────────────────────┤
│ MeshNetworkManager │
│ ├── Nearby P2P_CLUSTER advertise/discover │
│ ├── Broadcast + receive payloads │
│ └── Relay with message-id dedupe │
└─────────────────────────────────────────────────────────────┘
- Foreground microphone service for continuous monitoring
- Activity-gated ML inference for battery-aware operation
- Real-time debug telemetry in UI:
- Audio amplitude
- ML top label
- Gunshot confidence score
- LISTENING: dark screen + active mesh indicator
- BARRICADE: high-contrast red emergency instruction view
- EVACUATE: high-contrast green route guidance view
- Nearby Connections with automatic peer discovery
- Alert rebroadcast to simulate viral propagation
- Message ID cache to prevent infinite relay loops
cd shieldy
./gradlew assembleDebugAPK output:
app/build/outputs/apk/debug/app-debug.apk
Install from terminal (optional):
./gradlew installDebug| Permission | Purpose |
|---|---|
RECORD_AUDIO |
local audio detection |
ACCESS_FINE_LOCATION / ACCESS_COARSE_LOCATION |
Nearby discovery requirement |
BLUETOOTH_* |
P2P mesh links |
FOREGROUND_SERVICE_MICROPHONE |
persistent background monitoring |
POST_NOTIFICATIONS |
foreground service notification |
- Install
app-debug.apkon 2 real Android devices. - Grant all permissions.
- Keep both apps open for 10-20 seconds.
- Tap
SIMULATE THREATon one device. - Verify both devices switch to
BARRICADE.
- On dashboard, open
OPTIONS. - Tune activity threshold slider for environment.
- Produce sharp impulse near microphone.
- Watch ML line (
top label+ confidence) and verify trigger behavior.
app/src/main/java/com/echoshield/echonode/
├── MainActivity.kt # permissions + Compose entry
├── EchoShieldApp.kt # Application
├── data/
│ ├── MeshNetworkManager.kt # Nearby mesh + relay dedupe
│ └── SystemEventFlow.kt # Shared event/state flows
├── service/
│ ├── AudioSensorService.kt # Foreground audio + detection loop
│ └── GunshotClassifier.kt # YAMNet TFLite wrapper
├── viewmodel/
│ └── MainViewModel.kt # App state transitions
└── ui/
├── Screens.kt # LISTENING/BARRICADE/EVACUATE screens
└── theme/Theme.kt # Material 3 styling
Assets:
app/src/main/assets/
├── yamnet.tflite
└── yamnet_class_map.csv
- Replace YAMNet direct class gating with fine-tuned gunshot head trained on domain data.
- Add backend consensus and push relay (for reliable Android+iOS mixed fleets).
- Add zone mapping and Silent Escort routing by room/hallway.
- Add incident logs and admin console.
Hackathon project. Demo use only.