# APRSdroid Inter-App API This document describes how Android applications can interact with [APRSdroid](https://aprsdroid.org/). If you are an app developer aiming to do interesting things with APRS, this is for you. ## Features APRSdroid exposes the following data via broadcast Intents ("events"): * `SERVICE_STARTED` - APRSdroid's tracking service was launched * `SERVICE_STOPPED` - APRSdroid's tracking service was terminated * `POSITION` - an incoming/outgoing position packet (user, object or item) * `MESSAGE` - text messages received by APRSdroid * `MESSAGETX` - text messages sent by APRSdroid * `UPDATE` - any text added to APRSdroid's log, including raw packets Furthermore, it is possible to influence APRSdroid with the following Intents ("actions"): * `SERVICE` - start APRSdroid's tracking service * `ONCE` - send one position packet and stop * `SERVICE_STOP` - stop APRSdroid's tracking service * `SEND_PACKET` - send a (raw) APRS packet * `FREQUENCY` - change the frequency announced in position packets (requires APRSdroid 1.4.1) All uppercase strings mentioned in this document are suffixes to `"org.aprsdroid.app."` and need to be concatenated for the effective Intent action names. If you want to write a third-party app that is using APRSdroid's service, the recommended way is to make a service that listens to APRSdroid's `SERVICE_STARTED` event, launches its own service with the according configuration, sends and receives packets within that service, and terminates when a `SERVICE_STOPPED` event is received. That way, all installed third party applications can be launched automatically together with APRSdroid. You can use your own application's main activity to configure (and optionally disable) your add-on. ## Events - Getting Data from APRSdroid APRSdroid will inform applications using a broadcast Intent about all relevant status changes. You need to register a [BroadcastReceiver](https://developer.android.com/reference/android/content/BroadcastReceiver.html) that will process APRSdroid's events, either in your app's manifest or using the registerReceiver code. Example code to listen for broadcasts: public class APRSdroidEventReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (!intent.getAction().startsWith("org.aprsdroid.app")) return; String a = intent.getAction().replace("org.aprsdroid.app.", ""); switch (a) { case "SERVICE_STARTED": aprsdroid_running = true; break; case "SERVICE_STOPPED": aprsdroid_running = false; break; case "MESSAGE": String source = intent.getStringExtra("source"); String message = intent.getStringExtra("body"); Log.d("APRS Event", "message from " + source + ": " + body); break; case "POSITION": String callsign = intent.getStringExtra("callsign"); Location location = intent.getParcelableExtra("location"); Log.d("APRS Event", callsign + " position: " + location); break; } } } ### SERVICE_STARTED This event will be triggered whenever APRSdroid's service is started and successfully connects to the backend. After this event, it should be safe to send out packets. Please note that packet delivery can not be guaranteed despite all efforts. Intent extras: * `"api_version"` (int): the API version code implemented by the installed version of APRSdroid. This document corresponds to API version `1`, changes / additions will lead to higher version numbers. * `"callsign"` (String): callsign and SSID of the APRSdroid user, in the format "N0CALL-5" or "N0CALL" (if no SSID was configured). ### SERVICE_STOPPED This event will be triggered when APRSdroid's service terminates. It is not guaranteed to be called (i.e. when the app is force-closed, the event will not be triggered). ### UPDATE The `UPDATE` event comes with the following extras: * `"type"` (int): the type of the log entry. Possible values: * 0: sent packet (generated by APRSdroid) * 1: info (APRSdroid's internal information message) * 2: error (something went wrong) * 3: incoming packet (received from APRS) * `"status"` (String): the text that was added to the log. For type 0 and 3 this is the full raw packet content, header and data. ### MESSAGE / MESSAGETX When the user sends a message or when a new message is received, the `MESSAGETX` / `MESSAGE` events are fired. They are not fired for retransmissions of outgoing messages, and neither for incoming ACKs / REJs. Both event types have the following extras: * `"source"` (String): callsign of the sender (your own one for `MESSAGETX`) * `"dest"` (String): callsign of the receiver (might have a different SSID on incoming messages to your callsign) * `"body"` (String): content of the message ### POSITION A `POSITION` event is triggered every time when a position packet is decoded (station, item or object) or transmitted. It contains the following extras: * `"source"` (String): callsign that sent this packet. * `"callsign"` (String): callsign for which the position event was sent (this is the object/item name for objects/items, and equals to `"source"` for regular position packets). * `"location"` ([Location](https://developer.android.com/reference/android/location/Location.html)): the geo-coordinates of the position. This extra will have latitude, longitude, and time set. The accuracy fields is an approximation according to the original APRS position ambiguity. Bearing and speed will be set if they were present in the original packet. * `"packet"` (String): the raw packet that was parsed into this position report. ## Actions - Influencing APRSdroid ### Generic Intent Construction To influence APRSdroid, you need to create an Intent with a string action starting with `"org.aprsdroid.app."`, followed by the uppercase action name. The intent should have additional parameters according to the action description, and must be delivered using [startService](https://developer.android.com/reference/android/content/Context.html#startService(android.content.Intent)). The individual actions are described in the following. ### SERVICE / ONCE Start the APRSdroid tracking service for an indeterminate runtime (`SERVICE`) or for one position transmission (`ONCE`). // launch APRSdroid tracker Intent i = new Intent("org.aprsdroid.app.SERVICE").setPackage("org.aprsdroid.app"); startService(i); ### SERVICE_STOP Stop the tracking service. // stop APRSdroid tracker Intent i = new Intent("org.aprsdroid.app.SERVICE_STOP").setPackage("org.aprsdroid.app"); startService(i); ### SEND_PACKET Send a raw APRS packet via the (already running) APRSdroid service. Only the packet payload needs to be configured, APRSdroid will automatically complete the header (your callsign and the ARPS path) from its configuration. Intent extras (do not use `setData()`, it doesn't work!): * `data` (String): raw packet payload Example for sending a raw status packet: // send raw status packet Intent i = new Intent("org.aprsdroid.app.SEND_PACKET").setPackage("org.aprsdroid.app"); i.putExtra("data", ">third-party APRS status app"); startService(i); ### FREQUENCY (APRSdroid 1.4.1) Update the [frequency field](http://www.aprs.org/info/freqspec.txt) in the position reports sent by APRSdroid. If the APRSdroid service is running, this will immediately generate a position packet with the new frequency. Intent extras: * `frequency` (String): the new frequency value, e.g. "438.750MHz", "145.500" or "" to disable, decimal separator must be a dot (".") Example for updating the frequency: // send raw status packet Intent i = new Intent("org.aprsdroid.app.FREQUENCY").setPackage("org.aprsdroid.app"); i.putExtra("frequency", "438.750"); startService(i); Invocation from the adb shell: am startservice -a org.aprsdroid.app.FREQUENCY -e frequency "438.750" ## (In-)Security Currently, APRSdroid exposes the following personal information via global broadcast to all applications: * Your location and the location of your peers * Your callsign and callsigns from all nearby stations * The content of APRS messages sent and received * Any other data sent and received by APRSdroid * The times when APRSdroid is active and in which configuration As APRS (and ham radio in general) is considered public information, access to this data is not limited in any way. **A future version of APRSdroid might require third-party apps to have the "Access Fine Location" permission.** ----- APRSdroid can be influenced by third-party applications, in that they can start the service, stop it, and send unlimited amounts of data packets (over the air) in your name. **A future version of APRSdroid will display an API key in its preferences, which must be entered into third-party apps and supplied in the Intents sent to APRSdroid.**