Common questions, with answers, so you don't have to ask. If your problem isn't here, open an issue: https://github.com/nomar2/Tower/issues — include your phone model, Android version, flight-controller firmware, and how you connect (USB serial / Wi-Fi / TCP / UDP).
This is a one-person fork with best-effort support. The connection and mission paths are flight-tested on real hardware (see the README); other areas may not be.
tower-<version>-release.apk— normal use. Smaller, no debug logging, signed with a stable key so future updates install over it.tower-<version>-dev-debug.apk— sideload / testing. Different app id (.debug), installs alongside the release build.
They can both be installed at the same time.
Yes. Built and tested on Android 10 through Android 16.
You have an older Tower or DroidPlanner (or the other APK from this repo) installed, signed with a different key. Uninstall it first, then install the new one. There is no way around this — Android won't replace an app signed with a different certificate.
No. Download the APK from the Releases page.
The app needs a Google Maps API key and doesn't ship with one (keys are tied to a billing account and can't be published).
If you built it yourself:
- In
local.propertiesaddMAPS_API_KEY=.... - In the Google Cloud console, enable Maps SDK for Android on that key.
- Add an Android app restriction for the package
(
org.droidplanner.androidfor the release build,org.droidplanner.android.debugfor the dev build) with your signing certificate's SHA-1. - For a release build, add the release key's SHA-1 too — the debug and release certificates are different.
Map tiles are free to display; a billing account is only needed to activate the key.
- USB serial — a SiK telemetry radio (433 / 915 MHz) on a USB-OTG cable. Tested.
- Wi-Fi — UDP or TCP to a Wi-Fi telemetry bridge or to SITL.
- TCP and UDP — direct to any MAVLink endpoint.
Bluetooth telemetry adapters are not tested in this fork.
- Use a proper USB-OTG cable/adapter; not all phone-to-USB cables carry the OTG signalling.
- Accept the "Allow the app to access the USB device?" dialog when it pops up. If you dismissed it, unplug and replug.
- Some phones don't provide enough power for a bare radio module — use a radio with its own USB connector, or a powered hub.
- SiK radios enumerate as a USB-serial device; the bundled FTDI driver covers the common ones.
- If no permission dialog appears at all ("Connection failed: No Devices
found" with nothing else), Android isn't recognizing the device — Tower only
shows the dialog for USB vendor/product ids listed in
device_filter.xml. As of 4.0.0.6 that list includes ArduPilot's official vendor id (0x2DAE, any product id), which covers most modern Pixhawk-family boards. - If the permission dialog appears but nothing happens afterwards (no
error, device never shows up in the app), the dialog list isn't the problem —
the serial driver itself didn't recognize the device either, which is a
second, separate list. As of 4.0.0.7 that also accepts ArduPilot's
0x2DAEvendor id, plus its pid.codes allocation (0x1209, product ids0x5740/0x5741— covers some Pixhawk 2.4.8 clones). - Either way, if your board still isn't recognized,
open an issue with its USB
vendor/product id (check Windows Device Manager → the device's Properties →
Details → "Hardware Ids", e.g.
USB\VID_xxxx&PID_xxxx) and it can likely be added.
Use a TCP or UDP connection to the simulator's host and port
(from an Android emulator, the host machine is 10.0.2.2).
- On a marginal radio link, lower the SiK air data rate or move the antennas.
- Over Wi-Fi, a weak signal or a busy network will stall the stream.
- If it reproduces on a good link, open an issue with a TLog (see below).
Both. The link starts on MAVLink 1 and auto-switches to MAVLink 2 the first time the vehicle sends a v2 frame. Nothing to configure.
Received signed frames are accepted, but the signature is not verified. Outgoing frames are not signed. If your vehicle requires signed MAVLink, this fork won't connect.
Mission transfer reliability was improved (faster retry on lost packets, plus one automatic app-level re-try). On a genuinely bad link it can still fail — retry once the link is stable. If it fails consistently on a good link, open an issue with a TLog.
Third icon in the editor's trash tool. It erases the mission stored on the flight controller. Only enabled while a vehicle is connected.
The GUIDED follow-me was reworked (filtered position + velocity setpoints at 5 Hz), but it is only verified against a simulator so far — not flight-tested. The tuning constants may need adjusting on a real vehicle. Flight reports are very welcome.
"Dronie" only builds and uploads the mission. To fly it you still have to arm and switch to Auto yourself. If you press it without a GPS fix it now tells you instead of failing silently.
Gradle is running on the wrong Java. It needs JDK 17.
- Command line: set
JAVA_HOMEto a JDK 17 install. - IDE / Android Studio: set
org.gradle.java.home=/path/to/jdk-17in~/.gradle/gradle.properties, or point Gradle's JDK to 17 in the settings.
JDK 17, the Android SDK with a recent platform and build-tools, and a Google
Maps API key (above). Then ./gradlew :Android:assembleDevDebug.
Copy keystore.properties.example to keystore.properties, fill in your
keystore path and passwords, then ./gradlew :Android:assembleProdRelease.
Without keystore.properties the release build still works but is signed with
the debug key.
No. This is an ArduPilot GCS (ArduCopter, ArduPlane, Rover).
Follow-me and the dronie in flight, Bluetooth telemetry adapters, and the sensor-calibration screens (compass / accelerometer / radio / ESC). Parameter read/write and the rest of the connected flows are tested.
- GitHub Issues: https://github.com/nomar2/Tower/issues
- Include: phone model, Android version, flight-controller firmware and version, connection type (USB serial / Wi-Fi / TCP / UDP), and what you did.
- If it's a connection or mission problem, attach a TLog — the app records one per session; the built-in TLog viewer lists them and they're under the app's external files directory.
- For a crash, a
logcatcapture around the moment of the crash helps a lot.