main
Hoppie ACARS Android App
A native Android application for Hoppie's ACARS network built with Kotlin + Jetpack Compose.
Features
| Feature | Details |
|---|---|
| Live Message Feed | Poll inbox with auto-scroll, filter by message type |
| Compose Messages | Telex, CPDLC, and custom message types |
| Weather & ATIS | METAR, TAF, VATSIM/IVAO/PilotEdge ATIS via inforeq |
| PDC Templates | Pre-Departure Clearance quick-fill form |
| CPDLC Templates | WILCO, UNABLE, ROGER, FL request shortcuts |
| Auto-Polling | Randomized 45–75s interval (per Hoppie spec) |
| Background Worker | WorkManager polling when app is backgrounded |
| Persistent Settings | Logon code + callsign saved to DataStore |
| Dark Cockpit Theme | Aviation-inspired color palette |
Architecture
app/
└── java/com/hoppieacars/
├── HoppieApp.kt @HiltAndroidApp
├── MainActivity.kt NavHost + BottomNav
├── data/
│ ├── api/
│ │ ├── HoppieApiService.kt Retrofit interface
│ │ ├── HoppieResponseParser.kt Plain-text response parser
│ │ └── ScalarConverterFactory String body converter
│ ├── model/
│ │ └── Models.kt AcarsMessage, MessageType, etc.
│ └── repository/
│ ├── AcarsRepository.kt Business logic, message store
│ └── SettingsRepository.kt DataStore persistence
├── di/
│ └── NetworkModule.kt Hilt → OkHttp/Retrofit
├── ui/
│ ├── AcarsViewModel.kt StateFlow ViewModel
│ ├── Navigation.kt Screen routes
│ ├── screens/
│ │ ├── MessagesScreen.kt Live feed + filter chips
│ │ ├── ComposeScreen.kt Telex / CPDLC / custom
│ │ ├── WeatherScreen.kt METAR / TAF / ATIS
│ │ └── SettingsScreen.kt Logon + callsign config
│ ├── components/
│ │ └── SharedComponents.kt MessageCard, StatusDot, etc.
│ └── theme/
│ └── Theme.kt Dark aviation palette
└── util/
└── AcarsPollWorker.kt Background WorkManager worker
Getting Started
Prerequisites
- Android Studio Hedgehog (2023.1.1) or newer
- Android SDK 26+ (Android 8.0)
- A free Hoppie logon code: https://www.hoppie.nl/acars/system/register.html
Build
- Clone / unzip this project
- Open in Android Studio
- Let Gradle sync
- Run on device or emulator (API 26+)
First-Time Setup
- Open Settings tab
- Enter your Hoppie Logon Code
- Enter your Station Callsign (e.g.
BAW123for aircraft,EGLL_GNDfor ATC) - Tap Save Settings
- Go to Messages tab and tap START
Hoppie API Reference
Base URL: https://www.hoppie.nl/acars/system/connect.html
Request Parameters
| Param | Description |
|---|---|
logon |
Secret logon code (≥24 chars) |
from |
Your callsign |
to |
Recipient callsign or SERVER |
type |
poll, telex, cpdlc, ping, inforeq, posreq, position, progress |
packet |
Message payload (empty for poll/ping) |
Poll Response Format
ok ← no messages
ok {CALLSIGN type {payload}} {…} {…} ← one or more messages
error {reason} ← error
Polling Rules (important!)
- Poll once per 45–75 seconds (randomized to spread server load)
- After sending a message, may poll once after 20 seconds
- Don't poll until your station has sent its first message
- Use
ping(notpoll) to test connectivity — ping doesn't register you as online
Message Types
| Type | Direction | Description |
|---|---|---|
telex |
Both | General text messages |
cpdlc |
Both | Controller-Pilot Data Link Communications |
progress |
Aircraft → Dispatch | OUT/OFF/ON/IN times |
position |
Aircraft → Ground | Position reports |
posreq |
Either | Request a position report |
ping |
→ Server | Link test (doesn't register online) |
inforeq |
→ Server | Weather/ATIS requests |
InfoReq Packet Format
metar KLAX
taf EGLL
shorttaf KJFK
vatatis EDDM
ivaoatis LFPG-GND
peatis KSAN
Dependencies
| Library | Version | Purpose |
|---|---|---|
| Jetpack Compose BOM | 2024.08.00 | UI framework |
| Hilt | 2.51.1 | Dependency injection |
| Retrofit | 2.11.0 | HTTP client |
| OkHttp | 4.12.0 | Network layer |
| DataStore | 1.1.1 | Settings persistence |
| WorkManager | 2.9.1 | Background polling |
| Navigation Compose | 2.7.7 | Screen navigation |
Notes
- The app uses cleartext HTTP (
android:usesCleartextTraffic="true") since the Hoppie server is HTTP only - Logon codes expire after 3 months of inactivity — any login renews them
- The in-memory message log holds up to 500 messages and resets on process death
- CPDLC packet format follows ICAO FANS-1/A specification — see Hoppie CPDLC docs
License
MIT — free to use, modify, and redistribute.
Languages
Java
74.3%
Kotlin
25.5%
Shell
0.2%