feat(notifications): add branded monochrome icon and color to all notifications
Build & Deploy PluriWave / Análisis de código (push) Successful in 36s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m28s

Replace generic system icons (info bubble, stock alarm clock) with a
custom equalizer-bars vector drawable across all 4 notification
builders: pre-notice, snooze countdown, ringing alarm, and the audio
player. Apply the app's cyan brand color to the 3 alarm notifications
that previously had none. Audio notification now explicitly declares
its icon instead of falling back to the full-color launcher icon,
which Android was auto-silhouetting into an illegible status-bar
blob.
This commit is contained in:
2026-07-02 18:53:33 +02:00
parent c78af4b1e8
commit 8f2bf2bdd6
7 changed files with 39 additions and 3 deletions
@@ -577,7 +577,8 @@ class AlarmScheduler(private val context: Context) {
)
val notification = NotificationCompat.Builder(appContext, PluriWaveAlarmReceiver.CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
.setSmallIcon(R.drawable.ic_stat_pluriwave)
.setColor(NotificationBrand.CYAN)
.setContentTitle(spec.title)
.setContentText(text)
.setPriority(NotificationCompat.PRIORITY_LOW)
@@ -0,0 +1,14 @@
package es.freetimelab.pluriwave
import androidx.annotation.ColorInt
/**
* Shared brand color for native notification icons.
*
* Single source of truth for the cyan tint applied via `NotificationCompat.Builder.setColor()`
* across all PluriWave alarm and audio notifications, mirroring the [AlarmNotificationStrings]
* shared-constants precedent.
*/
object NotificationBrand {
@ColorInt const val CYAN: Int = 0xFF21D4D9.toInt()
}
@@ -181,7 +181,8 @@ class PluriWaveAlarmReceiver : BroadcastReceiver() {
)
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_dialog_info)
.setSmallIcon(R.drawable.ic_stat_pluriwave)
.setColor(NotificationBrand.CYAN)
.setContentTitle(title)
.setContentText(contentText)
.setPriority(NotificationCompat.PRIORITY_LOW)
@@ -387,7 +387,8 @@ class PluriWaveAlarmService : Service() {
snoozeMinutes: Int
) =
NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(android.R.drawable.ic_lock_idle_alarm)
.setSmallIcon(R.drawable.ic_stat_pluriwave)
.setColor(NotificationBrand.CYAN)
.setContentTitle(AlarmNotificationStrings.ringTitle(this))
.setContentText(
if (stationName.isNullOrBlank()) title else "$title - $stationName"
@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:fillColor="#FFFFFF" android:pathData="M7,18h2L9,6L7,6v12zM3,14h2v-4L3,10v4zM11,20h2L13,4h-2v16zM19,10v4h2v-4h-2zM15,18h2L17,6h-2v12z" />
</vector>
+5
View File
@@ -12,6 +12,10 @@ import 'tema/pluriwave_tokens.dart';
const _anchoMinimoLandscape = 600.0;
/// Branded monochrome status-bar icon, replacing the default full-color
/// launcher silhouette fallback.
const androidNotificationIconResource = 'drawable/ic_stat_pluriwave';
/// S5-R8: media notification accent uses the brand color, not the M3
/// default purple. Top-level const so tests can assert it.
const configuracionAudioService = AudioServiceConfig(
@@ -20,6 +24,7 @@ const configuracionAudioService = AudioServiceConfig(
androidNotificationOngoing: true,
androidStopForegroundOnPause: true,
notificationColor: PluriWaveTokens.brand,
androidNotificationIcon: androidNotificationIconResource,
);
Future<void> main() async {
+11
View File
@@ -13,4 +13,15 @@ void main() {
isNot(const Color(0xFF6750A4)),
);
});
test('AudioServiceConfig usa el icono monocromo de marca', () {
expect(
configuracionAudioService.androidNotificationIcon,
'drawable/ic_stat_pluriwave',
);
expect(
configuracionAudioService.androidNotificationIcon,
isNot('mipmap/ic_launcher'),
);
});
}