refactor: Centralize Meshtastic intent constants

This commit centralizes all Android Intent constants into a new `MeshtasticIntent` object within the `core/api` module.

This refactoring makes the constants accessible to external applications and removes the duplicated definitions from the main application. The app and the service example have been updated to use these new centralized constants.

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich
2026-02-07 15:45:11 -06:00
parent 75143ba07c
commit 34b0755192
5 changed files with 118 additions and 37 deletions

View File

@@ -16,22 +16,24 @@
*/
package com.geeksville.mesh.service
import org.meshtastic.core.api.MeshtasticIntent
const val PREFIX = "com.geeksville.mesh"
const val ACTION_NODE_CHANGE = "$PREFIX.NODE_CHANGE"
const val ACTION_MESH_CONNECTED = "$PREFIX.MESH_CONNECTED"
const val ACTION_MESH_DISCONNECTED = "$PREFIX.MESH_DISCONNECTED"
const val ACTION_CONNECTION_CHANGED = "$PREFIX.CONNECTION_CHANGED"
const val ACTION_MESSAGE_STATUS = "$PREFIX.MESSAGE_STATUS"
const val ACTION_NODE_CHANGE = MeshtasticIntent.ACTION_NODE_CHANGE
const val ACTION_MESH_CONNECTED = MeshtasticIntent.ACTION_MESH_CONNECTED
const val ACTION_MESH_DISCONNECTED = MeshtasticIntent.ACTION_MESH_DISCONNECTED
const val ACTION_CONNECTION_CHANGED = MeshtasticIntent.ACTION_CONNECTION_CHANGED
const val ACTION_MESSAGE_STATUS = MeshtasticIntent.ACTION_MESSAGE_STATUS
const val ACTION_RECEIVED_TEXT_MESSAGE_APP = "$PREFIX.RECEIVED.TEXT_MESSAGE_APP"
const val ACTION_RECEIVED_POSITION_APP = "$PREFIX.RECEIVED.POSITION_APP"
const val ACTION_RECEIVED_NODEINFO_APP = "$PREFIX.RECEIVED.NODEINFO_APP"
const val ACTION_RECEIVED_TELEMETRY_APP = "$PREFIX.RECEIVED.TELEMETRY_APP"
const val ACTION_RECEIVED_ATAK_PLUGIN = "$PREFIX.RECEIVED.ATAK_PLUGIN"
const val ACTION_RECEIVED_ATAK_FORWARDER = "$PREFIX.RECEIVED.ATAK_FORWARDER"
const val ACTION_RECEIVED_DETECTION_SENSOR_APP = "$PREFIX.RECEIVED.DETECTION_SENSOR_APP"
const val ACTION_RECEIVED_PRIVATE_APP = "$PREFIX.RECEIVED.PRIVATE_APP"
const val ACTION_RECEIVED_TEXT_MESSAGE_APP = MeshtasticIntent.ACTION_RECEIVED_TEXT_MESSAGE_APP
const val ACTION_RECEIVED_POSITION_APP = MeshtasticIntent.ACTION_RECEIVED_POSITION_APP
const val ACTION_RECEIVED_NODEINFO_APP = MeshtasticIntent.ACTION_RECEIVED_NODEINFO_APP
const val ACTION_RECEIVED_TELEMETRY_APP = MeshtasticIntent.ACTION_RECEIVED_TELEMETRY_APP
const val ACTION_RECEIVED_ATAK_PLUGIN = MeshtasticIntent.ACTION_RECEIVED_ATAK_PLUGIN
const val ACTION_RECEIVED_ATAK_FORWARDER = MeshtasticIntent.ACTION_RECEIVED_ATAK_FORWARDER
const val ACTION_RECEIVED_DETECTION_SENSOR_APP = MeshtasticIntent.ACTION_RECEIVED_DETECTION_SENSOR_APP
const val ACTION_RECEIVED_PRIVATE_APP = MeshtasticIntent.ACTION_RECEIVED_PRIVATE_APP
fun actionReceived(portNum: String) = "$PREFIX.RECEIVED.$portNum"
@@ -39,14 +41,11 @@ fun actionReceived(portNum: String) = "$PREFIX.RECEIVED.$portNum"
// standard EXTRA bundle definitions
//
// a bool true means now connected, false means not
const val EXTRA_CONNECTED = "$PREFIX.Connected"
const val EXTRA_CONNECTED = MeshtasticIntent.EXTRA_CONNECTED
const val EXTRA_PROGRESS = "$PREFIX.Progress"
// / a bool true means we expect this condition to continue until, false means device might come back
const val EXTRA_PERMANENT = "$PREFIX.Permanent"
const val EXTRA_PAYLOAD = "$PREFIX.Payload"
const val EXTRA_NODEINFO = "$PREFIX.NodeInfo"
const val EXTRA_PACKET_ID = "$PREFIX.PacketId"
const val EXTRA_STATUS = "$PREFIX.Status"
const val EXTRA_PAYLOAD = MeshtasticIntent.EXTRA_PAYLOAD
const val EXTRA_NODEINFO = MeshtasticIntent.EXTRA_NODEINFO
const val EXTRA_PACKET_ID = MeshtasticIntent.EXTRA_PACKET_ID
const val EXTRA_STATUS = MeshtasticIntent.EXTRA_STATUS

