系统各种升级,对闹钟设置也是个各种修改,前人送的福利大多数不能用了,只能自己整.
public class AlarmManagerUtil {
// 起床铃
public static final String ALARM_ACTION_RING = "com.lskj.alarm.ring";
/**
* 重新设置下次响铃时间
*
* @param context
* @param timeInMillis
* @param intent
*/
public static void setAlarmTime(Context context, long timeInMillis, Intent intent) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent sender = PendingIntent.getBroadcast(context, intent.getIntExtra("id", 0),
intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (null != am) {
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, timeInMillis, sender);
}
}
public static void cancelAlarm(Context context, String action, int id) {
Intent intent = new Intent(action);
PendingIntent pi = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (null != am) {
am.cancel(pi);
}
}
/**
* 设置起床铃
*
* @param flag 周期性时间间隔的标志,flag = 0 表示一次性的闹钟, flag = 1 表示每天提醒的闹钟(1天的时间间隔),flag = 2
* 表示按周每周提醒的闹钟(一周的周期性时间间隔)
* @param timeStr 时间--格式 hh:mm
* @param id 闹钟的id
* @param weekday weekday=0表示一次性闹钟或者按天的周期性闹钟,非0 的情况下是几就代表以周为周期性的周几的闹钟
* @param ringMediaType 铃声类型(1是系统铃声, 2是录音)
* @param ringMediaId 铃声提醒必填
* @param ringMediaUrl 闹钟提示音的URL
*/
public static void setAlarmRing(Context context,
int flag, String timeStr, int id, int weekday,
int ringMediaType, int ringMediaId, String ringMediaUrl) {
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Date date = StringUtils.str2Date(timeStr, "HH:mm");
Calendar alarmCalendar = Calendar.getInstance();
alarmCalendar.setTime(date);
int hour = alarmCalendar.get(Calendar.HOUR_OF_DAY);
int minute = alarmCalendar.get(Calendar.MINUTE);
Calendar calendar = Calendar.getInstance();
long intervalMillis = 0;
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), hour, minute, 0);
// 设置响铃间隔时间
if (flag == 0) {
intervalMillis = 0;
} else if (flag == 1) {
intervalMillis = 24 * 3600 * 1000;
} else if (flag == 2) {
intervalMillis = 24 * 3600 * 1000 * 7;
}
Intent intent = new Intent(ALARM_ACTION_RING);
intent.putExtra("intervalMillis", intervalMillis);
intent.putExtra("id", id);
intent.putExtra("ringMediaType", ringMediaType);
intent.putExtra("ringMediaId", ringMediaId);
intent.putExtra("ringMediaUrl", ringMediaUrl);
PendingIntent sender = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT);
if (null != am) {
// 设置的是Android19以上,以前的repeat方法不准确 ,闹钟时间不准确
// 后来使用setWindow还是不准确
// **setExactAndAllowWhileIdle**这个就好啦反正我用着没问题, 还有一个 **setAndAllowWhileIdle** 我没试过不知道什么情况
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calMethod(weekday, calendar.getTimeInMillis()), sender);
}
}
/**
* @param weekFlag 传入的是周几
* @param dateTime 传入的是时间戳(设置当天的年月日+从选择框拿来的时分秒)
* @return 返回起始闹钟时间的时间戳
*/
private static long calMethod(int weekFlag, long dateTime) {
long time = 0;
//weekflag == 0表示是按天为周期性的时间间隔或者是一次行的,weekfalg非0时表示每周几的闹钟并以周为时间间隔
if (weekFlag != 0) {
Calendar c = Calendar.getInstance();
int week = c.get(Calendar.DAY_OF_WEEK);
if (1 == week) {
week = 7;
} else if (2 == week) {
week = 1;
} else if (3 == week) {
week = 2;
} else if (4 == week) {
week = 3;
} else if (5 == week) {
week = 4;
} else if (6 == week) {
week = 5;
} else if (7 == week) {
week = 6;
}
if (weekFlag == week) {
if (dateTime > System.currentTimeMillis()) {
time = dateTime;
} else {
time = dateTime + 7 * 24 * 3600 * 1000;
}
} else if (weekFlag > week) {
time = dateTime + (weekFlag - week) * 24 * 3600 * 1000;
} else { // if (weekFlag < week)
time = dateTime + (weekFlag - week + 7) * 24 * 3600 * 1000;
}
} else {
if (dateTime > System.currentTimeMillis()) {
time = dateTime;
} else {
time = dateTime + 24 * 3600 * 1000;
}
}
return time;
}
}
public class ClockAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
long intervalMillis = intent.getLongExtra("intervalMillis", 0);
Log.d("ClockAlarmReceiver", "intervalMillis = " + intervalMillis);
if (intervalMillis != 0) {
// 闹钟重复设置
AlarmManagerUtil.setAlarmTime(context, System.currentTimeMillis() + intervalMillis, intent);
}
switch (Objects.requireNonNull(intent.getAction())) {
case AlarmManagerUtil.ALARM_ACTION_RING:
// 处理事件
break;
}
}
<manifest....>
<application....>
....
<!--
==**对应包名,对应action**==
-->
<receiver android:name=".biz.alarm.ClockAlarmReceiver">
<intent-filter>
<action android:name="com.lskj.alarm.ring" />
</intent-filter>
</receiver>
</application>
</manifest>