package com.ttstd.dialer.receiver; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Parcelable; import androidx.core.app.NotificationCompat; import com.ttstd.dialer.activity.alarm.AlarmAlertActivity; import com.ttstd.dialer.alarmclock.AlarmManagerHelper; import com.ttstd.dialer.alarmclock.AlarmRepeatConfig; import com.ttstd.dialer.alarmclock.AlarmTimeCalculator; import com.ttstd.dialer.db.alarm.AlarmInfo; import com.ttstd.dialer.db.alarm.AlarmRepository; import com.ttstd.dialer.db.alarm.IntegerListConverter; import com.ttstd.dialer.utils.Logger; import java.util.ArrayList; import java.util.List; public class AlarmReceiver extends BroadcastReceiver { private static final String TAG = "AlarmReceiver"; private static final String CHANNEL_ID = "alarm_channel"; @Override public void onReceive(Context context, Intent intent) { int alarmId = intent.getIntExtra("ALARM_ID", -1); Logger.d(TAG, "收到闹钟广播, ID: " + alarmId); if (alarmId == -1) { Logger.e(TAG, "收到闹钟广播但 ALARM_ID 为空"); return; } // 使用同步方法获取闹钟信息 AlarmRepository repository = new AlarmRepository(context); AlarmInfo alarmInfo = repository.getAlarmById(alarmId); if (alarmInfo == null) { Logger.e(TAG, "未找到对应的闹钟数据, ID: " + alarmId); return; } if (!alarmInfo.isEnabled()) { Logger.w(TAG, "闹钟已被禁用,不再处理: " + alarmId); return; } // 1. 执行响铃和弹出通知逻辑 showAlarmNotification(context, alarmInfo); // 尝试直接启动 Activity try { Intent alertIntent = new Intent(context, AlarmAlertActivity.class); alertIntent.putExtra("AlarmInfo", (Parcelable) alarmInfo); alertIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(alertIntent); } catch (Exception e) { Logger.e(TAG, "直接启动 AlarmAlertActivity 失败: " + e.getMessage()); } // 2. 核心:动态轮转,实现重复闹钟 scheduleNextRepeatAlarm(context, repository, alarmInfo); } private void scheduleNextRepeatAlarm(Context context, AlarmRepository repository, AlarmInfo alarmInfo) { // 如果是“只响一次”,响完就将其置为禁用状态 if (alarmInfo.getRepeatType() == AlarmRepeatConfig.REPEAT_ONCE) { alarmInfo.setEnabled(false); repository.updateAlarm(alarmInfo); return; } // 重新计算下一次的时间 AlarmRepeatConfig config = new AlarmRepeatConfig(alarmInfo.getRepeatType()); if (alarmInfo.getRepeatType() == AlarmRepeatConfig.REPEAT_CUSTOM) { List days = IntegerListConverter.toIntegerList(alarmInfo.getCustomDays()); config.setCustomDays(new ArrayList<>(days)); } long nextTriggerTime = AlarmTimeCalculator.calculateNextAlarmTime( alarmInfo.getHour(), alarmInfo.getMinute(), config); // 更新数据库中的下次触发时间 alarmInfo.setNextTriggerTime(nextTriggerTime); repository.updateAlarm(alarmInfo); // 再次调用精准闹钟设置工具,埋下新的定时炸弹 AlarmManagerHelper.setExactAlarm(context, alarmInfo.getId(), nextTriggerTime); } private void showAlarmNotification(Context context, AlarmInfo alarmInfo) { NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (notificationManager == null) return; // 1. 创建通知渠道 (Android 8.0+) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( CHANNEL_ID, "闹钟响铃", NotificationManager.IMPORTANCE_HIGH); channel.setDescription("用于展示闹钟响铃界面"); channel.enableLights(true); channel.setBypassDnd(true); // 绕过免打扰 notificationManager.createNotificationChannel(channel); } // 2. 构建点击通知或全屏弹出的 Intent Intent alertIntent = new Intent(context, AlarmAlertActivity.class); alertIntent.putExtra("AlarmInfo", (Parcelable) alarmInfo); alertIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE : PendingIntent.FLAG_UPDATE_CURRENT; // 使用 alarmId 作为 requestCode 区分不同的闹钟通知 PendingIntent pendingIntent = PendingIntent.getActivity(context, alarmInfo.getId(), alertIntent, flags); // 3. 构建高优先级通知 NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID) .setSmallIcon(android.R.drawable.ic_lock_idle_alarm) .setContentTitle("闹钟响了") .setContentText(alarmInfo.getLabel() != null && !alarmInfo.getLabel().isEmpty() ? alarmInfo.getLabel() : "时间到了,快起床!") .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_ALARM) .setAutoCancel(true) .setFullScreenIntent(pendingIntent, true); // 核心:锁屏时直接拉起 Activity notificationManager.notify(alarmInfo.getId(), builder.build()); } }