137 lines
5.8 KiB
Java
137 lines
5.8 KiB
Java
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<Integer> 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());
|
|
}
|
|
}
|