ATAK (Android Team Awareness Kit) and its desktop sibling WinTAK are the de-facto tactical situational awareness applications used across U.S. and NATO forces, allied militaries, and increasingly civilian first responders. They render a shared common operating picture (COP), exchange Cursor-on-Target (CoT) messages over TAK Server, manage map overlays, and host an open plugin SDK. For defense software engineers, building an ATAK or WinTAK plugin is usually the fastest path to fielded capability — orders of magnitude faster than shipping a standalone tactical app.

This article is an engineering walkthrough: from empty Android Studio project to a signed, distributable plugin that survives a real operator's day. It assumes you have requested and received the ATAK-CIV SDK from tak.gov and have a TAK Server instance you can connect to.

Why ATAK/WinTAK Plugins

The strategic reason to build a plugin rather than a standalone app is leverage. ATAK already solves the hard problems: map rendering with vector and raster sources, GPS handling, radio integration, CoT messaging, multicast discovery, encrypted TAK Server transport, user identity, and a navigation model operators have trained on for years. A plugin inherits all of that for free.

The tactical reason is adoption. An operator who already runs ATAK on a Samsung S22 Tactical Edition or a Galaxy XCover with a chest harness will install another plugin in seconds. Convincing the same operator to install, learn, and trust a second standalone tactical app is a much higher friction path. Plugins ride the existing trust surface. For new sensors, mission-specific workflows, drone integration, or NATO-specific message translators, a plugin is almost always the correct delivery format.

ATAK is a platform, not just an app. Treating it as a platform — and your code as a participant in that platform's contracts — is the mindset shift required to ship plugins that pass operator review.

ATAK-CIV vs ATAK-MIL

There are two ATAK editions a plugin author cares about. ATAK-CIV is the civilian release distributed via the Google Play Store and via tak.gov for unrestricted use. ATAK-MIL is the military variant maintained by the U.S. Army DEVCOM C5ISR Center and distributed only through controlled channels to authorized units.

From an SDK perspective the two share a common plugin API — the same AbstractPlugin, the same MapView, the same CotEventDispatcher. The differences that matter to a plugin engineer are: ATAK-MIL includes classified data adapters, military-specific symbology (MIL-STD-2525D fully populated), radio drivers for SRW, ANW2C, Link 16 gateways, and security controls that gate plugin loading by signing key. A plugin compiled against ATAK-CIV will load against ATAK-MIL provided the API version matches and the plugin is signed by an approved key — but UI and capability assumptions can break if you depend on widgets that exist only in one edition.

Prototype on ATAK-CIV. The SDK is open, the device requirements are lower, and you can iterate against a public TAK Server. When the capability is proven, port to ATAK-MIL: re-sign with the approved military signing chain, validate against the target API version, and re-test on actual end-user devices (typically EUD-class Samsung handsets or Persistent Systems MPU5 puck displays).

Project Skeleton

An ATAK plugin is an Android library module with a specific manifest contract. Start from the plugin-template Gradle project shipped inside the ATAK-CIV SDK. The dependencies that matter: the main.jar from the SDK (ATAK API), gradle-atak-plugin Gradle plugin, and AndroidX libraries pinned to the versions ATAK itself ships with — version skew here is a common cause of NoSuchMethodError at runtime.

The AndroidManifest.xml must declare the plugin descriptor metadata: com.atakmap.app.component pointing at your AbstractPlugin subclass, the API version the plugin targets, and the permissions you require. ATAK uses the manifest to discover and load plugins; an incorrect descriptor is the most common reason a plugin fails to appear in the ATAK plugin manager.

Lifecycle hooks live on AbstractPlugin (also surfaced as IPlugin in newer SDK versions). onCreate(Context, MapView) is where you register tools, drop-downs, layers, and listeners. onDestroyImpl is where you must unregister them — failing to do so leaks listeners across plugin reloads, which is a real scenario during operator updates. onConfigurationChanged handles device rotation and theme changes. Treat lifecycle methods like Android Activity lifecycle: assume they can be called multiple times in unexpected orders.

API version compatibility is enforced at load time. ATAK 4.x to 5.x has shipped breaking API changes; pin PluginAPI in your manifest to the lowest version you support, and test against every minor release in your target deployment. A compatibility matrix in your README — "this plugin: ATAK-CIV 4.10 through 5.2, ATAK-MIL 5.0+" — is the contract operators will hold you to.

CoT Integration

Cursor-on-Target (CoT) is the XML message format every TAK ecosystem participant speaks. Each CoT event has a UID, type code (a hierarchical string like a-f-G-U-C-I for friendly ground unit, combat, infantry), point (lat/lon/hae), time, stale time, and arbitrary detail children. Plugins emit CoT to report sensor contacts, missions, geofences, and custom track types; they consume CoT to react to events the operator or other systems produce.

The two API surfaces that matter: CotMapComponent exposes the central CotEventDispatcher for inbound events, and CotMapComponent.getInternalDispatcher() plus CommsMapComponent.getInstance().sendCoT(event) for outbound. Register a CotEventListener in onCreate, filter on type prefix, and dispatch into your plugin's domain logic. For outbound events, build the CotEvent programmatically — do not concatenate XML strings. Operators have lost track icons because of malformed XML produced by string templating.

