Intent API
Other apps can start and stop Network Survey surveys by sending an Android intent to its survey service. A start request names the record types to record and the destinations to send them to, the same two choices you make on the Survey tab.
Turning it on or off
Section titled “Turning it on or off”Other apps can only do this while Settings > Fleet > Let other apps start and stop surveys is on. It is on by default. When it is off, start and stop requests are ignored.
On a managed phone, the organization can set this with the managed configuration key allow_intent_control. See Managed configuration (MDM).
Sending an intent
Section titled “Sending an intent”| Actions | com.craxiom.networksurvey.START_SURVEY and com.craxiom.networksurvey.STOP_SURVEY |
| Package | com.craxiom.networksurvey (both the Google Play and the CDR build) |
| Service | com.craxiom.networksurvey.services.NetworkSurveyService |
| Start with | Context.startForegroundService() |
Debug builds you compile yourself use the package com.craxiom.networksurvey.dev; the service class name stays the same.
START_SURVEY extras
Section titled “START_SURVEY extras”| Extra | Type | Meaning |
|---|---|---|
record_types | String array, or one comma-separated String | What to record: cellular, phone_state, wifi, bluetooth, gnss, cdr (Call records). Another app can’t start the NS Scout record types wifi_clients and wifi_raw; see NS Scout record types. |
destinations | String array, or one comma-separated String | Where to send it: log_files, ns_analytics, mqtt, grpc, community. |
mqtt_config_json | String (JSON) | A broker to use for MQTT. Adding it also adds mqtt to the destinations. See below. |
Values are not case sensitive, spaces around them are ignored, and unknown values are skipped.
Every destination in the request receives every record type in the request, with the same exceptions as on the Survey tab:
- Call records only go to Log files.
- The Community databases only take Cellular (OpenCelliD and BeaconDB) and Wi-Fi (BeaconDB), for the targets chosen in their upload settings.
- Phone state is added whenever Cellular is, while Include phone state with cellular is on (the default).
NS Scout record types
Section titled “NS Scout record types”Another app can’t start wifi_clients (Wi-Fi clients) or wifi_raw (Raw frames), the record types only an NS Scout records. They capture what nearby devices send, so turning them on is left to the person using the phone, on the Survey tab, and to their organization.
- A request that names them. They are left out and the rest of the request starts, so
wifiand the other record types still record. They are not listed as left out on the Survey tab or in the notification, the same as a type the organization turned off, and a later retry doesn’t add them. - A request that names only them. From Ready, nothing starts. This counts as naming record types, so MQTT doesn’t connect to send only device status messages.
- A survey that already records them. A request adds to the running survey and never removes anything, so what the person’s survey asked for keeps recording. A destination the request adds takes these types like any other record type in the survey: Wi-Fi clients go to Log files, MQTT and gRPC, and Raw frames only go to Log files.
- A managed phone. The organization can still turn them on. See Managed phones.
- The Wi-Fi source. A request can’t change the Wi-Fi source. It uses the one chosen on the phone, and
wificomes from that source too.
mqtt_config_json
Section titled “mqtt_config_json”{ "mqtt_host": "mqtt.example.net", "mqtt_port": 8883, "mqtt_tls": true, "mqtt_client": "field-phone-07", "mqtt_username": "survey", "mqtt_password": "your-password", "mqtt_topic_prefix": "my/custom/topic/", "mqtt_qos": 1, "device_status_stream_enabled": true}| Field | Type | If left out |
|---|---|---|
mqtt_host | string | Needed |
mqtt_client | string | Needed. The MQTT client ID |
mqtt_port | integer | 8883 (also used for a port outside 1 to 65535) |
mqtt_tls | boolean | true |
mqtt_username, mqtt_password | string | No login |
mqtt_topic_prefix | string | No prefix |
mqtt_qos | integer, 0 to 2 | 1 (also used for any other value) |
device_status_stream_enabled | boolean | false: no device status messages to this broker |
The broker from the JSON is used only if MQTT is not already streaming. A stream that is already running (the phone’s own broker, the organization’s, or an earlier request’s) is never moved to another app’s broker. The broker from the JSON is kept only as long as the stream it started.
If the JSON parses but its broker cannot be used, the rest of the request starts without MQTT, so records never go to a different broker. If it does not parse at all, it is ignored. With destinations including mqtt and no JSON, the broker selected on the phone (or the organization’s) is used.
Deprecated extras
Section titled “Deprecated extras”These extras from Network Survey 1.x still work but are deprecated; use record_types and destinations instead.
| Extra | Type | Now means |
|---|---|---|
cellular_file_logging, phone_state_file_logging, wifi_file_logging, bluetooth_file_logging, gnss_file_logging, cdr_file_logging | boolean | true adds that record type and Log files to the request |
In mqtt_config_json: cellular_stream_enabled, phone_state_stream_enabled, wifi_stream_enabled, bluetooth_stream_enabled, gnss_stream_enabled | boolean | true adds that record type to the whole request; false adds nothing (it does not remove a type named elsewhere) |
The boolean extras must be real booleans (for example --ez with adb); a string "true" is not read.
Because a survey is one set of record types for every destination, the old per-destination extras are combined. For example, cellular_file_logging=true plus a JSON with wifi_stream_enabled: true sends Cellular and Wi-Fi to both Log files and MQTT.
What a start request does
Section titled “What a start request does”- Nothing named at all. An intent with no record types and no destinations (no
record_types, nodestinations, no*_file_loggingset totrue, and nomqtt_config_json) does nothing. - From Ready. The request starts a new survey with what it names, with a new Mission ID. If it names record types but no destination, nothing starts (except destinations the organization keeps on). If it names destinations but no record types, nothing is sent, with one exception: MQTT still connects and sends device status messages (and watchlist events, when Stream over MQTT is on) if there is something to send.
- While a survey is recording. The request adds to the running survey and never removes anything: the result is what the running survey asked for plus what the intent asks for, and the Mission ID stays the same. NS Analytics never receives a record type it was not already receiving (or, if the request is what adds NS Analytics, only the types the request names), because every record counts toward the workspace’s plan.
- No screen, no prompts. A request from another app shows no permission prompts or settings. Anything that cannot run (a permission missing, a radio off, a destination not set up, NS Analytics not connected) is left out, and the Survey tab and the survey notification list what was left out.
- No reply. The app does not send a result back to the calling app.
STOP_SURVEY
Section titled “STOP_SURVEY”STOP_SURVEY stops the whole survey, whoever started it: Log files, NS Analytics, MQTT, gRPC, and the Community databases. It takes no extras.
On a phone whose organization shapes the survey, a stop from another app counts like the person tapping Stop survey: opening the app does not start the survey again until the phone restarts or the organization pushes a new configuration.
Managed phones
Section titled “Managed phones”- Record types and destinations the organization set to
offare removed from any request. - Ones it set to
onare added even if the request did not name them. For example, a request for Log files on a phone where the organization keeps MQTT on also streams to MQTT. survey_wifi_clientsorsurvey_wifi_rawset toonis the one way a survey another app starts records these types, because that is the organization’s choice and not the app’s. They still need a paired Scout as the Wi-Fi source, and Raw frames need Log files in the survey. Set touser, or absent, they stay out of any request. With Override organization settings on, the organization’sondoesn’t apply, so a request can’t start them.- If the organization keeps MQTT off, a broker in
mqtt_config_jsonis ignored. - Requests cannot use NS Analytics or the community databases when the organization blocks them (
allow_ns_analyticsset tofalse, orallow_external_data_uploadnot set totrue).
Examples with adb
Section titled “Examples with adb”These commands are handy for testing from a computer. Start recording Cellular, Phone state, and Wi-Fi to Log files:
adb shell am start-foreground-service \ -n com.craxiom.networksurvey/.services.NetworkSurveyService \ -a com.craxiom.networksurvey.START_SURVEY \ --esa record_types cellular,phone_state,wifi \ --esa destinations log_filesStart recording Cellular and Wi-Fi to Log files and to a broker:
adb shell "am start-foreground-service \ -n com.craxiom.networksurvey/.services.NetworkSurveyService \ -a com.craxiom.networksurvey.START_SURVEY \ --esa record_types cellular,wifi \ --esa destinations log_files \ --es mqtt_config_json '{\"mqtt_host\":\"mqtt.example.net\",\"mqtt_port\":8883,\"mqtt_tls\":true,\"mqtt_client\":\"field-phone-07\"}'"Stop the survey:
adb shell am start-foreground-service \ -n com.craxiom.networksurvey/.services.NetworkSurveyService \ -a com.craxiom.networksurvey.STOP_SURVEYExample in Kotlin
Section titled “Example in Kotlin”val intent = Intent("com.craxiom.networksurvey.START_SURVEY").apply { component = ComponentName( "com.craxiom.networksurvey", "com.craxiom.networksurvey.services.NetworkSurveyService", ) putExtra("record_types", arrayOf("cellular", "wifi")) putExtra("destinations", arrayOf("log_files", "mqtt")) putExtra( "mqtt_config_json", """{"mqtt_host":"mqtt.example.net","mqtt_port":8883,"mqtt_tls":true,"mqtt_client":"field-phone-07"}""", )}context.startForegroundService(intent)To stop, send an intent with the STOP_SURVEY action and the same component.