View File

@@ -137,7 +137,9 @@ constructor(
PortNum.POSITION_APP -> handlePosition(packet, dataPacket, myNodeNum)
PortNum.NODEINFO_APP -> if (!fromUs) handleNodeInfo(packet)
PortNum.TELEMETRY_APP -> handleTelemetry(packet, dataPacket, myNodeNum)
else -> shouldBroadcast = handleSpecializedDataPacket(packet, dataPacket, myNodeNum, logUuid, logInsertJob)
else ->
shouldBroadcast =
handleSpecializedDataPacket(packet, dataPacket, myNodeNum, fromUs, logUuid, logInsertJob)
}
return shouldBroadcast
}
@@ -146,14 +148,16 @@ constructor(
packet: MeshPacket,
dataPacket: DataPacket,
myNodeNum: Int,
fromUs: Boolean,
logUuid: String?,
logInsertJob: Job?,
): Boolean {
var shouldBroadcast = false
var shouldBroadcast = !fromUs
val decoded = packet.decoded ?: return shouldBroadcast
when (decoded.portnum) {
PortNum.TRACEROUTE_APP -> {
tracerouteHandler.handleTraceroute(packet, logUuid, logInsertJob)
shouldBroadcast = false
}
PortNum.ROUTING_APP -> {
handleRouting(packet, dataPacket)

View File

@@ -113,7 +113,7 @@ constructor(
* NODE_CHANGE for new IDs appearing or disappearing
* ACTION_MESH_CONNECTED for losing/gaining connection to the packet radio
* Note: this is not the same as RadioInterfaceService.RADIO_CONNECTED_ACTION,
* because it implies we have assembled a warehouse valid node db.
* because it implies we have assembled a valid node db.
*/
private fun explicitBroadcast(intent: Intent) {
context.sendBroadcast(

View File

@@ -0,0 +1,77 @@
/*
* Copyright (c) 2025-2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.core.api
import org.meshtastic.core.api.MeshtasticIntent.EXTRA_CONNECTED
import org.meshtastic.core.api.MeshtasticIntent.EXTRA_NODEINFO
import org.meshtastic.core.api.MeshtasticIntent.EXTRA_PACKET_ID
import org.meshtastic.core.api.MeshtasticIntent.EXTRA_STATUS
/**
* Constants for Meshtastic Android Intents. These are used by external applications to communicate with the Meshtastic
* service.
*/
object MeshtasticIntent {
private const val PREFIX = "com.geeksville.mesh"
/** Broadcast when a node's information changes. Extra: [EXTRA_NODEINFO] */
const val ACTION_NODE_CHANGE = "$PREFIX.NODE_CHANGE"
/** Broadcast when the mesh radio connects. Extra: [EXTRA_CONNECTED] */
const val ACTION_MESH_CONNECTED = "$PREFIX.MESH_CONNECTED"
/** Broadcast when the mesh radio disconnects. */
const val ACTION_MESH_DISCONNECTED = "$PREFIX.MESH_DISCONNECTED"
/** Legacy broadcast for connection changes. Extra: [EXTRA_CONNECTED] */
const val ACTION_CONNECTION_CHANGED = "$PREFIX.CONNECTION_CHANGED"
/** Broadcast for message status updates. Extras: [EXTRA_PACKET_ID], [EXTRA_STATUS] */
const val ACTION_MESSAGE_STATUS = "$PREFIX.MESSAGE_STATUS"
/** Received a text message. */
const val ACTION_RECEIVED_TEXT_MESSAGE_APP = "$PREFIX.RECEIVED.TEXT_MESSAGE_APP"
/** Received a position update. */
const val ACTION_RECEIVED_POSITION_APP = "$PREFIX.RECEIVED.POSITION_APP"
/** Received node info. */
const val ACTION_RECEIVED_NODEINFO_APP = "$PREFIX.RECEIVED.NODEINFO_APP"
/** Received telemetry data. */
const val ACTION_RECEIVED_TELEMETRY_APP = "$PREFIX.RECEIVED.TELEMETRY_APP"
/** Received ATAK Plugin data. */
const val ACTION_RECEIVED_ATAK_PLUGIN = "$PREFIX.RECEIVED.ATAK_PLUGIN"
/** Received ATAK Forwarder data. */
const val ACTION_RECEIVED_ATAK_FORWARDER = "$PREFIX.RECEIVED.ATAK_FORWARDER"
/** Received detection sensor data. */
const val ACTION_RECEIVED_DETECTION_SENSOR_APP = "$PREFIX.RECEIVED.DETECTION_SENSOR_APP"
/** Received private app data. */
const val ACTION_RECEIVED_PRIVATE_APP = "$PREFIX.RECEIVED.PRIVATE_APP"
// standard EXTRA bundle definitions
const val EXTRA_CONNECTED = "$PREFIX.Connected"
const val EXTRA_PAYLOAD = "$PREFIX.Payload"
const val EXTRA_NODEINFO = "$PREFIX.NodeInfo"
const val EXTRA_PACKET_ID = "$PREFIX.PacketId"
const val EXTRA_STATUS = "$PREFIX.Status"
}

View File

@@ -39,6 +39,7 @@ import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import org.meshtastic.core.api.MeshtasticIntent
import org.meshtastic.core.service.IMeshService
private const val TAG: String = "MeshServiceExample"
@@ -83,19 +84,19 @@ class MainActivity : ComponentActivity() {
val intentFilter =
IntentFilter().apply {
addAction("com.geeksville.mesh.NODE_CHANGE")
addAction("com.geeksville.mesh.CONNECTION_CHANGED")
addAction("com.geeksville.mesh.MESH_CONNECTED")
addAction("com.geeksville.mesh.MESH_DISCONNECTED")
addAction("com.geeksville.mesh.MESSAGE_STATUS")
addAction("com.geeksville.mesh.RECEIVED.TEXT_MESSAGE_APP")
addAction("com.geeksville.mesh.RECEIVED.POSITION_APP")
addAction("com.geeksville.mesh.RECEIVED.TELEMETRY_APP")
addAction("com.geeksville.mesh.RECEIVED.NODEINFO_APP")
addAction("com.geeksville.mesh.RECEIVED.ATAK_PLUGIN")
addAction("com.geeksville.mesh.RECEIVED.ATAK_FORWARDER")
addAction("com.geeksville.mesh.RECEIVED.DETECTION_SENSOR_APP")
addAction("com.geeksville.mesh.RECEIVED.PRIVATE_APP")
addAction(MeshtasticIntent.ACTION_NODE_CHANGE)
addAction(MeshtasticIntent.ACTION_CONNECTION_CHANGED)
addAction(MeshtasticIntent.ACTION_MESH_CONNECTED)
addAction(MeshtasticIntent.ACTION_MESH_DISCONNECTED)
addAction(MeshtasticIntent.ACTION_MESSAGE_STATUS)
addAction(MeshtasticIntent.ACTION_RECEIVED_TEXT_MESSAGE_APP)
addAction(MeshtasticIntent.ACTION_RECEIVED_POSITION_APP)
addAction(MeshtasticIntent.ACTION_RECEIVED_TELEMETRY_APP)
addAction(MeshtasticIntent.ACTION_RECEIVED_NODEINFO_APP)
addAction(MeshtasticIntent.ACTION_RECEIVED_ATAK_PLUGIN)
addAction(MeshtasticIntent.ACTION_RECEIVED_ATAK_FORWARDER)
addAction(MeshtasticIntent.ACTION_RECEIVED_DETECTION_SENSOR_APP)
addAction(MeshtasticIntent.ACTION_RECEIVED_PRIVATE_APP)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {