AlarmClockReceiver: populate spec so notifications render on Xiaomi

Previously sourceAppId, title, and body were left null and sourceName
was the literal "ALARMCLOCKRECEIVER", causing Xiaomi watches to drop
the alarm-fire notification (the watch falls back to Gadgetbridge's own
package id which is not on the app allowlist, and the spec has nothing
to display).

Plumb the captured clock-app package (com.android.deskclock or
com.google.android.deskclock) through sendAlarm so:
- sourceAppId carries the real clock package
- sourceName is the resolved application label (NotificationUtils.getApplicationLabel)
- title = "Alarm" (R.string.menuitem_alarm)
- body = current time formatted via DateFormat

Strict improvement for all device families; Huami/ZeppOs previously
also displayed the alarm with empty title/body.
This commit is contained in:
Dany Mestas
2026-05-15 13:48:35 +02:00
committed by José Rebelo
parent a16b90f6aa
commit e0820f106f
@@ -20,16 +20,19 @@ package nodomain.freeyourgadget.gadgetbridge.externalevents;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.format.DateFormat;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec;
import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType;
import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils;
public class AlarmClockReceiver extends BroadcastReceiver { public class AlarmClockReceiver extends BroadcastReceiver {
private static final Logger LOG = LoggerFactory.getLogger(AlarmClockReceiver.class); private static final Logger LOG = LoggerFactory.getLogger(AlarmClockReceiver.class);
@@ -92,20 +95,24 @@ public class AlarmClockReceiver extends BroadcastReceiver {
} }
if (ALARM_ALERT_ACTION.equals(action) || GOOGLE_CLOCK_ALARM_ALERT_ACTION.equals(action)) { if (ALARM_ALERT_ACTION.equals(action) || GOOGLE_CLOCK_ALARM_ALERT_ACTION.equals(action)) {
sendAlarm(context, true); sendAlarm(context, true, packageName);
} else if (ALARM_DONE_ACTION.equals(action) || GOOGLE_CLOCK_ALARM_DONE_ACTION.equals(action)) { } else if (ALARM_DONE_ACTION.equals(action) || GOOGLE_CLOCK_ALARM_DONE_ACTION.equals(action)) {
sendAlarm(context, false); sendAlarm(context, false, packageName);
} }
} }
private synchronized void sendAlarm(Context context, boolean on) { private synchronized void sendAlarm(Context context, boolean on, String packageName) {
dismissLastAlarm(); dismissLastAlarm();
if (on) { if (on) {
NotificationSpec notificationSpec = new NotificationSpec(); NotificationSpec notificationSpec = new NotificationSpec();
//TODO: can we attach a dismiss action to the notification and not use the notification ID explicitly? //TODO: can we attach a dismiss action to the notification and not use the notification ID explicitly?
lastId = notificationSpec.getId(); lastId = notificationSpec.getId();
notificationSpec.type = NotificationType.GENERIC_ALARM_CLOCK; notificationSpec.type = NotificationType.GENERIC_ALARM_CLOCK;
notificationSpec.sourceName = "ALARMCLOCKRECEIVER"; notificationSpec.sourceAppId = packageName;
final String appLabel = NotificationUtils.getApplicationLabel(context, packageName);
notificationSpec.sourceName = appLabel != null ? appLabel : "Alarm Clock";
notificationSpec.title = context.getString(R.string.menuitem_alarm);
notificationSpec.body = DateFormat.getTimeFormat(context).format(new Date());
notificationSpec.attachedActions = new ArrayList<>(); notificationSpec.attachedActions = new ArrayList<>();
// DISMISS ALL action // DISMISS ALL action
@@ -114,7 +121,6 @@ public class AlarmClockReceiver extends BroadcastReceiver {
dismissAllAction.type = NotificationSpec.Action.TYPE_SYNTECTIC_DISMISS_ALL; dismissAllAction.type = NotificationSpec.Action.TYPE_SYNTECTIC_DISMISS_ALL;
notificationSpec.attachedActions.add(dismissAllAction); notificationSpec.attachedActions.add(dismissAllAction);
// can we get the alarm title somehow?
GBApplication.deviceService().onNotification(notificationSpec); GBApplication.deviceService().onNotification(notificationSpec);
} }
} }