Skip to content

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.

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).

Actionscom.craxiom.networksurvey.START_SURVEY and com.craxiom.networksurvey.STOP_SURVEY
Packagecom.craxiom.networksurvey (both the Google Play and the CDR build)
Servicecom.craxiom.networksurvey.services.NetworkSurveyService
Start withContext.startForegroundService()

Debug builds you compile yourself use the package com.craxiom.networksurvey.dev; the service class name stays the same.

ExtraTypeMeaning
record_typesString array, or one comma-separated StringWhat 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.
destinationsString array, or one comma-separated StringWhere to send it: log_files, ns_analytics, mqtt, grpc, community.
mqtt_config_jsonString (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).

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 wifi and 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 wifi comes from that source too.
{
"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
}
FieldTypeIf left out
mqtt_hoststringNeeded
mqtt_clientstringNeeded. The MQTT client ID
mqtt_portinteger8883 (also used for a port outside 1 to 65535)
mqtt_tlsbooleantrue
mqtt_username, mqtt_passwordstringNo login
mqtt_topic_prefixstringNo prefix
mqtt_qosinteger, 0 to 21 (also used for any other value)
device_status_stream_enabledbooleanfalse: 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.

These extras from Network Survey 1.x still work but are deprecated; use record_types and destinations instead.

ExtraTypeNow means
cellular_file_logging, phone_state_file_logging, wifi_file_logging, bluetooth_file_logging, gnss_file_logging, cdr_file_loggingbooleantrue 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_enabledbooleantrue 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.

  • Nothing named at all. An intent with no record types and no destinations (no record_types, no destinations, no *_file_logging set to true, and no mqtt_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 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.

  • Record types and destinations the organization set to off are removed from any request.
  • Ones it set to on are 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_clients or survey_wifi_raw set to on is 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 to user, or absent, they stay out of any request. With Override organization settings on, the organization’s on doesn’t apply, so a request can’t start them.
  • If the organization keeps MQTT off, a broker in mqtt_config_json is ignored.
  • Requests cannot use NS Analytics or the community databases when the organization blocks them (allow_ns_analytics set to false, or allow_external_data_upload not set to true).

These commands are handy for testing from a computer. Start recording Cellular, Phone state, and Wi-Fi to Log files:

Terminal window
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_files

Start recording Cellular and Wi-Fi to Log files and to a broker:

Terminal window
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:

Terminal window
adb shell am start-foreground-service \
-n com.craxiom.networksurvey/.services.NetworkSurveyService \
-a com.craxiom.networksurvey.STOP_SURVEY
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.