Aug 25, 2025

Plugins with ATAK-CIV SDK 5.5

Plugins with ATAK-CIV SDK 5.5

Learn ATAK plugin development with SDK 5.5. Build drone integration plugins using MAVSDK, Kotlin, and real-time telemetry. Complete tutorial.

Introduction

The world of tactical situational awareness has been revolutionized by the Android Team Awareness Kit (ATAK) and its powerful plugin architecture. With the recent release of ATAK-CIV SDK 5.5, plugin development has taken a significant leap forward, introducing modern development approaches that simplify the creation of sophisticated tactical applications. This comprehensive guide will walk you through everything you need to know about developing ATAK plugins from basic setup to basic drone integration. We’re going to review the latest ‘Hello World’ plugin example, and then we’ll move on to building a plugin from scratch, which will read telemetry data from a drone and display it on a map.

As usual, you can follow along with the video version as well.

Understanding ATAK and Its Plugin Architecture

The ATAK platform’s core strength lies in its modular architecture, which enables extensive customization through plugins. This design philosophy allows organizations to tailor ATAK to their specific needs without modifying the core application. Plugins can add new features, integrate with external systems, customize user interfaces, or provide specialized tools for particular operational contexts.

The plugin ecosystem is remarkably diverse, offering solutions ranging from drone control interfaces like the UAS Plugin Tool to specialized communication modules, sensor integrations, and mission planning tools. Currently, there are over 30 published ATAK-CIV plugins available through Google Play and tak.gov, and many more development plugins on github.com, demonstrating the active community engagement and the platform’s versatility.

In order to build a plugin, though, you will have to first download and install the base application. Here’s the Google Play Store link for your convenience.

Once set up, you can install any plugins you like to extend the functionality. You can find a comprehensive list on tak.gov.

You can see below in the picture an example app we’ve built before. If you decide to go on from this tutorial to develop your own custom plugin, we recommend you read our tutorial Signing Your ATAK App for Production which shows how to get it signed and distributed properly in the Play Store.

ATAK’s architecture extends beyond just the Android platform. The broader TAK ecosystem includes WinTAK for Windows environments and iTAK for iOS devices, all of which can optionally intercommunicate through TAK servers or mesh networks. This interoperability ensures that teams using different devices and platforms can maintain seamless communication and data sharing.

Mesh network configuration

Client-server configuration

What’s New in ATAK-CIV SDK 5.5

The release of ATAK-CIV SDK 5.5 brings several significant improvements that modernize the plugin development experience. The most notable change is the introduction of Jetpack Compose support, allowing developers to create modern, declarative user interfaces instead of relying on traditional XML layouts. This represents a major step forward in aligning ATAK development with contemporary Android development practices.

However, the transition isn’t without its challenges. While the new SDK promises improved development workflows, developers may encounter stability issues with some of the newer features. The Compose plugin template, for instance, has shown some reliability concerns that may require developers to fall back to proven approaches while the platform matures.

The SDK also includes updated build tools and dependency management systems, requiring developers to work with specific versions of Gradle and Android Studio. These changes, while initially presenting a learning curve, ultimately provide a more stable and maintainable development environment.

Setting Up Your Development Environment

Getting started with ATAK plugin development requires careful attention to your development environment setup. The process has been streamlined in SDK 5.5, but several critical steps must be followed precisely to ensure a smooth development experience.

First, you’ll need to download the ATAK-CIV SDK from tak.gov. Note that the SDK is no longer available through GitHub and must be obtained directly from the official TAK website. While you don’t need a government account to access the civilian SDK, you are going to need a tak.gov account to access the SDK and any other resources.

The installation process involves several key steps:

  1. Download and unzip the SDK package

  2. Unzip and create a plugins directory within the SDK folder

  3. Copy Hello World plugins into the plugins directory

  4. Set Gradle Plugin Version 8.9.0

  5. Set Gradle Version 8.13

  6. Configure Android Studio to Build Variant civDebug

  7. Set up launch configurations

  8. Run application

One of the major improvements in SDK 5.5 is that developers no longer need to worry about Java version compatibility issues. While the documentation still references Java 11 and Java 17, the Android Studio version of Java works seamlessly with the new SDK.

Building Your First Plugin: The Hello World Example

The Hello World example included with ATAK SDK 5.5 serves as much more than a simple introduction—it’s a comprehensive demonstration of ATAK plugin capabilities. Unlike traditional Hello World programs, this example showcases a wide range of plugin features, including custom layouts, map interactions, sensor integration capabilities, and heat map functionality.

