feat: 联系人增加头像选择
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package com.ttstd.dialer.alarmclock;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.provider.Settings;
|
||||
|
||||
import cn.jpush.android.service.AlarmReceiver;
|
||||
|
||||
public class AlarmManagerHelper {
|
||||
|
||||
public static final int ALARM_REQUEST_CODE = 1001;
|
||||
|
||||
/**
|
||||
* 设置一个精准闹钟(兼容 Android 5.0 到 Android 16)
|
||||
*
|
||||
* @param context 上下文
|
||||
* @param triggerAtMillis 触发的时间戳(毫秒)
|
||||
*/
|
||||
public static void setExactAlarm(Context context, long triggerAtMillis) {
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
if (alarmManager == null) return;
|
||||
|
||||
// 检查 Android 12+ 的精准闹钟权限
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
if (!alarmManager.canScheduleExactAlarms()) {
|
||||
// 如果没有权限,跳转到系统设置页让用户授权
|
||||
Intent intent = new Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(context, AlarmReceiver.class);
|
||||
// 使用 FLAG_IMMUTABLE 或 FLAG_MUTABLE 增强 Android 12+ 安全性
|
||||
int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ?
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE :
|
||||
PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, intent, flags);
|
||||
|
||||
// 核心兼容性定时逻辑
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// Android 6.0+ 支持低功耗休眠模式(Doze Mode)下的精准唤醒
|
||||
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
// Android 4.4 - 5.1 精准唤醒
|
||||
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
|
||||
} else {
|
||||
// Android 4.4 以下
|
||||
alarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消闹钟
|
||||
*/
|
||||
public static void cancelAlarm(Context context) {
|
||||
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
|
||||
if (alarmManager != null) {
|
||||
Intent intent = new Intent(context, AlarmReceiver.class);
|
||||
int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ?
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE :
|
||||
PendingIntent.FLAG_UPDATE_CURRENT;
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, intent, flags);
|
||||
alarmManager.cancel(pendingIntent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.ttstd.dialer.alarmclock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class AlarmRepeatConfig {
|
||||
public static final int REPEAT_ONCE = 0; // 只响一次
|
||||
public static final int REPEAT_EVERYDAY = 1; // 每天
|
||||
public static final int REPEAT_WEEKDAYS = 2; // 周一至周五
|
||||
public static final int REPEAT_CUSTOM = 3; // 自定义星期几(比如只选周六日)
|
||||
|
||||
private int repeatType;
|
||||
private ArrayList<Integer> customDays; // 存储 Calendar.MONDAY (2) 到 Calendar.SATURDAY (7)
|
||||
|
||||
public AlarmRepeatConfig(int repeatType) {
|
||||
this.repeatType = repeatType;
|
||||
this.customDays = new ArrayList<>();
|
||||
if (repeatType == REPEAT_WEEKDAYS) {
|
||||
customDays.add(Calendar.MONDAY);
|
||||
customDays.add(Calendar.TUESDAY);
|
||||
customDays.add(Calendar.WEDNESDAY);
|
||||
customDays.add(Calendar.THURSDAY);
|
||||
customDays.add(Calendar.FRIDAY);
|
||||
}
|
||||
}
|
||||
|
||||
public int getRepeatType() {
|
||||
return repeatType;
|
||||
}
|
||||
|
||||
public ArrayList<Integer> getCustomDays() {
|
||||
return customDays;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.ttstd.dialer.alarmclock;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class AlarmTimeCalculator {
|
||||
|
||||
/**
|
||||
* 根据重复配置,计算下一次闹钟应该响铃的绝对时间(毫秒)
|
||||
*
|
||||
* @param hour 闹钟设定的小时
|
||||
* @param minute 闹钟设定的分钟
|
||||
* @param config 重复配置
|
||||
* @return 下一次响铃的时间戳
|
||||
*/
|
||||
public static long calculateNextAlarmTime(int hour, int minute, AlarmRepeatConfig config) {
|
||||
Calendar now = Calendar.getInstance();
|
||||
|
||||
Calendar target = Calendar.getInstance();
|
||||
target.set(Calendar.HOUR_OF_DAY, hour);
|
||||
target.set(Calendar.MINUTE, minute);
|
||||
target.set(Calendar.SECOND, 0);
|
||||
target.set(Calendar.MILLISECOND, 0);
|
||||
|
||||
// 情况 1:只响一次
|
||||
if (config.getRepeatType() == AlarmRepeatConfig.REPEAT_ONCE) {
|
||||
// 如果设定的时间在今天已经过去了,就定在明天
|
||||
if (target.getTimeInMillis() <= now.getTimeInMillis()) {
|
||||
target.add(Calendar.DAY_OF_MONTH, 1);
|
||||
}
|
||||
return target.getTimeInMillis();
|
||||
}
|
||||
|
||||
// 情况 2:每天
|
||||
if (config.getRepeatType() == AlarmRepeatConfig.REPEAT_EVERYDAY) {
|
||||
if (target.getTimeInMillis() <= now.getTimeInMillis()) {
|
||||
target.add(Calendar.DAY_OF_MONTH, 1);
|
||||
}
|
||||
return target.getTimeInMillis();
|
||||
}
|
||||
|
||||
// 情况 3 & 4:周一至周五 或 自定义星期
|
||||
if (config.getRepeatType() == AlarmRepeatConfig.REPEAT_WEEKDAYS ||
|
||||
config.getRepeatType() == AlarmRepeatConfig.REPEAT_CUSTOM) {
|
||||
|
||||
ArrayList<Integer> targetDays = config.getCustomDays();
|
||||
|
||||
// 从今天开始,往后最多循环7天,找到最近的符合星期要求的日子
|
||||
for (int i = 0; i < 7; i++) {
|
||||
int currentDayOfWeek = target.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
// 如果 target 的日子在今天或今天之后,且其星期在用户选中的列表中
|
||||
if (targetDays.contains(currentDayOfWeek)) {
|
||||
// 如果刚好是今天,但时间已经过去了,则不能算今天,继续往后找
|
||||
if (i == 0 && target.getTimeInMillis() <= now.getTimeInMillis()) {
|
||||
target.add(Calendar.DAY_OF_MONTH, 1);
|
||||
continue;
|
||||
}
|
||||
// 找到了最近的匹配日期
|
||||
return target.getTimeInMillis();
|
||||
}
|
||||
// 否则,日期加一天,继续匹配
|
||||
target.add(Calendar.DAY_OF_MONTH, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return target.getTimeInMillis();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user