警报管理器不适用于Android中的多个警报
Posted
技术标签:
【中文标题】警报管理器不适用于Android中的多个警报【英文标题】:Alarm manager not working for multiple Alarm in Android 【发布时间】:2018-07-14 21:56:26 【问题描述】:我想使用基于某些数据库时间值的警报。目前我的闹钟正在为一个闹钟工作,例如:我在上午 8:30、上午 10:20 和下午 12:20 设置了 3 个闹钟 我的闹钟只适用于一个值。这是我正在创建闹钟的提醒类
public class OwnGoalReminder extends EventReminder
GoalOwn goalOwn;
int interValTime;
int goalId;
int hour;
int minute;
int requestCode;
String type;
public void setInterValTime(int interValTime)
this.interValTime = interValTime;
public int getHour()
return hour;
public void setHour(int hour)
this.hour = hour;
public void setRequestCode(int requestCode)
this.requestCode = requestCode;
public void setType(String type)
this.type = type;
public int getMinute()
return minute;
@Override
protected int getGoalId()return this.goalId;
public void setMinute(int minute)
this.minute = minute;
public OwnGoalReminder(Context context , int goalId, int interValTime)
super(context);
this.interValTime = interValTime;
this.goalId = goalId;
@Override
protected String getType()
return this.type;
@Override
protected String getMessage()
return "Reminder!!! You should check your goals!";
@Override
protected int getRequestCode()
return requestCode;
@Override
protected EventTime getEventTime()
int h = hour;
int m = minute;
return new EventTime(hour,minute,interValTime);
@Override
protected Class getBroadcastReceiver()
return MyBroadcastReceiver.class;
这是 OwnGOalReminder 的基类
public abstract class EventReminder
protected Context context;
protected Alarm alarm;
PushNotificationsManager notificationsManager;
public void remind()
Bundle bundle = new Bundle();
bundle.putString("type", getType());
bundle.putString("msg", getMessage());
notificationsManager.sendNotification(bundle);
protected abstract String getType();
protected abstract String getMessage();
protected abstract int getRequestCode();
protected abstract int getGoalId();
protected abstract EventTime getEventTime();
protected abstract Class getBroadcastReceiver();
protected EventReminder(Context context)
this.context = context;
alarm = new Alarm(context, getBroadcastReceiver());
notificationsManager = new PushNotificationsManager(context);
public void startReminder()
alarm.startAlert(getRequestCode(), getGoalId(), getEventTime().hour, getEventTime().minute, getEventTime().intervalInMinute);
//alarm.setAlarm(context, getEventTime().hour, getEventTime().minute);
protected class EventTime
int hour, minute, intervalInMinute;
public EventTime(int hour, int minute, int intervalInMinute)
this.hour = hour;
this.minute = minute;
this.intervalInMinute = intervalInMinute;
这是警报类,我正在创建警报管理器
public class Alarm
private final Context context;
private Class broadcastReceiver;
public Alarm(Context context, Class broadcastReceiver)
this.context = context;
this.broadcastReceiver = broadcastReceiver;
public void startAlert(int requestCode, int gid, int hour, int minute, int intervalMinute)
Log.d(this.getClass().getName(), "starting alert");
int i = 10;
Long timeToMilliSeconds = timeToMilliSeconds(hour, minute);
Intent intent = new Intent(context, MyBroadcastReceiver.class);
intent.putExtra("reqcode", requestCode);
intent.putExtra("time", timeToMilliSeconds);
intent.putExtra("gid" , gid);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, timeToMilliSeconds+
+ (i * 1000), 1000*60*intervalMinute, pendingIntent);
//Toast.makeText(context, "Alarm set in " + i + " seconds",Toast.LENGTH_LONG).show();
@NonNull
public static long timeToMilliSeconds(int hour, int minute)
Date dat = new Date();//initializes to now
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_now.setTime(dat);
cal_alarm.setTime(dat);
cal_alarm.set(Calendar.HOUR_OF_DAY,hour);//set the alarm time
cal_alarm.set(Calendar.MINUTE, minute);
cal_alarm.set(Calendar.SECOND,0);
if(cal_alarm.getTimeInMillis() < System.currentTimeMillis())
cal_alarm.add(Calendar.DAY_OF_YEAR,1);
return cal_alarm.getTimeInMillis();
这是我根据数据库值创建多个警报对象的方法
public static void registerAlarm(Context context)
if(!UserPreferences.isAlarmRegistered(context))
GoalReminder goalReminder = new GoalReminder(context);
AppraisalReminder appraisalReminder = new AppraisalReminder(context);
goalReminder.startReminder();
appraisalReminder.startReminder();
// ownGoalReminder.startReminder();
//UserPreferences.setIsAlarmRegistered(context,true);
ArrayList<Goal> LIST_OF_OWN_GOALS = new ArrayList<>();
LIST_OF_OWN_GOALS = (ArrayList<Goal>) Goal.getGoalFromOwnGoals();
for (Goal g : LIST_OF_OWN_GOALS)
OwnGoalReminder ownGoalReminder = new OwnGoalReminder(context , g.getgId(),3 );
int h = Integer.parseInt(g.getrTime())/60;
int min = Integer.parseInt(g.getrTime())%60;
ownGoalReminder.setHour(h);
ownGoalReminder.setMinute(min);
ownGoalReminder.setRequestCode(16);
ownGoalReminder.setType("16");
ownGoalReminder.startReminder();
LIST_OF_OWN_REMINDERS.add(ownGoalReminder);
这是我的广播接收器类:
public class MyBroadcastReceiver extends BroadcastReceiver
private static final String[] goalMessagesArray = ApraiseApplication.getContext().getResources().getStringArray(R.array.goals_messages);
private static Queue<String> goalMessagesQueue = new ArrayDeque<>(Arrays.asList(goalMessagesArray));
private static final String[] appraisalsMessagesArray = ApraiseApplication.getContext().getResources().getStringArray(R.array.appraisals_messages);
private static Queue<String> appraisalsMessagesQueue = new ArrayDeque<>(Arrays.asList(appraisalsMessagesArray));
@Override
public void onReceive(Context context, Intent intent)
Log.d(this.getClass().getName(), "notify");
PushNotificationsManager notificationsManager = new PushNotificationsManager(context);
PowerManager.WakeLock wl = acquireWakeLock(context);
int requestCode = intent.getIntExtra("reqcode",1);
int gId = intent.getIntExtra("gid",1);
long time = intent.getLongExtra("time",0);
String message = "";
// it will create the instance of Random class
Random randomGenerator = new Random();
// it will generate a random number based on goal message arrayList length
int indexForGoalMessage = randomGenerator.nextInt(goalMessagesArray.length);
// it will generate a random number based on appraisalsMessagesArray length
int indexForAppraisalsMessage = randomGenerator.nextInt(goalMessagesArray.length);
String gid = "";
if(isNotifyTimePassed(time))
//return;
if(requestCode == 123)
// if(goalMessagesQueue.isEmpty())
// goalMessagesQueue = new ArrayDeque<>(Arrays.asList(goalMessagesArray));
//
// message = goalMessagesQueue.poll();
message = goalMessagesArray[indexForGoalMessage];
else if(requestCode == 124)
// if(appraisalsMessagesQueue.isEmpty())
// appraisalsMessagesQueue = new ArrayDeque<>(Arrays.asList(appraisalsMessagesArray));
//
// message = appraisalsMessagesQueue.poll();
message = appraisalsMessagesArray[indexForAppraisalsMessage];
Bundle bundle = new Bundle();
bundle.putString("type", Integer.toString(requestCode));
bundle.putString("msg", message);
bundle.putString("gid" , String.valueOf(gId));
notificationsManager.sendNotification(bundle);
wl.release();
@NonNull
private PowerManager.WakeLock acquireWakeLock(Context context)
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
return wl;
private boolean isNotifyTimePassed(long time)
return (System.currentTimeMillis()-time) > 1000L*60L*5L;
【问题讨论】:
AtomicInteger 也可用于获取唯一 ID,如果您在同时有多个通知时遇到任何通知排序问题。 【参考方案1】:最好将你的事件id(唯一id)设置为PendingIntent.getBroadcast()方法的请求码。所以这里的好处是当你更新/编辑事件时,警报不会重复。
【讨论】:
【参考方案2】:[我通过搜索谷歌找到了这个解决方案]
我通过传递取决于当前时间的唯一 id 解决了这个问题:-
final int intent_id= (int) System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context, intent_id , intent, PendingIntent.FLAG_UPDATE_CURRENT);
【讨论】:
以上是关于警报管理器不适用于Android中的多个警报的主要内容,如果未能解决你的问题,请参考以下文章
Android 警报管理器 setExactAndAllowWhileIdle() 在打盹模式下的 Android 7.0 Nougat 中不起作用