Everything is included in the unzipped examples directory.

To get started with the Hello World plugin, copy it from the SDK’s samples directory into your plugins folder with your ATAK-CIV{{VERSION NUMBER}}-SDK directory.

While you’re here, we also need to install the developer version of the ATAK APK from the SDK directory on your phone. You can either email it to yourself from your phone or utilize an ADB command.

Your development environment should include Android Studio Narwhal (the latest version at the time of this writing), with Gradle Plugin version 8.9.0 and Gradle version 8.13. These specific versions are crucial for compatibility with the ATAK SDK, and using different versions may result in build failures or runtime issues.

You will also need to set the build variant to civDebug.

Because our ATAK plugin sits on top of a base Android app, we need to click on Edit Configurations to change the default behavior from launching an app to launching nothing, select ‘Nothing’ in the Launch field’s dropdown.

You can now open the plugin in Android Studio and hit build. The Hello World plugin demonstrates the classic ATAK interface pattern with a map view on the left and contextual information panels on the right. This layout pattern has become the standard for ATAK plugins and provides users with familiar navigation and interaction models.

The Hello World plugin’s interface includes multiple interactive elements that demonstrate different aspects of plugin development:

  • Layout examples showing various UI component arrangements

  • Interactive buttons that demonstrate event handling

  • Map integration features

  • Sensor data visualization capabilities

Have fun playing around and seeing how all these features work and interact. This example is in Java, but modern ATAK development also supports the use of Kotlin.

Creating a Drone Integration Plugin with MAVSDK

Moving beyond the Hello World plugin functionality, let’s explore how to create a much more basic plugin from scratch that communicates with a PX4 drone using MAVSDK. This example demonstrates real-world plugin development by connecting ATAK to drone telemetry systems, providing operators with real-time position data directly within their tactical interface.

To avoid issues from the bleeding-edge release, we are going to use the legacy template as our base within the plugintemplate directory.

The plugin architecture for drone integration follows ATAK’s standard pattern but incorporates MAVSDK for MAVLink protocol communication. We’ll start with the plugin template example, which provides a cleaner foundation than the feature-rich Hello World plugin.

The core components of our drone plugin include:

  1. A simple user interface displaying latitude and longitude coordinates

  2. MAVSDK integration for receiving telemetry data

  3. Real-time data updates using coroutines and state flows

  4. MAVLink message parsing for position information

To achieve all that, we will have to go through the following steps:

  1. Convert code to Kotlin

  2. Copy code from MAVSDK-Java Android Client

  3. Change UDP port

  4. Add MavSDK libraries

  5. Configure and run jmavsim simulator

  6. Configure UDP / TCP ports

  7. Run 'app’

If you had skipped over the Hello World example, make sure to also add all the Android Studio setup steps to the process.

After copying over the plugintemplate rename it “mavsdk” for clarity. In Android Studio, go to the file menu and select Convert Java File to Kotlin File for both PluginTemplateDropDownReceiver and PluginTemplateMapComponent .

When you open the plugin directory in Android Studio, you should see the following:

There are two main files for the plugin (the two we converted), and what you would expect from a basic Android app, like the main_layout.xml.

Edit the configuration to rename the plugin mavsdk, and just like before in the Hello World example, change the Launch activity to ‘Nothing’.

We can set up our basic layout by adding a TextView in main_layout.xml for the position data:

<?xml version="1.0" encoding="utf-8"?>

<ScrollView xmlns:android="<http://schemas.android.com/apk/res/android>"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fadeScrollbars="false"
    android:layout_marginLeft="3dp"
    android:layout_marginRight="3dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
        
        <TextView
		        android:layout_width="wrap_content"
		        android:layout_height="wrap_content"
		        android:text="@string/app_name" />

        <TextView
            android:id="@+id/positionTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/position_lat_long" />

    </LinearLayout>
</ScrollView>

And be sure to add the position strings in the strings.xml file. The layout will now display the static text ‘Position:’ and the currently hard-coded latitudes and longitudes.

The plugin’s core functionality resides in the PluginTemplateDropDownReceiver class, which we’ll convert to Kotlin (see above).

In the Kotlin implementation, we establish a coroutine-based system for handling real-time position updates:

private val positionTextView: TextView = templateView.findViewById(R.id.positionTextView)

init {
    CoroutineScope(Dispatchers.IO).launch {
        position.collect { pair ->
            val newPositionString = "Position: (${pair.first}, ${pair.second})"
            withContext(Dispatchers.Main) {
                positionTextView.text = newPositionString

The PluginTemplateMapComponent serves as the plugin’s entry point and manages the MAVSDK server connection. We implement state management using StateFlow to ensure thread-safe data updates:

private val _position = MutableStateFlow(Pair(0.toDouble(), 0.toDouble()))
private val position: StateFlow<Pair<Double, Double>> = _position

Then we need to add the MAVSDK dependencies to the build.gradle file.

dependencies {
		implementation: fileTree(dir: 'libs', include: '*.jar')
		implementation: 'adroidx.core:core-ktx:1.13.1'
		implementation: 'io.mavsdk:mavskd:1.3.1'
		implementation: 'io.mavsdk:mavsdk-server:1.3.1'
}

Back in the PluginTemplateMapComponen, add code to see if the MAVSDK server is running.

override fun onCreate(
    context: Context, intent: Intent,
    view: MapView
) {
    context.setTheme(R.style.ATAKPluginTheme)
    super.onCreate(context, intent, view)
    pluginContext = context

    ddr = PluginTemplateDropDownReceiver(
        view, context, position
    )

    Log.d(TAG, msg: "registering the plugin filter")
    val ddFilter = DocumentedIntentFilter()
    ddFilter.addAction(PluginTemplateDropDownReceiver.SHOW_PLUGIN)
    registerDropDownReceiver(ddr, ddFilter)

    if (!isMavsdkServerRunning) {
        runMavsdkServer()
    }
}

The remaining code is copied from the MAVSDK Java Android client (more info below).

private fun runMavsdkServer() {
    MavsdkEventQueue.executor().execute {
        val mavsdkServerPort: Int = mavsdkServer.run( systemAddress: "udp://:14550")
        drone = System(
            BACKEND_IP_ADDRESS,
            mavsdkServerPort
        )
    }

    disposables.add(
        drone!!.telemetry.getFlightMode().distinctUntilChanged()
        .subscribe(Consumer<Telemetry.FlightMode> { flightMode: Telemetry.FlightMode ->
            Log.d(TAG, msg: "flight mode: $flightMode")
        })
    )

    disposables.add(
        drone!!.telemetry.getArmed().distinctUntilChanged()
        .subscribe(Consumer<Boolean> { armed: Boolean ->
            Log.d(TAG, msg: "armed: $armed")
        })
    )

    disposables.add(
        drone!!.telemetry.getPosition()
        .subscribe(Consumer<Telemetry.Position> { position: Telemetry.Position ->
            val latLng: Pair<Double, Double> = Pair(position.latitudeDeg, position.longitudeDeg)
            Log.d(TAG, msg: "position: (${latLng.first}, ${latLng.second})")
            _position.update { latLng }
        })
    )

    isMavsdkServerRunning = true
}

When initializing the plugin, we check if the MAVSDK server is already running and start it if necessary. The server listens for MAVLink messages on UDP port 14550 and parses incoming GPS position data.

The MAVSDK integration handles the complexity of MAVLink protocol communication, automatically parsing GPS_RAW_INT messages and extracting position coordinates. The parsed data flows through the StateFlow system to update the user interface in real-time, providing operators with current drone position information directly within their ATAK interface.

If you don’t have a drone in hand to start doing HITL testing, you can run jMavSim on WSL with these commands:

$ git clone <https://github.com/PX4/PX4-Autopilot.git>

This effectively clones the PX4 code, starts the simulator by running the make command. Once the simulator starts, it uses the mavlink start command to send messages to your phone. Make sure your phone and computer are on the same network or you will run into trouble.

Open Windows Defender and go to settings. We’re going to create an inbound rule and an outbound rule.

Set the outgoing TCP port 4560 and the incoming UDP port to 14550.

Once you have the PX4 simulator running, click on run in Android Studio to launch the plugin. Back in the ATAK, click on plugins, and you should see the list of plugins, which will include our newest one.

Cool, now we can see what everything looks like. You’ll see the updating position in the plugin when you run it this time.

Conclusion

You've explored the new features in ATAK-CIV SDK 5.5 and built your first functional plugin from the ground up. Armed with the Hello World example walkthrough and hands-on drone integration experience, you now have the foundation to create custom plugins tailored to your specific operational needs. The tools and knowledge are in place—start building your own ATAK plugin today.

Additional Resources

To learn more about drone application development, join the Drone Software Meetup group for monthly tutorials and networking.