diff --git a/core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshServiceNotificationsImpl.kt b/core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshServiceNotificationsImpl.kt index bc982fa25..37764047f 100644 --- a/core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshServiceNotificationsImpl.kt +++ b/core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshServiceNotificationsImpl.kt @@ -920,7 +920,10 @@ class MeshServiceNotificationsImpl( PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE, ) - return NotificationCompat.Action.Builder(android.R.drawable.ic_menu_add, label, pendingIntent).build() + return NotificationCompat.Action.Builder(android.R.drawable.ic_menu_add, label, pendingIntent) + .setSemanticAction(NotificationCompat.Action.SEMANTIC_ACTION_NONE) + .setShowsUserInterface(false) + .build() } private fun commonBuilder( diff --git a/feature/auto/build.gradle.kts b/feature/auto/build.gradle.kts index 54a33c302..692285118 100644 --- a/feature/auto/build.gradle.kts +++ b/feature/auto/build.gradle.kts @@ -23,10 +23,6 @@ plugins { android { namespace = "org.meshtastic.feature.auto" resourcePrefix = "auto_" - - // Car App Library requires API 23+; bump above the app's default minSdk - // so we can use conversation shortcuts and LocusId APIs cleanly. - defaultConfig { minSdk = 23 } } dependencies { diff --git a/feature/auto/src/main/AndroidManifest.xml b/feature/auto/src/main/AndroidManifest.xml index 8cf24a494..e9fbb05ec 100644 --- a/feature/auto/src/main/AndroidManifest.xml +++ b/feature/auto/src/main/AndroidManifest.xml @@ -17,16 +17,12 @@ --> - + - - - + android:exported="true" + android:permission="androidx.car.app.CarAppService"> diff --git a/feature/auto/src/main/kotlin/org/meshtastic/feature/auto/CarScreenDataBuilder.kt b/feature/auto/src/main/kotlin/org/meshtastic/feature/auto/CarScreenDataBuilder.kt index fa6a883ae..49e701ff0 100644 --- a/feature/auto/src/main/kotlin/org/meshtastic/feature/auto/CarScreenDataBuilder.kt +++ b/feature/auto/src/main/kotlin/org/meshtastic/feature/auto/CarScreenDataBuilder.kt @@ -55,12 +55,18 @@ internal object CarScreenDataBuilder { * * @param resolveUser Returns the [User] for a given node-ID string. The caller is responsible * for providing a null-safe fallback (typically [NodeRepository.getUser]). + * @param channelLabel Produces the display name for a channel given its index. + * Defaults to `"Channel N"`; callers can supply a localised string. + * @param unknownLabel Fallback display name when neither long name nor short name is available. + * Defaults to `"Unknown"`; callers can supply a localised string. */ fun buildCarContacts( merged: Map, myId: String?, channelSet: ChannelSet, resolveUser: (String) -> User, + channelLabel: (Int) -> String = { "Channel $it" }, + unknownLabel: String = "Unknown", ): List { val all = merged.map { (contactKey, packet) -> val fromLocal = packet.from == DataPacket.ID_LOCAL || packet.from == myId @@ -72,11 +78,11 @@ internal object CarScreenDataBuilder { val displayName = if (toBroadcast) { channelSet.getChannel(packet.channel)?.name?.takeIf { it.isNotEmpty() } - ?: "Channel ${packet.channel}" + ?: channelLabel(packet.channel) } else { // userId can be null for malformed packets (e.g. both `from` and `to` are null). // Fall back to a broadcast lookup which returns an "Unknown" user rather than crashing. - user.long_name.ifEmpty { user.short_name }.ifEmpty { "Unknown" } + user.long_name.ifEmpty { user.short_name }.ifEmpty { unknownLabel } } // Mirror ContactsViewModel: prefix received DM text with the sender's short name, @@ -125,21 +131,31 @@ internal object CarScreenDataBuilder { * - `"Offline ·