APRSlocus · packets relayed 509,260

APRSlocus 2.0TOUCH SKY

APRS Tracking & Mapping

An APRS client for amateur radio operators - a tool that runs on your own device.
It ships with no server address: enter your own APRS-IS server, or use a Bluetooth TNC / sound card / direct Icom connection.

That number is every packet the world’s APRS stations have relayed so far — radio waves cross the sky and end up on this planet, and the next one is yours to send.

APRSlocus 2.0 released 2.0 is out · Download now →

APRS-IS · TNC · Audio · PKWDWPL Android / Windows
Announcement

📡 APRSNETCN OA · test round

This Saturday, send a packet to the duty stationAPRSNETCN OA · test round

Saturday 17 October, 00:00 to 23:59 Beijing time. Network and RF both count, RF first. Address the message to BG7LZQ-3 and send it the CQ CNNET way.

The first round of APRSNETCN OA is this Saturday. Stay on for the day, send one packet to the week's duty callsign, and you are on the list.

📡 When, and who is on duty

  • Saturday, 17 October 2026, 00:00–23:59 Beijing time (UTC+8)
  • In UTC that is 16:00 on 16 October to 15:59 on 17 October
  • The duty callsign this week is BG7LZQ-3

📮 How to join

Address the message to BG7LZQ-3.

Send CQ CNNET BG7XXX from OL62 with your own call and your own grid. When the duty station answers with an ACK, send U CNNET.

You can also send CNNET BG7XXX from OL62 and skip the CQ step.

A grid of 4 or 6 characters both work, for example OL62 or OL62AA. If a packet arrives without a grid, the duty station answers with a hint; send it once more with the grid in.

Anything you want to pass on to the duty station goes after the grid. That sentence shows up next to your callsign on the roster.

Packets over the network and packets over RF both count, RF first. An RF packet records the digipeaters it went through.

You need a valid callsign and licence, and please follow your local regulations.

📋 What shows up

The duty station answers every check-in with an ACK.

Your callsign then appears on the activity page roster, with your grid and the time it arrived.

The roster image and the grid image can be downloaded the same day.

🙋 About this round

This is the first round, so the flow will keep changing. The activity page always carries the current version.

No scoring, no leaderboard, and no commercial use.

If you miss this one, there is another round next Saturday.

In APRSLocus, open the Messages page and set the recipient to the duty callsign.

The roster for the day is on the activity page. Open the activity page

✅ The Qingling channel is back

The 2.2.0 build published on the Qingling (清零) channel by mistake has been taken down, and the channel works normally again.

Checking for updates now returns the latest stable version, 2.1.6. If you installed 2.2.0, uninstall it first, then install 2.1.6.

Download 2.1.6

🥚 A small easter egg in 2.1.0: tap, and the planet turns around

The egg is on the About page — the spot you most likely pass every day.

That slowly turning star on the cover is not a picture. Give it a light tap: it shudders, turns around, and drops you into a page of story. There is a planet turning there too, a number that keeps climbing, people who keep watch on the airwaves — and the people who built this thing alongside them.

There is sound on that page; turn your speakers up. No long press, no five-second wait — one tap and the story arrives. Changed your mind? One more tap turns the cover back, and the story stays closed.

The rest is yours to see.

📮 We would like to hear from you

APRSLocus has walked a while with 620+ users now. Where it goes next is partly your call: what feels awkward, what is missing, what we should fix first.

Take the survey

💬 Official QQ group 925025834

Questions, ideas, or just a "copy that": you are welcome to drop in.

Join 925025834

🎵 A song for you: 启航的歌 (Set Sail)

The planet is still turning, the number is still climbing.
Thank you, everyone still listening.

The APRSLocus team

October 2026

UI 2.0 · Live Preview

The all-new UI 2.0: a full-screen map with floating capsule navigation and draggable panels. See the full promo page →

APRSlocus 2.0 interface

Map-first · Everything floats

  • The map stays on screen full-time — pages no longer destroy it
  • Floating capsule navigation at the bottom, with a sliding indicator
  • Draggable content panels with a 44px grab handle
  • Top-right capsules: weather / link status / position
  • Frosted glass · Mica materials, light and dark themes
Open the 2.0 promo page →

What It Does

Position tracking, beacon reporting, messaging, group chat — all the APRS essentials, built to be straightforward.

Maps & tracking

01

Real-time Map Tracking

Many tile sources: AMap tiles, AMap satellite, Vector, Carto (light/dark/voyager), OSM (standard/humanitarian), OpenTopo, and Esri. One marker per station (clustering removed in v1.6.149), with trail playback support; the heatmap shows density when zoomed out.

  • GCJ-02 / WGS-84
  • Heatmap
  • Trail Display
02

Immersive Drive View

A navigation-style page built for glancing at while driving: large heading / distance / speed readouts, a nearby-stations panel, and the target station centred.

  • Navigation style
  • Nearby stations
  • Large type
03

Offline Maps

Download the tiles of the current view to the device (resumable, 200k tiles per region) and keep the map with no network at all; a four-step fallback keeps it readable and clickable.

  • Download view
  • Resumable
  • 4-step fallback

Messaging & gateway

04

Position Beacon

One-tap position reporting in standard APRS 1.0 format. Auto-includes altitude, speed, heading, and battery level. Report interval is configurable.

  • Standard Format
  • Auto Attachments
  • Demo Mode
05

Messaging

Private and group chat in a unified conversation list with ACK confirmation. Supports group invites, member management, unread badges, and Chinese text.

  • ACK Confirmation
  • Group Chat
  • Chinese Compatible
06

Two-way Chat Translation

Built-in multi-engine translation that works out of the box on a free endpoint, no API key required. Translate both incoming and outgoing messages, compare against the original, or translate your text into the other station's language before sending.

  • No API key
  • Side-by-side
  • Pre-send
07

Gateway (iGate)

Relays RF packets into APRS-IS, tagging them with qAr / qAR; loop protection is built in (packets already carrying TCPIP* or a q-construct are never echoed back), and the same frame is injected once per 30 seconds. Optional two-way mode sends messages to stations recently heard on RF.

  • RF→IS
  • Loop-safe
  • De-duplication

Stations & data

08

Station Recognition & Filter

Recognizes station devices via the official aprs.org database (tocalls): vendor + model + device class (rig / HT / tracker / app / gateway…). Filter by status, type, device class or exact model; jump to QRZ callsign DB or aprs.fi for tracks from the details page.

  • Official Device ID
  • Class / Model Filter
  • QRZ / aprs.fi
09

Packet & Log Viewer

Raw packets displayed in monospace with long-press copy. Parsed results sorted by type: position, message, weather, status. Built-in hierarchical logs for debugging.

  • Raw Packet View
  • Type Filtering
  • Debug Logs
10

Five Data Sources

Internet (APRS-IS), Bluetooth / serial TNC (KISS), sound-card AFSK 1200 (Bell 202 software TNC), Kenwood $PKWDWPL waypoints (receive-only), and WLAN radio direct link (supporting IC-705 / IC-9700 / IC-7610 / IC-905 over Wi-Fi / Ethernet with CI-V and LAN audio). Multiple links can receive simultaneously, while the transmit link is picked separately.

  • APRS-IS
  • TNC
  • Audio
  • PKWDWPL
  • WLAN Radio
11

Weather · Statistics · Honors

A weather panel whose dynamic background follows the actual conditions, station statistics (latest spot, farthest distance, packet rate), and an honors wall.

  • Weather
  • Statistics
  • Honors
12

Data Export

One-tap ADIF export — the standard amateur-radio log interchange format — with a configurable frequency, ready to import into other logging software.

  • ADIF
  • Custom frequency
13

HF & Ionospheric Propagation

An HF panel plus a standalone widget: SFI / Kp / A index, sunspots, X-rays, solar wind, and day/night conditions for four band pairs at a glance. Data comes from hamqsl.com (N0NBH) with a 30-minute cache.

  • SFI / Kp / A
  • Day / night
  • 30-min cache

System & experience

14

Connectivity & Background

Auto-connects to APRS-IS public servers over TCP or WebSocket. Progressive reconnect: 8 → 16 → 32 → 60 seconds. Android uses a foreground service to stay online.

  • Auto Reconnect
  • Foreground Service
  • System Notifications
15

Auto Updates

In-app update checker with two channels (GitHub / GitCode). Platform-aware download routing and historical version access.

  • Dual Channels
  • Platform Routing
  • Historical Versions
16

Personalization

Simplified Chinese / Traditional Chinese / English / Japanese / Indonesian / Spanish UI, dark mode, custom accent colors, scalable UI (85%–130%). Six-step onboarding wizard on first launch.

  • Six Languages
  • Dark Mode
  • OOBE Wizard
17

Home-screen Widgets

Android home-screen widgets: weather (four adaptive sizes), HF propagation and system status. The widgets never open a connection themselves — the app pushes a snapshot to them, which keeps them cheap on battery.

  • Android
  • 4 adaptive sizes
  • No direct network
18

Themes & Backup

Themes go beyond colour: icons, text and your own background image (17 colour tokens), exported as JSON to share; settings and data back up as one file for a one-tap restore.

  • 17 tokens
  • JSON export
  • One-tap backup

Supported Platforms

Ready-made packages for Android and Windows. Download and go.

First Launch? Follow the Wizard

On first open, the onboarding wizard walks you through the setup. Fill in the steps and you'll be connected to APRS-IS and reporting your position.

  1. 1

    Choose Language

    中文 / English / Follow System

  2. 2

    Learn the Features

    Try demo mode first

  3. 3

    Enter Callsign

    e.g. BG7LZQ-3, choose SSID suffix

  4. 4

    Pick a Symbol

    Car / House / Person / Weather Station …

  5. 5

    Receive Filter

    Filter stations by country / region

  6. 6

    Server Config

    Enter Passcode, done — auto-connect

💡
Passcode Tip: Entering -1 works for basic connectivity, but an unverified Passcode cannot send or receive messages properly. Visit APRS Passcode Generator to generate your own Passcode.

Beacon & Symbols

APRS 1.0 compliant, compatible with mainstream APRS software. All icons from the official symbol table.

Position Beacon Example APRS 1.0
BG7LZQ-3>APALOC,TCPIP*:!2148.90N/11049.14E/> /A=000328 090/050 Bat:70% APRSlocus v1.6.18
  • APALOC — Identifies this station as APRSlocus
  • /A=000328 — Altitude in feet
  • 090/050 — Course / Speed
  • Bat:70% — Battery level

Changelog

Highlights of recent releases — dozens of maintenance releases in between are folded in; see GitHub Releases for the full history.

v2.1.6 2026-10-16
History can be exported as GPX: today, the last 7 days, 30 days, a year, or a range you pick. The file lands in the system Downloads folder and can be shared straight away; any other app that opens it gets the track as timestamped points.
The follow button has three states: off, locked centre with north up, and locked centre with heading up, one tap apart. The stations page keeps its sort entry in landscape, and the sort field is remembered with the backup.
In landscape the drawn track, beacon marks, accuracy ring and heat map no longer paint under the left card or the bottom bar (the cards are frosted, so the blue line used to show through them). The reporting bar now shows the symbol this beacon will send, and permissions are checked once at startup, naming only the ones that were there before and are now off.
v2.1.5 2026-10-15
The map follows you: the right toolbar gained a "lock map centre" button. With it on, the map keeps your position in the middle as you move, so there is no need to recentre by hand, and zoom stays yours. Dragging the map, or focusing a station, releases the lock.
The About page gained a Partners section listing APRSNET.CN.
Tapping Connect with no server address no longer just spins: the server field shows an "unset" badge with the reason, and Connect pops a note with a one-tap way into the connection settings.
v2.1.4 2026-10-14
The "waiting for confirmation" prompt no longer keeps popping up: the persistent notification could be re-sent once a second (any change in the fix, stations, battery or countdown rewrote its text) and the system popped it again as a new notification; it now stays quiet while the text is unchanged, and is flagged alert-once. More to the point: a jitter in the link (an automatic reconnect, a server-side disconnect, a transmit-source switch) used to wipe the "start reporting" tap already made for this connection, stopping reporting and sending the UI and the notification back to "waiting for confirmation". Now only your own connect / disconnect / factory reset voids it; a link that dropped on its own and came back keeps the confirmation and carries on.
v2.1.3 2026-10-14
"Android cannot get the satellite count" fixed: newer devices no longer attach a satellite count to the fix, and the GNSS-status fallback does not fill in "used in fix" on every device -- so the beacon settings page kept showing a dash. The count is now read in three steps: attached to the fix -> used in fix -> satellites in view, using whichever has a value; a failed listener registration also retries itself every 30 seconds instead of staying "unknown" forever.
v2.1.2 2026-10-14
The beacon can carry the satellite count: SAT=nn is an optional comment field, fed by whichever source is supplying the position — phone GPS (Android reads the satellites used in the fix) or the external GPS module's GGA sentence. Off by default, and nothing is sent when the source does not provide it, rather than a zero that reads as "no satellites".
A new "Current fix" card on the external GPS device page: position, altitude, speed, course, satellites, accuracy (with the raw HDOP), fix type (2D / 3D from GSA, and an explicit "not reported"), module time (UTC), the trigger sentence and the latest raw sentence are all out in the open; the age ("N seconds ago") refreshes every second, so a stalled stream shows at a glance how long ago the last fix was.
No more "Connect TNC": the external GPS and PKWDWPL device pages used the TNC button wording, so tapping them looked like connecting a radio. They now speak in terms of the device (Scan devices / Connect device / Bound device …), and only the actual TNC page says "Connect TNC".
v2.1.1 2026-10-14
External GPS position source: an NMEA 0183 module (RMC / GGA / GLL / ZDA / GSA / VTG) over Bluetooth SPP or a USB serial port, used for this device's own position and receive-only. Position priority: simulated > external module > Garmin watch > phone GPS.
New "External GPS" device sub-page: scan / bind / connect / disconnect / restart, plus reception stats; the data source card lists phone GPS / external module / Garmin together with the priority; the beacon bar shows the position source (e.g. "External GPS · 45s").
v2.1.0 2026-10-14
The cover easter egg no longer counts to five: the egg on the About cover used to be "tap, then watch a motionless cover for five seconds" — nobody can tell an easter egg from a freeze. A tap is the activation now: the shudder, the flip and the particles happen together, and the moment the flip lands, that page of story is handed over; one more tap turns the cover back and the story stays closed. Platforms with an embedder (Android / iOS / macOS) open it full-screen inside the app; only Windows / Linux / Web hand it to the system browser.
Leaving the page takes the music with it: the story page plays its own background music, and leaving it (back, or switching the app away) used to leave the sound running — an Android WebView does not silence the audio inside it when it is torn down. The page is now silenced before the route pops and unloaded during the exit animation, and switching away silences it too.
v2.0.68 2026-10-13
Faster agent replies: the "stream replies" request of 2.0.67 was missing stream, so the backend answered with one plain JSON blob; the app saw "no stream" and sent the very same request a second time — every round waited twice as long and paid twice the tokens. The streaming request now really carries stream: one request, shown as it arrives, with the same automatic fallback when a backend does not accept it — never fewer replies.
The agent no longer "stops after a few tool calls": one failing tool no longer takes down the whole turn (the exception becomes the result of that call and goes back to the model), and when a turn runs out of tool round-trips the app makes one more request without any tools so the model puts its conclusion into words, instead of stopping dead on the last tool bubble.
More complete station comments: comments get their own line, wrap, and default to unlimited lines, so long ones are no longer eaten by an ellipsis; URLs inside a comment (https://… / www.…) become tappable links, consistently in the station list, the station detail page and the map info window.
A faster agent: the default system prompt shrank from 5.3KB to 2KB — it used to restate all 57 tools one by one, even though each tool is already described in the schemas sent with every request; the tool descriptions were trimmed too (names / parameters / values unchanged). Prompt plus tool schemas are re-sent on every request, and together they are now about a quarter smaller, so replies come faster.
Leaner, no-flicker status reports: the APRS-IS keep-alive used to send an >APRSlocus CONNECT … frame every 15 seconds and then a second frame with your custom status — a wasted frame that also made the status on aprs.fi flip between the two. Now a single frame is sent, whichever has content: custom text if set, otherwise the built-in default; the CONNECT identity frame goes out once, at the moment of connecting. A custom frame that fails to write is still retried automatically, so your status is never overwritten by CONNECT.
v2.0.67 2026-10-13
The agent now replies character-by-character. Replies are no longer "wait, then the whole block appears" but are shown as the model writes them, which matters most for long answers. Real streaming (SSE tokens) is used first; when the backend cannot stream (it ignores stream, or on the Web) the app falls back to a whole-answer request plus a typewriter effect for the same feel — never fewer replies. A switch in Settings → Interface (on by default) controls it.
Agent "tool activity" history + a live working bubble: a new button in the chat header records every tool call (tool / arguments / result / time / success · denied · failed), newest first and clearable with one tap, carrying a numeric badge. While it works, a status bubble appears next to it — "Working: xxx" or "Thinking…" — so you never have to guess what it is doing.
Clearer PHG in station details: power / antenna height / gain / direction went from one grey line to an orange card with each value labelled and unit-tagged, readable at a glance; an omni pattern now reads "Omni" instead of 360°.
Clearer packet viewer: each frame's "call → target" now sits on its own line instead of being crammed with the badges and time and ellipsised away; "raw mode" no longer truncates — the full frame (path / data extensions / comment) is shown, wraps, and copies on long-press.
v2.0.66 2026-10-13
The agent can now drive the shared strategy map. Ask it in plain language to drop markers, draw lines and circles, or place rally points for your group: it calls the new strategy_add_point / strategy_add_line and friends, and each element lands on every member's map and is broadcast to the group. Use list_strategy to see what is there, edit or delete by id, or strategy_clear to wipe the layer. The read-only list_strategy needs no confirmation; the frame-sending writes still need the "allow sending"/"allow settings" permissions and a per-action confirmation.
v2.0.65 2026-10-12
Fix: the WLAN radio link could not change its RF digipeater path. The “WLAN radio direct” sub-page (IC-705 / IC-9700 / IC-7610 / IC-905) had no digipeater-path field, so there was nowhere to set an RF route such as WIDE1-1,WIDE2-1. The page now has an “RF digipeater path” input, sharing the same key and semantics as the TNC/audio pages (empty = no digipeater); changes take effect immediately.
v2.0.64 2026-10-11
Fix: APRS-IS dropping after joining the radio hotspot. After the phone joins the Wi-Fi hotspot hosted by an IC-705 (or similar), the system treated it as the default route and paused mobile data -- so the radio connected but APRS-IS dropped. The app now requests a local-only Wi-Fi network and binds the radio's UDP traffic to Wi-Fi, keeping APRS-IS on mobile data so the two paths no longer interfere. Older Android falls back to the previous behaviour.
v2.0.55 2026-10-10
New Hong Kong node: "Aliyun OSS (Hong Kong)" update channel. The update page gains an "Aliyun OSS (Hong Kong)" option next to the Guangzhou one -- both are team-funded CDN distribution, differing only in Aliyun region: Guangzhou is fast inside mainland China, Hong Kong is more reliable over cross-border / overseas networks. Both show the "please use sparingly 🙏" hint. The release pipeline now pushes each version's installers and index to both the Guangzhou (aprslocus) and Hong Kong (aprslocushk) buckets; Hong Kong is served over the custom domain aprslocushk.oss.theez.top.
v2.0.54 2026-10-10
Map interaction rework: tapping a station marker no longer flies to it and zooms in -- it now selects it and shows the callsign label / info popup, so the map stays put while inspecting nearby stations; details move to double-tap (or the popup). Also better readability on satellite imagery: symbols get a dark halo and callsign chips on both the main and strategy maps switch to dark background / white text on satellite basemaps.
v2.0.53 2026-10-10
Fixed Aliyun OSS download 400: the OSS default endpoint rejects public .apk / .ipa downloads with ApkDownloadForbidden (.exe is fine). Uploads now add a .bin suffix to those objects and the index download URLs point at xxx.apk.bin, while asset names stay unchanged -- no client change needed. The release self-check now really downloads each asset.
v2.0.52 2026-10-10
New Aliyun OSS update channel (optional): alongside GitHub / GitCode / Qingling, installers can now be served from Alibaba Cloud OSS over the Aliyun CDN (aprslocus.oss-cn-guangzhou.aliyuncs.com), which is fast in mainland China. It is off by default and must be picked on the update page.
Cost notice: traffic on this channel is paid for by the dev team, so a persistent banner asks users to use it sparingly 🙏. The release pipeline gained a publish-oss job that uploads the installers plus a GitHub-format releases index; credentials come only from GitHub Secrets and are never committed.
v2.0.51 2026-10-10
New Qingling update channel: fetching updates straight from GitHub often fails in mainland China. A fourth optional channel points at a self-hosted mirror (it pulls the release, then serves a GitHub-format API; the client never talks to GitHub). Channel bases are centralized in updateChannelBases, shared by the update page and the launch prompt. The Qingling channel uses HTTPS with a pinned self-signed certificate (pinning only that one host; other channels keep the default trust chain): encrypted and tamper-proof, with no domain, filing or purchased cert needed. GitHub stays the default.
Fixed test-pipeline artifacts: the Windows test build shipped only the Flutter launcher (~123 KB, missing flutter_windows.dll and data/, so it did nothing when opened) -> now a single-file installer with if-no-files-found: error; the iOS test artifact dropped its fork suffix -> the suffix is kept. Also: v2.0.50 was already released, so this feature bumps the version to 2.0.51.
v2.0.50 2026-10-09
Fixed audio settings not saving: changing the sample rate / baud / tones / TX delay / output amplitude and then tapping elsewhere (without pressing Enter) silently lost the change — those fields only wired onEditingComplete, which fires on Enter but not on focus loss. They now settle on blur; Enter still confirms immediately, and the output-amplitude commit rebuilds only the modulator without interrupting receive. The same fix lands for the IC-705 radio fields and the TNC serial baud.
v2.0.49 2026-10-09
Fixed sound-card RX-but-no-TX: the far end could not decode because output amplitude — the gain that decides clipping — was not editable in the UI, while both warnings said to adjust it. The TX card now has an output-amplitude field that takes effect immediately (rebuilding only the modulator, without interrupting receive). It also shows the current TX source (connected ≠ transmitting) and notes that the app never keys the radio PTT (use VOX or a data-port cable).
Packet source labels: every frame now carries a source badge (APRS-IS / TNC / sound card / PKWDWPL / local), so checking "is RF working / did the gateway relay it?" tells you at a glance where a frame came from.
v2.0.48 2026-10-09
Fixed the settings chevrons not pinned right: the title used a loose Flexible, so short text left free space and the chevron drifted left; switching to a tight Expanded pins it to the right and aligns the description column too.
v2.0.47 2026-10-09
Tap outside to dismiss the keyboard: tapping anywhere outside the compose box clears focus; the settings page is aligned (unified icon-tile / icon / chevron sizes, descriptions start at the same x); a new "Feedback" entry under "About" opens the repo issues.
v2.0.46 2026-10-09
A handier compose bar: the main key is "+" (send a location) by default and turns into "send" as soon as you tap into the field; "translate" moved out of the "+" sheet to a permanent button. Tapping a shared location opens a small sheet to view it on the map or navigate to it.
v2.0.45 2026-10-09
Pick a station — search & paging: the private-chat "+ → send location" menu now offers "Pick a station" with search by callsign / alias and paged browsing (20 rows per page, labelled prev/next buttons), sorted near → far when a position is known; each row can open station details first. A station's "More" menu can also share that station to other chats.
Free-picked locations, unified panel: pick any point on the map (or "My position") to share a location; tapping it reuses the station panel, putting navigation one tap away. Callsign recognition fixed in messages: any callsign-looking word is clickable — solid underline for known stations, dotted for not-yet-heard ones, all opening the station panel.
v2.0.44 2026-10-09
Send a location in a private chat: in a one-to-one conversation tap the compose "+" to send a location — drag the map to pick any point, or use "My position"; you can also share a station. The peer receives it as a dedicated card message.
Clickable callsigns in messages: a station callsign recognized in a conversation behaves like a hyperlink and opens station details; the shared station card does the same, while a free-picked location jumps to the main map. The compose bar is collapsed into a single WeChat-style "+".
v2.0.43 2026-10-09
Strategy map, easier to use: tapping a teammate/self marker opens the station detail panel; "navigate" hands off to the phone's map app (AMap → system maps → browser OSM); the map now draws your own position (blue dot + callsign + bearing) with a one-tap "locate me".
Strategy changes leave a trail: add / edit / delete / clear all leave a notice in group chat, and a tap jumps into the strategy map; group send no longer asks for confirmation and just sends (with a pre-check when the server is offline).
v2.0.42 2026-10-09
Strategy map upgrades: the map now shows teammate positions with a bearing badge (matched to group members by SSID-stripped base callsign; no badge when stationary or without a heading), lines/circles get selectable colors (a network-wide six-color palette), and a strategy element leaves a clickable notice in group chat that jumps straight into that group's strategy map.
Group chat and the strategy map now work on RF: groupChatAllowed is always on; on RF (TNC / audio) strategy frames are sent ack-requesting and delivery is judged by teammates' standard auto-ack; unacked after 90s is treated as "unconfirmed" (a peer may have auto-ack off) and can be resent manually from the strategy map page.
Fixed strategy-point "jump to navigation": a strategy point is not in the station list, so a focus marker is now painted; the jump snaps instantly instead of animating and stalling mid-flight.
v2.0.41 2026-10-03
In-group "Strategy Map": share points, lines, circles and rally points with teammates/groups, reusing existing groups and transported over APRS messages (frame prefix $M, long lines auto-chunked, every frame ≤ 67 chars); elements support jump-to-navigation and editing attached info, and "clear layer" syncs to the whole group.
Long-press quick message: long-pressing a beacon/station opens a quick-message sheet, reusing the existing send path.
Removed the OOBE passcode hint: the first-run guide no longer shows a "get Passcode" hint.
v2.0.40 2026-10-08
"Transmit position beacon" button on Messages: a one-tap button sits to the right of the Messages page title, firing a single position beacon on demand (the same action as the map page's "Beacon now") without touching the automatic-report toggle; when no fix is ready it says "waiting for a fix" honestly, and collapses to an icon in narrow panels.
v2.0.39 2026-10-08
Backups include track history: exporting a backup now folds track history into the "Settings" group (moved verbatim, day by day), so the history survives a device move and can still be reviewed. The backup schema goes to v2 while old v1 backups still import; on import, days are merged, so a newer local day is not overwritten by an older backup. Tracks travel as a separate, untyped payload outside the preference whitelist.
About wording: the subtitle drops the "Local" qualifier in all six locales, now "APRS client · tracking & map", so it no longer implies the app only runs locally.
v2.0.38 2026-10-07
Tianditu layers: the basemaps gain a "Tianditu" group with three layers — Tianditu Vector (vec), Tianditu Imagery (img) and Tianditu Terrain (ter). Their base tiles carry no place labels; text lives in separate transparent annotation layers (cva/cia/cta), so each basemap is composited with its matching overlay (vector+cva, imagery+cia, terrain+cta). Base and annotation are cached separately and downloaded together offline, so you never get a map with no place names. Tianditu is measured as WGS-84 (zero offset vs Esri/OSM imagery), so it is not GCJ-shifted and falls back to OSM; tiles go up to z18. The key is injected at build time (CI Secret TIANDITU_KEY), never committed to source; when absent the map falls back to OSM and stays usable.
v2.0.37 2026-10-07
Terrain / contour layers: the basemaps gain a "Terrain" group with four hiking-friendly layers — OpenTopo Terrain (with contours, moved out of "Others"), Esri Topo (contours) (roads + labels + contours, closest to a paper contour map), Esri Shaded Relief (pure relief, cleanest for overall terrain) and Esri Hillshade (valley direction only). All four are key-free, offline-downloadable and fall back to OSM; being native WGS-84 international tiles, they are not GCJ-shifted and will not offset.
v2.0.36 2026-10-03
Manual confirmation before reporting: whatever positioning method is used, the app no longer auto-reports the position after connecting. The report action group now shows a formal "Start reporting" button — disabled as "Waiting for fix" until a valid fix for this round arrives, then one tap starts interval reporting and sends an immediate beacon so you can see yourself on the map. Disconnect / reconnect / restart all reset this confirmation, never falling back to "auto-report on connect"; the post-connect popup was also replaced by this button (non-intrusive).
Nicer honor wall: the member honor wall gains a toolbar — a search box (filter by name / callsign / honor), a live overview (members, badges) and a horizontally scrollable badge legend that jumps to each group. Cards, group headings and the responsive layout were polished, and it is keyboard navigable; the exported honor-card (PNG) style is left untouched.
v2.0.35 2026-10-06
Simulated location not applied after restart: after choosing "simulated location + manual fix" and saving coordinates, the next launch restored the coordinates but kept the reporting gate closed — the UI sat at "waiting for location" and you had to tap "Apply coordinates" again. Cause: startup treated any saved coordinates as "last round's live fix" and closed the gate (correct for GPS, to avoid reporting a stale position with location off), while the GPS auto-locate path is skipped in simulated mode — so the gate never opened. Now, in simulated mode the saved coordinates are the chosen position: they are accepted on startup and the filter center follows; the simulated-mode keep-alive foreground service is also started at boot, symmetric with GPS mode.
v2.0.34 2026-10-03
Blurry map at fractional zoom levels: measuring the pixels each source returns showed that apart from Gaode street (wprd host + scl=2, 512px), Carto / OSM / Esri / Tencent / Gaode satellite only serve 256px — the source was not the cause. The real issue was level selection: the map used zoom.floor(), so the whole [z, z+1) band pulled level-z tiles, stretching the source up to 1.93× at z=12.9 and then 2–3× more by screen pixel density — a 4–6× physical upscale, hence blur. It now uses zoom.round(): the upscale is capped at √2≈1.41× and the upper half downscales. Applies to every source.
v2.0.33 2026-10-03
One reporting control, two buttons: the scattered "report now" actions on the map status bar, the My panel and the immersive page are consolidated into a shared ReportActions (auto-report switch + report-now button); the duplicate implementations and the false "reported" toast are gone. Settings now use the unified "自动上报" wording with a hint pointing back to the main UI.
v2.0.32 2026-10-03
Data-maintenance page rework + factory reset: retention days moved from *Connection → Storage limits* onto the *Data maintenance* page next to the prune button (as a dropdown); manual pruning no longer reuses the auto-prune days — you pick its own days on the spot; and a new "Erase all data and start over" clears all settings including callsign, server, beacon and UI and re-runs the first-run wizard.
v2.0.31 2026-10-03
Custom status "sometimes still shows CONNECT": a status report is a pair — the built-in identity frame plus your custom status — and both write the same "station status" field on aprs.fi, last one wins. The compensating frame was fire-and-forget, so a socket hiccup could drop it silently and leave aprs.fi stuck on CONNECT while each keep-alive renewed it. The connector now reports send success, and keep-alive remembers a lost custom frame and re-sends the custom frame itself on the next tick (no extra CONNECT) until it goes through — your status can no longer be overwritten by the built-in text.
v2.0.30 2026-10-03
Data maintenance: prune stale stations by age (issue #33): a station retention (days) setting prunes stations not heard from for longer than that at startup, and the Data maintenance page adds a prune now action that first shows how many will be removed. Only ordinary stations are pruned — favorites, manual contacts and your own station are never pruned, and stations exactly at the threshold are kept; retention 0 = auto-prune off. Pruning is irreversible, so there is never a silent full wipe.
v2.0.29 2026-10-03
Setting the phone down a bit firmly triggered a crash alert (issue #32 follow-up): the old rule was "an impact spike + then 12 s of stillness", and setting the phone down satisfies both at once. Raising the threshold cannot help — it is a flaw in the rule itself. The two events now have separate requirements: a fall needs a free fall (weightlessness) before the landing impact; a crash, with no weightlessness to rely on, must be much harder (about twice the threshold). A real vehicle crash peaks at 20 g or more and still triggers, while a 3–8 g set-down is rejected.
Fixed a free-fall detection bug: weightlessness used to be judged from the gravity-removed linear acceleration, which is always 0 at rest — so "sitting still" was mistaken for "in free fall" and every impact was labelled a fall. It now uses the gravity-included total acceleration (~1 g at rest; only true weightlessness tends to 0). The explainer card was updated to match.
v2.0.28 2026-10-03
Life-guard "strong reminder": when a crash/fall or an abnormal heart rate fires, besides the in-app dialog the app now posts a high-priority system notification (sound + vibration + lock-screen/heads-up banner). Previously alarms only went to the quiet (IMPORTANCE_LOW) persistent notification, which the system neither vibrates nor banners for — so with the phone in a pocket (the usual state during a fall or while driving) it was not noticed at all. The strong reminder uses its own high-priority channel; Android needs the VIBRATE permission (added).
Better crash/fall detection algorithm: on top of the existing "impact + then ~12 s of stillness", it now also looks for a free fall just before the impact (acceleration magnitude ≤ 0.35 g for ≥ 80 ms) — a fall almost always starts with a free fall before the landing impact, whereas a vehicle crash does not. Alarms are therefore split into fall and crash, changing the title, icon and explanatory text. Both kinds are handled exactly the same; this only makes the wording more accurate. It is still a heuristic, and the dialog still says so ("not engineering-grade detection").
Three detection-sensitivity levels: Settings → Life Guard now offers Sensitive / Standard / Firm. The threshold used to be hard-coded, which cannot fit every way of carrying the phone — in a cycling pocket an ordinary bump crosses it, while a bar-mounted phone then false-alarms the whole ride. Sensitivity only affects detection (which impact counts), not what the alarm does; it travels with backups. iOS parity was added too: local notifications and the same crash/fall detection.
v2.0.27 2026-10-05
The custom status packet was overwritten by the built-in identity frame on connect (issue #31): connecting to APRS-IS first sends an identity status frame to announce presence, which rewrites the "station status" field on aprs.fi with the built-in text. Only the 15-second keep-alive frame used to re-send the custom status, and the connect-success path missed it — so every reconnect wiped the user's status once. Both paths now re-send it.
v2.0.26 2026-10-04
The map's my-location marker now shows heading: a triangular arrow (blue fill, white outline, matching the dot's visual language) points along your course so you can tell at a glance which way you are facing. It is not drawn for network-only fixes or when no course is known, rather than guessing a direction.
The interval shown in the bottom-left my-location panel disagreed with the countdown next to it: the panel's "auto-reporting · every Ns" line read the fixed interval field while the countdown read the effective one. In network-only mode the two differ (effective = the network interval, 300 s by default), so the label sat on a stale value left over from GPS mode. Both now use the effective interval.
v2.0.25 2026-10-04
Confirm once before a group mass-send: whether you send from the messages page with a group selected or from the tracker's quick-chat panel to the whole group, a single "Send to <group call>?" prompt appears first. A mass-send goes to every member at once and cannot be recalled.
Confirm once before inviting: single-member invites (typing a call or tapping the check beside a member) and the batch invites fired when creating a group both ask once first (the create-group prompt states how many members will be invited).
"Steps today" resetting to zero after an upgrade / reinstall (issue #22-2): the count only ever lived in memory and was never written to disk, so any cold start, in-place upgrade or rebuild began at 0 and stayed there until a sensor reading arrived. The count is now written on every change and restored on launch; it still resets across a date change, and a same-day device reboot resumes the pre-reboot accumulation instead of losing it.
v2.0.24 2026-10-04
Honor celebration no longer distinguishes new and existing users: previously only a freshly granted title would show, and honors you already had were never shown. Now: with no local "read" record, every honor you currently own is shown in turn (a fresh install, an upgrade from an older version, or a cleared record all count as no record); once seen, the record is written and it will not repeat - unless the account is granted a new honor.
Tapping your own row in the steps leaderboard showed a black-on-black toast: the text used ts(12), whose default color is dark, on an equally dark background - dark on dark and unreadable. It is now explicit white text (one more instance of the same bug in the settings pages is fixed too).
New developer option "Clear read honors" (Settings → Lab & developer tools): wipes the local "read" record so the next check replays every honor you currently own - handy for previewing and for self-testing.
v2.0.23 2026-10-04
New display setting: "Always show map labels": when on, every station's callsign label is drawn on the map regardless of station count or zoom (both the raster and vector maps). Off by default, keeping the original trade-off (labels only when there are 60 or fewer stations or zoom is 13+) - turning it on gets crowded, labels may overlap, and it costs more to render. The preference travels with backups.
The intercept page's "unblock on long-press" never fired: the soft-ban hidden unblock (long-press the install ID) was swallowed by two other gestures on the same row - the ID used selectable text, so a long-press raised the system selection toolbar, and the copy icon's long-press tooltip claimed the same gesture. The long-press was therefore never the unblock. The ID row is now a single gesture area: tap = copy, long-press = unblock (works for soft bans; hard bans stay silent by design).
v2.0.22 2026-10-04
Fixed: existing users never saw the new-honor celebration: the previous release only recorded a "seen" snapshot after you dismissed the animation - and older versions had no such feature, so after upgrading the device held a roster but no seen-record. The old logic treated that as a fresh install and waited for the first online roster to build the baseline - but that roster already contained the newly granted honor, so it was folded into the baseline and never celebrated. It now tells existing users from fresh installs by whether a local roster is stored: on upgrade the baseline is built immediately, so a genuinely new online grant in the same session still pops, while a fresh install still waits for the online roster and never replays honors you already had. Several honors granted at once only celebrated one is fixed too: they are now queued and shown one after another.
The first-run wizard no longer prefills connection fields: server, port and Passcode are left empty (common values only show as grey hints) instead of defaulting to rotate.aprs2.net / 14580 / -1 - the app presets and recommends no server; re-running the wizard still restores your saved values.
v2.0.21 2026-10-04
A "Congratulations" celebration when you earn a new honor: after the app starts, if your account has been newly granted an honor (a member title or FIRST FIX), a celebration pops up - gold-foil particles scatter over a dimmed backdrop while a badge emerges with rings and rays inside a white card, then the honor name, description and the primary button fade in. It follows the app light-card language and the badge color matches the honor wall; tap anywhere or the button to dismiss, each honor is celebrated only once. Detection waits for the online roster, so a fresh install never replays honors you already had as if they were new.
v2.0.20 2026-10-03
Map cannot be zoomed/panned when a finger lands on a station: the marker swallowed the map gestures (HitTestBehavior.opaque); with translucent both receive the pointer - tap selects the station, drag/pinch moves the map; applied to both the raster and vector map. The vector-map heatmap never worked either (it was excluded by !_usePluginMap); the vector map draws it now, projected with the flutter_map camera. "Start from a favourite station" opening a black screen was fixed too: it closes the New conversation dialog first and then closed one again after picking, popping the whole messages page - now the dialog is only closed when one is open. No system notification when picking a simulated point was fixed too: setting the position manually stopped the foreground service without restarting keep-alive - it is restarted now.
Heatmap level (Settings -> Display -> Map): Light / Medium / Strong, scaling the heat blobs size and density, shared by both maps. PHG is back in the station detail (power / antenna height / gain / direction), now on its own line instead of crammed into the three metrics.
v2.0.19 2026-10-03
The map no longer stutters (three root causes): the vector map had no viewport culling and pushed every station in the world into a MarkerLayer, while the station version bumps on every packet - so every packet rebuilt thousands of markers. Only viewport stations are built now, markers carry a key for identity reuse, and callsign labels are skipped when dense. Tile dragging was fixed too (tile loads are deferred until the gesture ends), as was the packet page (each row restarted a fade-in whose duration grew with the row index).
New: tapping the connection banner on the settings home page opens a floating link-method panel (same card as the Connection -> Device page); "Start from a favourite station" under New session; a Favourites filter in the station list (tap a row star to un-favourite); and you now appear in the activity leaderboard. Also fixed: Garmin link-drop request pile-up (stutter/crash risk), the box calling itself a TNC, the stale "coming soon" on the settings home page, and the map legend was removed.
v2.0.18 2026-10-02
New: WLAN radio direct link over Wi-Fi / Ethernet (supporting IC-705, IC-9700, IC-7610, IC-905). With the phone and radio on the same LAN you can send and receive APRS audio with no sound card or TNC; PTT and tuning go over CI-V while audio goes over the network, leaving the audio port free. Adds a dedicated radio page, a parallel data source entry, and 19 new test files. Contributed by nimenhagg (PR #29).
v2.0.17 2026-10-02
Terms of Use updated to V1.2: the app neither provides nor recommends any server address and connects to no APRS-IS / iGate / network server by default, with added clauses on configuring your own server, lawful use, and data safety. In the first-run guide an empty server means no connection at all (no pre-filled public server, no automatic connect).
v2.0.16 2026-10-02
Remote checks are timely at launch: the app now checks on every launch (it used to take up to 6 hours).
v2.0.15 2026-10-01
Terms of Use updated to V1.1 (with a donation clause). All three languages, 34 -> 41 clauses, documenting what the software actually does: gateway forwarding means transmitting on amateur bands on behalf of others (3.5); minors need a guardian consent and must not transmit unqualified (3.6); what you send must be truthful, accurate, lawful and respectful of local laws and customs (3.7); which third parties see what (weather sends a location, translation sends text, update checks query GitHub - none of it happens unless you use the feature, 5.3); Life Guard etc. are not medical devices and not an emergency service (7.6); a disclaimer that data may be passed to third-party software services (7.7); and about tips and donations (voluntary, no feature in return, non-refundable, minors need a guardian, 9.4). The in-app notice and the sponsor page state the same. The same release fixes three things: the crash when Bluetooth fails to connect (the blocking connect ran on the main thread, so the system killed the app), a phone battery that never updated (it was only read when a location fix arrived), and the sport ranking placeholder text and counting rule (today only, and you now appear on the board, marked).
v2.0.14 2026-10-01
New: an "APRSLOCUS" live dashboard on the box. Building on the box support from the previous release, the phone live status is now pushed to the box too: heart rate, speed, course, the auto-report countdown with a progress bar, mileage (trip / total), battery, steps, GPS accuracy, APRS-IS state and unread messages - visible at a glance on the bar-mounted box while the phone stays in the bag. Heart rate takes the lead when available, otherwise speed does; nearby stations moved to their own NEARBY page (8 rows). The protocol now uses TEL k=v ..., so the app can add fields without touching the firmware (unknown keys are skipped, empty values are not sent, and the box shows --, never a fake 0). Also: IS rx-only now explains itself in three places (home set pass, the server own words on the SYS page, and the app event log) with the fix (use the passcode of the base callsign), and countdowns now tick locally on the box with status pushed every 5 s.
v2.0.13 2026-10-01
New: APRSlocusBOX - manage your little APRS box from the phone. The Device page has a new entry, APRSlocusBOX: once connected you can read the box config, change it, feed it your position, trigger a beacon and see what it is actually doing. It connects over Bluetooth SPP or USB serial on its own channel, so managing the box never interrupts a TNC. Config covers all 23 keys (names match the box documentation) and the app re-reads after each change, so what you see is the real value in the box. This release also pushes what the phone sees - speed, course, altitude, fix, APRS-IS up/down, unread messages and the nearby station list (by distance, up to 8) - to the box PHONE page. In Bluetooth-only mode the box has no APRS-IS of its own, so that list is the only way it can show who is nearby. Two deliberate rules: the box is not a data source, and nothing is transmitted automatically - beacons and status packets must be tapped.
v2.0.12 2026-10-01
Fix: the update page no longer asks you to pick a package and never opens a browser. The previous build listed the three packages and sent a tap to the browser — that was wrong: almost everyone only knows "I want to update", and making them work out what armeabi-v7a means (or which row to choose) pushes the app's job onto the user. The page now picks the package matching this device's CPU by itself (Abi.current(), no platform channel needed) and downloads it in-app: a 32-bit device gets the 32-bit build, an emulator gets x86_64, and no one sees "incompatible with this device" after downloading. When the architecture cannot be determined it falls back to the pre-split behaviour, so an unknown device never ends up with no package at all.
v2.0.11 2026-10-01
Android packages are now split per CPU architecture: 81.6 MB → about 30 MB. In the previous build, 76.6 MB of the 81.6 MB — 94% — was three sets of native libraries (the machine code compiled from the app plus the Flutter engine, for arm64-v8a / armeabi-v7a / x86_64), while a phone only ever uses one of them. A release now carries three packages of about 30 MB each: 64-bit keeps the original file name (this is what the in-app update downloads; that logic is untouched), plus 32-bit and x86_64 (emulators / Chromebooks). Keeping the plain name is deliberate: the updater takes the first .apk in the asset list and assets come back in ascending name order, where . sorts before _ — so the 64-bit build is always first, an invariant with a dedicated check and self-test.
A "choose a package" block on the update page: when a release has more than one package it lists one row per file (name · architecture · size), the first marked "Recommended" — the one the in-app update fetches — and tapping a row opens that package's download URL in the browser, so 32-bit-only devices can grab _armeabi-v7a directly. One display fix came along: while downloading, the hero card and the card below it each drew a progress bar for the same download (it read as two tasks); now there is one.
v2.0.10 2026-09-30
New: LiveTrack from China-region Garmin accounts. Garmin runs two separate account systems on two sets of servers: the international one at livetrack.garmin.com and the China-region (mainland) one at livetrack.garmin.cn. Only the international host was recognised, so a link shared from the China-region app just said "no LiveTrack link found" — and not a single network request was ever made, making the feature silently dead. All three host forms are accepted now (.com / .cn / .com.cn), including a link without https:// (which is what copying from a chat window usually gives), and two fallbacks were added: parsing searches the whole document for trackPoints (the China-region and older share pages are not Next.js streaming chunks), and fetching still follows the 301 redirect.
Fix: Chinese text was garbled across the macOS UI. Almost all body text goes through one shared text style, and on macOS its "primary font" was pinned to a CoreText private family name (.SF NS Text). When that name fails to resolve, no fallback is left for Chinese, so the map page and the settings pages came out as garbage. macOS now uses the system default font instead (it is SF either way, so nothing looks different — the OS just does the font picking and CJK fallback), and the CJK fallback list was completed (PingFang SC / Microsoft YaHei / Noto Sans CJK SC …). Monospace areas (packets, logs, the honour wall) got CJK fallbacks as well — monospace faces carry no Chinese glyphs either. A new check refuses that private family name and requires the three platforms' CJK families.
Fix: the length counter above the chat input was not live (reported: it only updated once the field lost focus). It was computed by reading the field during a page build, and typing only rebuilds the text field itself, never the counter beside it; losing focus happens to be one such rebuild, which is why it looked focus-driven. It now listens to the input (typing rebuilds just that one row, not the whole messages page), the translation-preview rule (the preview counts only while its source still matches what is typed) moved in with it, and a regression test goes red the moment that subscription is removed.
v2.0.9 2026-09-28
New: crash and fall detection in Life guard (beta) — judged from the phone accelerometer; it raises an alert (I am fine / call emergency services / ask nearby stations) and also shows in the notification. The test is two-stage: a sharp spike and then almost no movement for 12 seconds. With the spike alone, speed bumps and a phone dropped on a desk all qualify, and an alert that fires several times a day gets ignored; the trade-off is that a minor impact (where you can still move) will not alert — this is about "I cannot move". It can false-alarm (speed bump plus a red light), so the first button is "I am fine" and the page states it is a heuristic, not engineering-grade crash detection.
Fix: steps always showed "permission needed" even after granting it. A reading of -1 has three causes — no sensor / no activity-recognition permission / no hardware event yet (without permission the system just does not dispatch events, with no error). They were conflated, so "granted but has not walked yet" read as "permission needed". The native side now reports the permission separately and steps have four states (unsupported / needs permission / waiting for data / ok) behind one decision point; the step counting depending on the sensor-assist switch, and the grant button appearing while merely waiting, were fixed too. Fix: switches on the Life guard page did nothing (SettingsPageShell.state only serves the guide card; it does not make the page follow state changes). Fix: the speed-tier editor Save button was covered by the navigation bar — the sheet now reserves both the keyboard and the system navigation bar, taking the larger of padding and viewPadding (some ROMs only report the latter).
v2.0.8 2026-09-28
New: step counting and a leaderboard — steps come from the phone's hardware counter and can ride along in the beacon (STEPS=, off by default). A new activity leaderboard sits above the honour wall in Settings: today's steps, and tapping a row opens the station detail. You cannot see the board without contributing — every number there was sent by someone else, and receiving without sending should not get you other people's data for free. The page states plainly that it ranks the neighbours you can hear, not the whole network.
New: a "Life guard" page, and background downloads. The heart-rate alarm moved into its own Life guard page that states what it is, the exact trigger conditions, and what "ask nearby stations" does — clearly marked as beta (the judgement uses the heart-rate number only, with no medical basis). Update downloads now run in the background: leaving the page or backgrounding the app keeps it going, progress shows in the notification, and it can be cancelled. It writes a .part file and renames atomically, so an interrupted download never leaves an uninstallable package behind.
Fix: the heart-rate alarm limits could not be changed — the fields only saved on the keyboard's enter key, not on focus loss, so editing and tapping elsewhere saved nothing. Input now saves as you type, and the card shows "Currently active 40 ~ 150 bpm".
v2.0.7 2026-09-28
Fix: dragging the immersive map jumped to Beijing. The follow-mode viewport offset was never handed to manual mode, so a drag snapped the map to the projection base point. It now picks up the current viewport first, and the map rotation is accounted for (with the heading up, a screen drag must be converted back to canvas space).
New: a "Detailed" beacon status bar showing what will actually trigger the next report (active tier, seconds left, metres until the distance trigger, degrees until the turn trigger). New: heart-rate alarm — an out-of-range reading raises a warning and a notification, offering an emergency call or a help message to the 5 closest stations within 100 km; it only warns, never acts for you. New: idle the phone GPS while an external GPS feeds data, switching back and saying so when the external source goes stale.
Fixes: the notice banner reappears when the notice changes; network-only positioning can use its own station icon; the 2.0 connection banner says what is missing; the sponsors entry moved above "About". Update page: the channel text follows the current channel, long release notes are collapsed by default, and the button turns into "Install" after downloading. Floating panels and the exit animation: panels and the bottom pill now use the system-UI inset (it used to compute as 0 on some ROMs), and the "flat colour then gone" exit is fixed.
v2.0.6 2026-09-28
Heart-rate logging and charts on the history track page. Track points now record heart rate (from the same source as HR= in the beacon comment: a BLE chest strap or Garmin LiveTrack), and the day detail page gains three polylines — heart rate / speed / distance — each of which can be toggled, or the whole panel hidden. A vertical cursor follows playback, and the heart-rate row shows the day's min–max. Gaps with no reading are drawn as breaks, not straight lines. A day can hold 40,000 points, so the curves are bucketed once to 240 points on entry; playback stays smooth.
Selectable audio devices and TX serial port on Windows. The audio page can now pick the playback and capture device instead of being stuck with the system default — which decides what actually feeds your radio. The TNC device page can pick a separate TX serial port; the default is still one port for both directions, and splitting them avoids two handles fighting over one COM port on Windows. (Android/iOS hide the audio picker: routing there is the OS's job, and a fake switch would only mislead.)
A round of user-reported fixes (#12, #13, #15, #16, #18, #19). (1) The "Advanced" extras on the station identity card could not be cleared: empty means "do not send", but saving merely skipped the write, so the old value stayed on disk and came back after a restart — clearing now removes it. (2) A custom status was overwritten by the 15-second keep-alive frame; a custom status is now re-sent right after it. (3) Android 15 forces edge-to-edge, so the navigation bar covered buttons at the bottom of a page — scrollable content now reserves that inset. (4) Expand/collapse on settings pages flashed or snapped; height and opacity now animate together. (5) The download button stayed after finishing (a file-name version 2.0.5 was compared against the tag v2.0.5, which never matches); the comparison now ignores the v prefix. (6) The update channel now defaults to GitHub (one tap switches back to the mirror).
v2.0.5 2026-09-27
Fix: 2.0.4's PHG never actually took effect for third parties. In 2.0.4 the data extensions were space-separated (000/000 PHG2130 /A=000033), and the reference implementation (aprslib) reports phg as missing entirely with PHG2130 left as ordinary comment text — meaning third-party maps showed no coverage and the feature did nothing. Two independent traps caused it: (1) APRS101 defines PHG / /A= / CsT as fixed-length data extensions that must be glued to the symbol with no separators (real stations look like …ErPHG1460/A=000071); (2) CsT and PHG compete for the same "start of comment" slot — parsers match ^\d{3}/\d{3} first and, once it hits, only look for a DF report and never search for PHG, so even glued together PHG stays unreadable while 000/000 comes first.
The fix: keep the extension block glued together and give the first slot to PHG — when PHG is present, CsT is no longer sent with the position packet. Afterwards: !2155.17N/11052.40EbPHG2130/A=000033 Bat:22% (spaces appear only between the block and the comment). One trade-off: a mobile station that also fills in PHG shows no speed/bearing on aprs.fi — both need that single "start of comment" slot and cannot coexist; stations without PHG are unaffected. The beacon packet's third-party compatibility test now runs in CI, so this class of "compiles, analyze is green, third parties cannot read it" bug has a guard.
v2.0.4 2026-09-27
Position packet data extension (PHG, APRS101 chapter 9): under Radio settings → "Station comment" there is now an "Advanced" section taking power (W) / antenna height (ft) / gain (dB). Filling in any one of them appends the fixed 7-byte PHGphgd; leaving them empty sends nothing at all. The encoding follows the spec: power uses the largest step that does not exceed the real value (25 W reports 25, and 30 W still reports 25 — over-reporting claims coverage you do not have) and antenna height snaps to 10×2ⁿ feet. The settings page echoes back what will actually be encoded, since quantisation is invisible and there would otherwise be no way to know what went out. In the packet the extension sits where the spec puts it: PHGphgd comes immediately after the symbol (right after !lat/lon/symbol, ahead of the /A= altitude and any other comment text), matching the standard packet …:!2216.45N/11113.90ErPHG5950 — third-party parsers look for PHG as a data extension at the start of the comment, and reading it after other fields fails.
Standalone status packets: the Advanced section takes a status text, sharing one "Transmit" button with the position packet — whichever has content is sent, and an empty status text sends the built-in APRSlocus CONNECT vX.Y.Z online frame. A status packet is a frame of its own (>-prefixed, carrying no coordinates, and it does not move you on aprs.fi), so it can be sent even without a fix. Transmitting reads the current contents of the field directly instead of relying on input-event timing — with an IME composing text the app used to send the default frame although the user had typed something. A manually entered altitude was added too: empty follows the fix (the default is unchanged), and the settings page shows the /A=aaaaaa fragment that will be sent.
Station details and the map info window: station details gained a line for the standalone status packet (purple, with a megaphone icon), shown separately from the position comment — the two come from different packets (frequencies usually live in the position comment, device provenance in the status packet), and merging them makes it impossible to tell which is which. That text used to appear only in the raw packet console and never on the station. The map marker info window gained altitude, position comment and status text lines, each appearing only when present rather than as a permanent placeholder — few stations carry these fields, and placeholders would print two rows of --, making "absent" and "not received" look identical.
Fixes in this build: (1) the Transmit button checks the link first and says "connect the link first" instead of silently recording locally; (2) PHG without a fix is reported honestly — the receipt says the position packet with PHG was not sent; (3) status packets use their own connection text (previously the banner claimed "position beacon sent" when only a status frame had gone out); (4) the countdown for the next report on the map page now ticks every second (it used to freeze when no station update arrived); (5) the link self-test on the device page no longer shows its title and subtitle twice; (6) the phone-battery switch stays on the beacon page ("Beacon contents") with unchanged defaults.
v2.0.2 2026-09-26
New Baidu Map / Baidu Satellite sources: Baidu is not Web Mercator (BD-09 coordinates plus its own projection, tiles with a north-pointing y-axis), so a per-source projection now runs through the whole chain — rendering, markers / tracks, the immersive map, the tracker, track replay and offline downloads share one projection, and markers no longer drift against the tiles.
New "Network only" location mode: cell / Wi-Fi only (GPS not registered), for devices without GPS and for extreme battery saving; auto-beaconing uses a dedicated fixed interval (default 300s, configurable) — no force switch needed, and smart beaconing does not apply because network fixes have no reliable speed.
Notices can embed video: the in-app notice is now hand-written Markdown (Simplified Chinese / Traditional Chinese / English) and an @video marker plays in-app (Android / iOS / macOS; Windows / Linux / Web fall back to the external browser). Older versions simply show that line as plain text (still a link).
Update check on launch: the app checks once on start and shows a reminder when a new version exists (once per version, dismissible).
Fixes: the map info window still showed "Tap to view" (2.0.1 only changed the generated l10n output and missed the ARB source, so the build reverted it; fixed in all six languages); the Windows build now drops the webview_windows plugin that is incompatible with the current toolchain and opens such links externally.
v2.0.0 2026-09-25
TOUCH SKY · 2.0: the 322 updates from 1.5.8 to 2.0 land together — the new UI 2.0 (a map-first layout with a draggable sheet, bottom capsule nav, landscape unified across phone / tablet / desktop), frosted-glass and mica materials, the immersive map with many sources, offline maps and track replay, aprs.org device identification, group chat and 7 translation providers, Bluetooth and sound-card TNCs, iGate and PKWDWPL, native iOS / macOS location, smart beaconing by turn and by distance, weather and HF propagation advice, Android home-screen widgets, ADIF export and the packet console, Garmin sharing and BLE heart-rate straps, and six UI languages.
v1.6.173 2026-09-24
The Garmin page now has auto-fill, a confirm button and a status display (reported from a real device). (1) The URL field used to read the state once at init, so a share arriving while the page was already open would never fill it in — it now follows the state and says "Share link filled in automatically". (2) There used to be only an ambiguous switch (labelled "Tracking", a state rather than an action) — it is now explicit [Start tracking] / [Stop tracking] buttons. (3) A new status card shows Not tracking / Tracking (with forwarded-point count and last update time) / Fetch failed (with the reason), and the field shows "Link is valid" live. The share toast also lasts 8s instead of 4s so it is not missed.
v1.6.172 2026-09-24
The About page name card no longer touches the section below — the "Code contributions" header used to start immediately after it (0 gap); it now has 22, matching the other sections. Also, "which position source wins?" is now stated: the UI used to describe it in two halves (beacon page "Location / Simulated", Devices page "Phone GPS / Garmin"), which read as two different things. There is now one decision (positionSourceNow) whose priority is written in both places — simulated/manual › Garmin (while the watch has live data) › phone GPS — and the beacon page option is renamed to "Phone GPS" (matching the Devices page), with an "In use now: …" line.
v1.6.171 2026-09-24
Garmin sharing "sometimes works, sometimes doesn't" is fixed. (1) Share text was only read from EXTRA_TEXT, while plenty of apps (some Garmin versions, browsers) put it in clipData — a null read made the whole share go silent, which is exactly the intermittent mechanism. (2) No text meant a silent return, with neither a message nor a log line. (3) A cold-start race: the share can arrive before the UI registers the callback, so the callback is null and the event is dropped (the "still no feedback after the hand-off") — it is now "call if present, otherwise store", with the UI consuming it once it is up. Link detection was widened too: the short code is unbounded in length and case-insensitive.
v1.6.170 2026-09-24
Heart rate now names its source (on request): there are two sources (a BLE strap / the heart rate carried in Garmin points), so while Garmin is supplying data both the heart-rate card and the heart-rate row of the data-sources card say "Heart rate from Garmin LiveTrack (watch) · 128 bpm" — no strap required, and it is obvious where the number comes from. Also About page spacing (reported as too tight): section header → card 8 → 12, and inside the credits card the "test members" label → callsign chips 8 → 11 with chip gaps 8 → 10, and the BA3RZL group 6 → 8.
v1.6.169 2026-09-24
Garmin sharing was still silent in the 1.0 layout: the previous release made "the shared content has no link" visible too, but that callback was registered only in the 2.0 shell — so on 1.0 sharing still showed nothing, exactly like "not recognised". The 1.0 shell now registers both callbacks: a link shows a notice plus an "Open settings" action, and a share without a link says so plainly (failures are visible too).
v1.6.168 2026-09-24
"Position source" is now an honest status row, not a two-way choice (pointed out from a real device): with tracking not started, "Phone GPS" still showed a filled selection dot (nothing was running) and "Garmin" could be "selected" — the state only looked at the switch, never at whether tracking was running. Garmin and the phone GPS are not a choice at all: while the watch is live it wins, and after 120s without a fresh point the phone takes over. It now reports reality: "Not tracking (location off)" / "Tracking" / "Tracking (phone GPS stepped aside)" / "Link set, but Garmin has no fresh points"; the heart-rate row shows the current bpm too.
v1.6.167 2026-09-24
The beacon UI now says where the position comes from. While Garmin is live the beacon bar shows "Garmin · 45s · ❤128" in red instead of an indistinguishable countdown (the two positions can be tens of kilometres apart). A coarse (cell/Wi-Fi) fix is now blocked from replacing the watch position: once Garmin goes stale the phone GPS rightly takes over, but a cell-tower centroid must not — the bar would still show a normal countdown, so nothing on screen reveals a wrong coordinate is being transmitted. Garmin and the strap also became selectable "data sources" (position source: phone GPS / Garmin; heart-rate source: the BLE strap), listed separately from the packet links, and the manual-beacon toast now lists what was actually attached (e.g. "Grid FN20xx · HR 128 bpm").
v1.6.166 2026-09-24
Fix: the short link the Garmin app shares (gar.mn/…) never got through. Garmin's Share button produces a short link, but the app only accepted the long form and the Android share target only allowed that host — so "Share → APRSlocus" did nothing. Both forms are recognised now (including a bare gar.mn/xxx with no scheme), redirects are followed, and the token is masked before logging, because a share link is the credential for reading a live position.
v1.6.165 2026-09-24
Bluetooth heart-rate straps (standard BLE service 0x180D): the beacon settings page can scan/connect and show the current BPM, with a new "Send heart rate in beacon" switch (on by default) that adds HR=nn to the position comment — and sends nothing without a reading (HR=0 would read as "pulse 0"). It does not fight with the TNC link: TNC uses classic Bluetooth SPP while heart rate uses BLE GATT, they run in parallel, classic discovery (which would tear down the SPP link) is never used, and a device already held by TNC is rejected with a reason.
Garmin LiveTrack: your watch activity can feed straight in — either share it from the Garmin Connect app to APRSlocus (a registered system share target), or paste the link on the new "Garmin LiveTrack" page (clipboard button included). It reads trackPoints from the public share page (position, altitude, speed, heart rate) and accepts only points up to 120s old, skips to the newest past a 60s backlog, and forwards at most one point every 10s; while Garmin is live the phone GPS steps aside automatically.
Heart rate on the main screen (the first chip in the map top-left column, tagged BLE or Garmin, and hidden entirely with no reading). Two gaps while Garmin is driving are closed: the heading was not computed at all (Garmin points carry none, so the compass froze on the phone GPS last value) and it is now derived from the previous point; and the daily history log was not written while the phone GPS was standing down, leaving a blank stretch — it now records like the GPS path. The device page also gained an "Other data sources" card (strap + Garmin), which is independent of the packet links and can run alongside them.
v1.6.164 2026-09-24
Three layout fixes. (1) In the About share sheet the title and subtitle sat flush against each other (0 gap); now 3px, with 14→18px above the option list and 8→10px between options. (2) The About cover switched to contain whenever "container width / card height > 1.62" — but the card height is capped at 300 while the container reaches 600, so that held on every screen 600 wide or more: the photo shrank to a band in the middle with 75px of blank space on each side, and in landscape the logo card sat on that left gap (the "logo backdrop isn't filled" report). It is now cover + topCenter, filling the card while keeping the snow-capped summit. (3) The messages page switched columns by orientation (any landscape screen got two columns), but the 2.0 landscape shell puts it in the ≤560 left pane (often 200–280 on a phone), where the fixed 280 list column squeezed the chat column to a negative width. Column switching now looks only at the available width, the list column follows its container, and a new narrow-container degradation lets the callsign ellipsise and wraps the group action chips onto their own row (nothing hidden).
v1.6.163 2026-09-24
Network positioning is de-emphasised overall: coarse (cell/Wi-Fi) fixes are never transmitted automatically. An automatic beacon is a public statement of "I am here", and a coarse fix is routinely hundreds of metres off and wanders in place — what goes out is a wrong coordinate. The map beacon bar, immersive map, home page and settings all say "network fix · auto beacon paused", and reporting resumes the moment GPS is back (manual "beacon now" is unaffected). Three thresholds were tightened at the same time: a coarse fix is only used once GPS has been stale for 300s (was 120s), its self-jump limit is 3km (was 8km), and its accuracy floor is 300m (was 150m). Coarse fixes no longer move the APRS-IS filter centre either — the filter string is rounded to 0.01°, so a drift could trigger a full link reconnect.
Landscape polish for phone, tablet and desktop. (1) Widths inside the pane are no longer computed from the screen — message bubbles used to take "screen width × 0.55", which on a 1920 desktop is 1056px, silently clipped by the pane so long messages were cut off (they now use the message area's actual width). (2) The top-left station chip degrades to "online + stations" when the map area is narrow (landscape with the pane open often leaves only about 200px). (3) "Short landscape" is now judged by the height actually available below the top bar — the disconnected and notice banners each take a row — so the clipped, unreachable locate button at the bottom of the tool column is no longer missed. (4) Self-drawn buttons on desktop are wrapped in ClickCursor (MouseRegion + SystemMouseCursors.click), because GestureDetector has no mouseCursor parameter, so a hover shows a hand cursor.
About page: the name card is no longer cramped — bigger header padding, title/subtitle gap 2→4px, title 13.5→14.5, a roomier share row, and the website icon went 32→34 with a hover tooltip on desktop.
v1.6.162 2026-09-23
Guide/overlay overlap on the map is fixed. The previous build hard-coded the guide card at topBase+46, right on top of the immersive-map entry. Merging it into the same column fixed that, but measuring the real geometry showed it was one pixel from intersecting the legend — a layout that relies on "it just barely fits" breaks with a longer language or a different text scale. So both full-screen map views now use a one-off bottom sheet: with overlays on every side there is no position where a floating card is safe. The sheet only fires when the page is actually in the foreground.
The card is smaller and quieter: tint 8%→6%, border 22%→16%, icon chip 30→28, and the lone × became a "Got it" text button. The map copy was shortened (the card is only ~300px wide there and used to wrap to four lines). check_landscape_layout.py no longer counts occurrences of leftInset but judges the structure instead — counting implementation details punishes refactoring, and it produced a false failure this time.
v1.6.161 2026-09-23
Feature guides: sixteen pages now show a dismissible one-off tip card at the top of the body on first visit, saying in one line what the page does and where to start. Closing it records "seen", after which it never appears and takes up no space. Sub-pages built on the settings shell also gain a "show this guide again" button in the app bar. Covered: map, station list, immersive map, messages, packets, devices, settings, offline maps, log, backup, track replay, theme, translation, sound-card TNC, Bluetooth TNC and PKWDWPL
The "seen" record is stored in settings and included in backups (a restored device should not replay guides the user already read), and settings gained "show all feature guides again", which clears the record. A new static check, tool/check_guides.py, ties the guide table, the six-locale text, the generated l10n output and the page call-sites together — missing any one of them breaks neither the build nor the tests, it just means the guide never appears. The check caught three real problems the moment it was written
v1.6.160 2026-09-23
The About page business card no longer overlaps the hero: the previous build lifted it 14px onto the bottom edge of the photo, which on a real device hid a strip of the image and cut the card's rounded corners into it, looking like a misalignment. The card now sits below the hero with a 12px gap, leaving the photo intact
v1.6.159 2026-09-23
About page redesigned: the hero cover is now a real photograph of Pico del Teide instead of the logo backdrop, with the version in a glass pill at the top-right and the logo and title anchored to the lower-left over a gradient. The hero height now follows the window width (width × 0.64, 196–300) and switches to “fit entirely” on ultra-wide screens so the volcano is never cropped; the hero and body now share one width-capped container (600) on desktop
Removed the Features section from the About page (the seven rows for live map, GPS, beacon, messages, auto-connect, layer filter and FMO duplicated what the app already shows). The share entry became a full-width tappable row, section headers gained a tinted icon chip and a trailing hairline rule, and the footer gained a divider plus a photo credit for the cover
About page relaid out as a business card: a card now rides the bottom edge of the hero (callsign and name, a globe button and a full-width share row), and the section count drops from 8 to 5 — "Open source thanks + License" became "Open source & licence" (the four projects in a 2×2 grid) and "Test members + AI compute support + Sponsor entry" became "Credits" (callsigns as wrapping chips). The author's personal site theez.top and the "site owner" label are removed, and the globe button now opens the app's own website (already listed under Feedback)
v1.6.158 2026-09-23
Fixed the flash when leaving a Settings sub-page: the transition backdrop decided “is the transition over” from the value, but on pop reverse() only changes the status — the value moves a frame later — so the page underneath showed through for one full frame (visible only with the material or a background image enabled)
The announcement entry moved to the bottom of the Settings home screen (after Backup, before About); the Settings sub-page no longer shows a banner, only the toggle. The entry only goes online when tapped, so it still works with the toggle off — without breaking the “off means no background network requests” promise
v1.6.157 2026-09-23
The announcement banner moved to the home screen (above the map, in both 1.0 and 2.0) with another copy in Settings; it now opens in a bottom sheet (scrollable, drag to dismiss) and carries its own close button — switch it back on in Settings any time
Fixed the base-map panel that would not open: that button's callback was missing its parentheses (returning the function instead of calling it) — broken since v1.6.151, and neither the compiler nor analyze reports it
v1.6.156 2026-09-23
New announcement banner (Settings → Display, on by default): its content is taken straight from the website homepage announcement, so publishing a notice needs no app release. Markdown (headings, lists, tables, images) and hyperlinks are rendered in-app, with the last cached copy shown offline
Smart beaconing gains a third trigger: turning — a point is added once you turn past the configured angle, set per tier (10–180°, 0 = off). On mountain roads you are slow, so the distance threshold takes ages to reach, yet those hairpins are exactly where the track matters most
The station comment field now looks editable: that row used to be entirely blank (no border, no placeholder), indistinguishable from the static "label + value" rows. Empty fields now show a placeholder, the input area has a fill and border, and the border turns blue on focus — all 42 input rows benefit
v1.6.155 2026-09-23
Fixed map buttons that “did nothing”: the layers and zoom buttons only responded on the small centre icon — now the whole button works
A much clearer offline notice: an orange bar above the map, tappable anywhere to connect — no longer just a tiny pill in the corner
Opening a chat now raises the panel by itself (the input box is no longer hidden below the fold); “View on map” from the station list switches back to the map and collapses the panel
v1.6.154 2026-09-23
Live track sampling refined from 10 s to 1 s so corners are no longer cut into diagonals; the points actually sent to the server are marked with small orange diamonds, so count and spacing are visible at a glance
Smart beaconing can now trigger by distance: each tier takes an “or N metres” value, so fast movement adds points while standing still falls back to pure timing
v1.6.153 2026-09-22
Fixed the UI 2.0 sheet having its bottom edge cut into right angles: the clip now rounds the bottom corners, so a half-open panel still looks like a complete rounded card
v1.6.152 2026-09-22
Frosted glass optimised again: surfaces over the same backdrop share a single sample, and shells that only sit on the wallpaper no longer blur — smoother list scrolling, pixel-identical looks
v1.6.151 2026-09-22
UI 2.0 landscape: five defects that only show up on a real device, including the rail covering the map’s controls, the tool column clipping “locate”, and the bottom inset counting the safe area twice
v1.6.150 2026-09-22
Tap into a day in track history and replay it on the map (the line grows as it plays, 0.5×–4× speed, follow view; stops over 45 s are fast-forwarded)
Network fixes no longer make the marker fly around: coarse points are dropped while GPS is fresh, and only allowed as a fallback after 2 minutes without an GPS update
v1.6.149 2026-09-22
Clustering removed: both maps are back to one marker per station, with low-zoom density left to the heatmap (its toggle stays)
More accurate track points (Android): the compass fills in heading at low speed and the accelerometer decides whether you are moving; on by default, switchable
Personal track history: saved per day on the device, with total distance, average and top speed and moving time in Settings; delete a day or clear all
The "no stations in view" pill is gone: the map already has an info chip and a toolbar
v1.6.139 2026-09-21
UI 2.0: a new map-first layout, switchable back to the classic one in Display settings
v1.6.138 2026-09-20
UI materials: frosted glass and mica, switchable in Display settings
v1.6.136 2026-09-19
New "hardware serial": USB-OTG serial on Android to wire a radio, with desktop serial parameters you can tune
v1.6.135 2026-09-19
On-air audio that others could not decode: media volume is maxed and the mic muted during TX, with wiring and level hints
v1.6.128 2026-09-18
Offline maps: download the tiles of the current view once (resumable, 200k tiles per region) and keep the map with no network at all
v1.6.124 2026-09-18
Themes: recolour the UI, replace icons and text, and export the result as JSON to share
Themes can carry a background image — your own photo behind the UI; exports can include it too (v1.6.125–126)
v1.6.123 2026-09-18
Backup and restore: settings and data export to a single JSON, import it after a reinstall
v1.6.121 2026-09-17
The HF widget gained 6 m band forecasts, widgets gained dark mode, and a system-status widget was added
v1.6.117 2026-09-17
HF and ionospheric propagation: a new panel section plus a standalone widget, with SFI / Kp / A and day/night conditions for four band pairs at a glance
v1.6.114 2026-09-17
New Android home-screen widgets: weather plus ham-radio tips, in four adaptive sizes
v1.6.113 2026-09-15
Fixed "the longer it runs the slower it gets": the APRS-IS connection was rebuilt repeatedly, leaking sockets
v1.6.109 2026-09-15
Bigger home-page beacon / connect buttons (44px tall, 13px label)
A PKWDWPL-only setup is now allowed: use the radio as a pure receiver; the UI states plainly that nothing is transmitted
v1.6.108 2026-09-15
New fourth data source "PKWDWPL": reads the $PKWDWPL waypoint sentences a Kenwood radio emits, plotting heard stations directly (receive-only, never transmits)
v1.6.107 2026-09-15
New gateway (iGate): relays RF packets into APRS-IS with qAr / qAR tagging, loop protection and 30-second de-duplication
Data sources became multi-select: several links can receive at once, while the transmit source stays a single choice
v1.6.106 2026-09-14
The actual fix for "Bluetooth TNC receives but will not transmit" (Android)
v1.6.105 2026-09-14
Device settings split from one catch-all page into three pages grouped by the question you are asking
Group-chat protocol consolidated into a single state machine
v1.6.104 2026-09-14
New "Audio (sound-card TNC)" data source: AFSK 1200 through your mic / speaker and a radio
New link self-test: layered one-tap diagnosis for both TNC and audio
v1.6.100 2026-09-13
New data source: Bluetooth TNC with full KISS control — the move from network-only towards RF
Chat translation: two-way, side-by-side, and pre-send into the other station's language
2.0 BETA 2026-09-15
TOUCH SKY: from network-only to radio — 2.0 BETA development officially begins
Thanks to the APRS community, digipeaters, iGates, server maintainers and all open-source projects
Testers, HAMs and developers are welcome to join the 2.0 BETA
v1.6.18 2026-09-05
New: "QRZ callsign / aprs.fi position" online lookup on station details
New: Traditional Chinese (繁體中文) UI — selectable in Settings / OOBE, fully translated
Official APRS device ID via aprs.org database — vendor + model + device class
v1.6.17 2026-09-05
Station filter redesigned to single-row tap-to-filter chips; removed the FMO option
v1.6.16 2026-09-05
Filter stations down to a specific device model (official tocalls recognition)
v1.6.5 2026-09-02
New: "All changelogs" entry on the Update page — view every release note
New: Map help panel when no stations are in view (tap the hint)
Fix: Map offset on international tiles (Carto/OSM/Esri/OpenTopo) — WGS-84 projection
Removed "show all stations" auto-fit; hint now opens the help panel
v1.6.4 2026-09-02
New: Speed / altitude trend charts on the station detail page
Chart time range selectable: 10m / 30m / 1h / 3h / All
v1.6.3 2026-09-02
New: "Share APRSlocus" on the About page (system share / copy / download)
Simulated-location mode hides GPS-only settings; manual coordinates shown first
Tile map minimum zoom extended to world view (z=3)

View full release history →

Frequently Asked Questions

From Passcode to battery drain — everything we could think of. The full 23 questions, grouped by topic, live in the Help Center.

Can't receive / send messages?

Most likely an unverified Passcode. Entering -1 only lets you connect — it won't work for messaging. Visit APRS Passcode Generator to generate your own Passcode and enter it in Connection Settings. If the server returns unverified, a yellow banner appears at the top of the home page — tap "Go to Settings" to fix it.

How do I set up a Passcode?

In step 6 of the wizard or under Settings → Connection, use your full callsign (including SSID suffix, e.g. BG7LZQ-3) to generate a Passcode, then paste it in.

Connection fails / keeps dropping?

The app has built-in progressive reconnect (8 → 16 → 32 → 60 seconds). If it persists, check your network, make sure the server address (default rotate.aprs2.net:14580) and port aren't blocked, or try a different server in Connection Settings.

Can't see nearby stations on mobile?

Check if your target country/region is selected in the Receive Filter, and verify that the receive range (lat/lon + radius) covers your location. By default, only Chinese (B-prefix) stations are received.

Does background positioning drain the battery?

Android uses a foreground service for continuous positioning. You can adjust the report interval in Location / Beacon settings, or switch to manual reporting to reduce power usage. The notification bar has a one-tap "Exit" button.

Map display issues on Windows?

For best compatibility on Windows, switch to Vector Map (no API key needed) or use Carto / OSM / Esri layers in Display → Map Type.

Signature conflict / version downgrade on install?

Since v1.5.2, Android builds use the official release signature. CI and local builds use the same key — just install over the old version. If upgrading from a much older build, uninstall and reinstall.

Chat, Feedback, Development

Star, open an issue, send a PR, or join the QQ group / Discord — all welcome.

Contributors

Thank you to everyone who makes APRSlocus better.

Development
D BG7LZQ (Darion)Author · Full-stack
Translation / i18n
B BD3QIDEnglish B BA4UAXTraditional Chinese K BA7KSMTranslation
Code
B BD3QIDWLAN radio link Z 清零 (BG2HCB)Settings optimization G BH7GZBCode contribution
Support
B BA3RZLAI compute support N BH7NORProtocol interface support A APRS.TVAPRS.TV interface support
Testing
P BG7PGWFunctional testing L BG7LMWFunctional testing O BG7OSLFunctional testing I BG4LZYBug reports & feedback
Sponsors
S STUDENT HAMS communityThanks to the group for funding APRSlocus development and operations. P BG7PGWThanks for sponsoring a Mixue drink 🧋 O BG7ORCGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. J BA4JLDQingdao University of Science and Technology Amateur Radio Club · Gifted with jade I BA4IUDGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. F BD1FEHGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. R BA3RZLGifted with jade — compute given as jade, the light that keeps our long nights burning. E BG2EFXGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. W BG2WXGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. A BA8AZJGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. L BG7LZQGifted with jade — your kindness is treasured in my heart; the only return I can offer is to strive, and answer with good work. T BD4TYWGifted with jade — you gave jade, and are answered with the long wave. W BH2WIXGifted with jade — jade has a price, but a clear tone is priceless. Q BG7QZCGifted with jade — small as it is, the long wave carries it far. H BH4HGAGifted with jade — jade in hand, the echo goes on. N BH7NORProtocol interface support A APRS.TVAPRS.TV interface support E Every supporterEvery bit of your support keeps APRSlocus shining.

Want to be on this list? Translate, open a PR, or file a bug — see the contributing guide →

Friendly Links

Sites we are glad to link with.