Schema validation prevents tactical data corruption. Validate every inbound CoT event against the expected detail schema before trusting its contents — type code, point bounds (a lat of 9000 is a parser bug somewhere upstream that you do not want propagating into your overlay), and stale time monotonicity. CoT is permissive by design; defensive parsing is the plugin author's responsibility.

Map Layer Plugins

The single most common ATAK plugin pattern is adding a custom map overlay: drone telemetry, EW (electronic warfare) signal coverage, friendly artillery fans, no-strike zones, mesh radio coverage estimates. ATAK's map stack is GLMapView (OpenGL ES) with a layer ordering model based on integer z-order plus visibility groups.

Add layers by subclassing AbstractLayer for vector data or extending TileClientControl for raster overlays. MapItem is the unit of interactive content — markers, shapes, drawing primitives — and has a full lifecycle: onMapItemEvent fires for clicks, drags, deletes, and visibility changes. Long-lived plugins must remove their MapItems on onDestroyImpl; orphaned items persist across plugin reloads and confuse operators.

Performance matters more than people expect. Thousands of features at once is normal — a wide-area ISR feed easily produces 5,000 to 20,000 visible tracks. Cluster aggressively, use Marker.setVisible(false) rather than removing/recreating, and offload heavy math (geodesic buffers, viewshed calculations) off the UI thread. Hit a 60fps target on a Samsung S22 Tactical; if you cannot, your plugin will be uninstalled.

UI Discipline

ATAK's UI conventions exist for a reason: an operator wearing gloves, in low light, possibly under fire, navigates by muscle memory. Drop-Downs (the right-side sliding panel) are the canonical way to surface plugin UI. Extend DropDownReceiver, register your intent action, and let ATAK manage the show/hide lifecycle. Do not pop your own dialog windows over the map — they break the map gesture stack and disorient operators.

Navigation menu placement is governed by tool registration. Use ToolbarBroadcastReceiver or the newer plugin pane API to place your entry point in the right toolbar or overflow tray. Naming matters: short verbs ("Track", "Mark", "Scan"), not nouns ("Tracking Manager"). Icons must read at 24dp on a 5-inch screen in direct sunlight — that means high-contrast, single-foreground-shape, no gradient.

Dark mode is the only mode. ATAK's default theme is built for low-light operation and night-vision compatibility. Never introduce a white background in a Drop-Down — it floods the operator's NV optics and announces their position. Use the ATAK theme constants (atakmap.android.R.style.ATAK_TextAppearance and friends) so your widgets pick up the operator's preferred profile, including the red-light NVG-compatible mode.

Plugin Signing and Distribution

ATAK enforces plugin signing as a load-time gate. Every plugin APK must be signed with a key the running ATAK installation trusts. ATAK-CIV ships with a permissive trust store that accepts the development debug key plus a small set of community keys; ATAK-MIL accepts only keys issued by the controlling military authority. Plan signing early — re-signing a plugin already in operator hands requires re-distribution.

The signing chain is standard Android: keytool to generate the keystore, jarsigner or Gradle signingConfigs to sign the APK, apksigner v2/v3 to verify. ATAK validates the signature at load time and surfaces "Plugin signature invalid" in the plugin manager when it fails — a generic error that, in practice, almost always means key mismatch or APK Signature Scheme version mismatch.

Distribution paths vary by edition. ATAK-CIV plugins distribute through the Play Store, tak.gov, or sideload via the plugin manager's URL fetch. ATAK-MIL plugins distribute through military app stores (NIPRNet/SIPRNet repositories, unit-specific MDM channels) with vetting cycles that can take weeks. Version-pinning is contractual: an MDM rollout typically locks both ATAK and plugin versions, and an out-of-band plugin update is not an option once a rotation has deployed.

Production Realities

Battery is the first production constraint. A plugin that wakes the GPS every second or holds a partial wake-lock will drain an EUD battery before a four-hour patrol completes. Profile with Android's Battery Historian, prefer ATAK's existing location services (which already deduplicate fixes across plugins), and never schedule background work that does not gate on operator intent.

Low-network operation is the second. ATAK is designed to operate disconnected and intermittently connected; any plugin that assumes IP reachability fails the moment the operator walks off the FOB. Queue outbound work to disk, drain on reconnect, and degrade gracefully — the patterns are the same as those for offline-first military apps and the MBTiles/PMTiles offline map stack that ATAK itself uses.

Telemetry is the third, and the most constrained. OPSEC requires that plugins do not phone home — not to your analytics endpoint, not to a crash reporter, not to a license server. Bake telemetry into the local log file ATAK already maintains, surface it through the ATAK debug bundle export, and let the unit decide whether to share. The instinct to ship Firebase Crashlytics into a tactical plugin will end the plugin's deployment authorization.

Support cycles align to ATAK's release cadence, not your roadmap. ATAK-CIV releases roughly quarterly; ATAK-MIL releases on military timelines that can extend a single version for 18 months. Maintain a rolling support window — current version plus the two prior minor versions is a sustainable contract — and treat ATAK release notes as a mandatory input to your regression plan. A capability that integrates with broader C2 systems or feeds NATO tactical data links through a plugin is only as reliable as your discipline around the ATAK release train.