Skip to content

Repository files navigation

AES Alert Tracker

Platform API Language UI Offline

Fully offline Android app that warns drivers when approaching AES/AWAS enforcement cameras in Malaysia - highway speed cameras and red-light junction cameras. Runs as a persistent foreground GPS service.


Screenshots

Running on car head unit Alert overlay
Car head unit AES warning
Dashboard — PASSED state Dashboard — CLEAR (sim mode)
Passed state Default sim mode

Features

  • Real-time GPS tracking via foreground service
  • Proximity detection using Haversine distance + bearing-aware directional filtering
  • Full-screen alert overlay when approaching a camera - shows camera name, highway, distance, speed limit vs current speed
  • Junction cameras (red light + speed) show a dedicated traffic-compliance warning
  • Audio alert: 3-beep sequence on approach, silenced once passing
  • Dashboard with large speed readout, GPS lock status, current area name, and next camera info
  • 47 AES/AWAS cameras: 33 highway speed + 14 red-light junction sites (JPJ list 15.07.2024)
  • Configurable alert distance (500 m - 5 km), per-camera mute, and per-category alert toggles
  • In-app camera database browser with edit capability
  • Now Playing bar showing current media via notification listener
  • Route simulator for testing without driving (Kajang, JB, RLC KL routes)
  • Auto-starts on device boot

How It Works

GPS location update (every second)
          |
          v
    ProximityEngine
     - Haversine distance to each camera
     - Bearing match: is the user heading toward the camera's monitored direction?
     - Ahead check: is the camera in front, not behind?
          |
          v
    Alert state machine
    CLEAR -> DETECTED -> APPROACHING -> PASSING -> PASSED -> (30s cooldown) -> CLEAR
          |
          v
    AlertManager (3-beep audio)  +  AlertOverlay (full-screen visual)

An alert only fires when all three conditions are met:

  1. Within scan radius
  2. Travel direction matches the camera's monitored bearing (within tolerance)
  3. Camera is ahead, not already passed

Camera Coverage

Highway / Road Cameras States
PLUS E2 (Southern) 10 Johor, Melaka, N. Sembilan, Selangor
PLUS E1 (Northern) 11 Perak, Pulau Pinang, Kedah, Selangor
ELITE E6 2 Selangor
GCE E35 2 Selangor
SKVE E26 1 Selangor
LEKAS E21 2 Negeri Sembilan
Lebuh Sentosa 1 WP Putrajaya
Federal Route 1 1 Perak
Federal Route 8 1 Kelantan
LPT2 E8 2 Terengganu
Red-light junctions 14 Perak, Kedah, WP Kuala Lumpur
Total 47

Sources: JPJ official AWAS list (15.07.2024), OpenStreetMap Overpass API, paultan.org calibration reports.


Architecture

com.aesalert.app/
  |
  +-- data/
  |     AESCamera.kt          Room entity (lat, lng, speed limit, bearing, type, status)
  |     CameraDao.kt          Room DAO (CRUD operations)
  |     AESDatabase.kt        Room database with prepopulation on first launch
  |     CameraData.kt         Hardcoded camera seed list (47 cameras)
  |     AreaData.kt           Offline area zones for current-location display
  |     AppSettings.kt        SharedPreferences wrapper (distance, toggles, mutes)
  |
  +-- logic/
  |     ProximityEngine.kt    Core detection: Haversine + bearing + ahead + filters
  |     AlertManager.kt       Audio alerts via ToneGenerator (3-beep sequence)
  |     OverlayLogic.kt       Overlay visibility, dismissal, overspeed, warning text
  |     Heading.kt            GPS heading resolution (hasBearing-aware)
  |     RouteSimulator.kt     Fake GPS routes for testing (Kajang, JB, RLC KL)
  |
  +-- service/
  |     LocationTrackingService.kt   Foreground service, GPS updates, StateFlow emission
  |     NowPlayingService.kt         Notification listener for media info
  |
  +-- ui/
  |     MainScreen.kt         Dashboard — speed display, GPS status, camera info
  |     AlertOverlay.kt       Full-screen warning overlay (APPROACHING state)
  |     CameraListScreen.kt   View, edit, and mute cameras
  |     SettingsDialog.kt     Alert distance, alert toggles, now playing, simulation
  |     theme/Theme.kt        Dark theme (Material 3)
  |
  +-- MainActivity.kt         Entry point, runtime permissions, service binding
  +-- BootReceiver.kt         BroadcastReceiver — auto-start service on boot

Tech Stack

Language Kotlin
UI Jetpack Compose + Material 3
Database Room (SQLite)
Concurrency Kotlin Coroutines + StateFlow
Build Gradle Kotlin DSL, KSP
Tests JUnit 4 (49 unit tests)
Min SDK 26 (Android 8.0 Oreo)
Target SDK 35

Installation

Download the latest APK from the Releases tab.

  1. Transfer the APK to your Android device via USB or any storage
  2. On your device: Settings > Security > Unknown Sources (or Install unknown apps) - enable for your file manager
  3. Open the APK with your file manager and install
  4. Grant location permissions when prompted

Tested on Android car head units and tablets (Android 8.0+)


Build from Source

# Debug APK
./gradlew assembleDebug

# Install directly to connected device
./gradlew installDebug

# Release APK (minified + obfuscated)
./gradlew assembleRelease

Requires Android Studio with Android SDK 35.


Permissions

Permission Purpose
ACCESS_FINE_LOCATION Precise GPS tracking
ACCESS_BACKGROUND_LOCATION Continue tracking when screen is off
FOREGROUND_SERVICE Persistent GPS service
FOREGROUND_SERVICE_LOCATION Location-type foreground service (Android 14+)
POST_NOTIFICATIONS Foreground service notification (Android 13+)
RECEIVE_BOOT_COMPLETED Auto-start service on device boot
WAKE_LOCK Keep CPU active while service is running

Disclaimer

This app is for informational purposes only. It is the driver's sole responsibility to obey all traffic laws and speed limits at all times.

Speed displayed is GPS-derived and may differ from your vehicle's speedometer. This is normal - most speedometers are calibrated to read slightly higher than actual speed by design.

About

Offline AES/AWAS speed camera alert app for Malaysian highways. Foreground GPS service with bearing-aware proximity detection

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages