Java Android Alarm Manager设置在特定时间重复
我对Android中的alarm manager有一些问题。所以我要做的是将警报设置为重复,以便在每天12:01左右运行DB插入Java Android Alarm Manager设置在特定时间重复,java,android,date,alarmmanager,recurring,Java,Android,Date,Alarmmanager,Recurring,我对Android中的alarm manager有一些问题。所以我要做的是将警报设置为重复,以便在每天12:01左右运行DB插入 Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); calendar.set(Calendar.HOUR_OF_DAY, 0 ); calendar.set(Calendar.MINUTE, 1);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0 );
calendar.set(Calendar.MINUTE, 1);
notificationCount = notificationCount + 1;
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context,
ReminderAlarm.class);
notificationIntent.putExtra("NotifyCount", notificationCount);
PendingIntent pi = PendingIntent.getBroadcast(context,
notificationCount, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
所以基本上我已经想出了这些代码。但是,报警管理器在我设置它的那一分钟后再次执行
假设我在2014年10月1日下午5:48运行这些应用程序。我希望在我将其设置为仅在凌晨12点01分左右后,在onReceive每天运行DB插入。但不知怎的,报警管理器在2014年10月1日下午5时49分执行,这是我设置它后的一分钟,它停止工作
我不知道我做错了哪一部分
提前谢谢
编辑
定期课程
对于该类,它将每天触发报警管理器,并将变量传递给提醒报警类以插入DB
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recurring);
context = this;
buildListView();
if(!alarmInitialized(this)) {
scheduleAlarms(this);
}
}
// And the few methods you suggested to schedule the alarm
public static void scheduleAlarms(Context context) {
Calendar calendar = Calendar.getInstance();
if (hasRunnedToday(context)) { // if the alarm has run this day
calendar.add(Calendar.DATE, 1); // schedule it to run again starting
// tomorrow
}
long firstRunTime = calendar.getTimeInMillis();
AlarmManager mgr = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent notificationIntent = new Intent(context, ReminderAlarm.class);
PendingIntent pi = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstRunTime,
AlarmManager.INTERVAL_DAY, pi);
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
引导接收器类
public void onReceive(Context context, Intent i) {
if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Recurring.scheduleAlarms(context);
}
}
ARM类的提醒
基本上,对于这个类,它只是获取从循环类传递的变量并执行DB插入。我确实插入了一些Toast.makeText来测试它是否正在检索,但测试失败
public class ReminderAlarm extends BroadcastReceiver {
private NotificationManager mNotificationManager;
private Notification notification;
@Override
public void onReceive(Context context, Intent intent) {
String recurID = null;
String recurStartDate = null;
String currentDate = null;
String description = null;
String type = null;
String amount = null;
String categoryName = null;
String frequencyStr = null;
String nextPaymentDate = null;
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
DatabaseAdapter mDbHelper = new DatabaseAdapter(context);
mDbHelper.createDatabase();
mDbHelper.open();
RecurringController rc = new RecurringController(mDbHelper.open());
ArrayList<RecurringModel> recur_list = rc.getAllRecurring();
// THIS PART TO GET DATA FROM DATABASE
for (int i = 0; i < recur_list.size(); i++) {
recurID = recur_list.get(i).getRecurringID();
recurStartDate = recur_list.get(i).getRecurringStartDate();
currentDate = dateFormat.format(new Date());
description = recur_list.get(i).getRecurringDesc();
type = recur_list.get(i).getRecurringType();
amount = Float.toString(recur_list.get(i).getRecurringAmount());
categoryName = recur_list.get(i).getCategoryID();
frequencyStr = recur_list.get(i).getFrequency();
Toast.makeText(context,
description, Toast.LENGTH_LONG)
.show();
Toast.makeText(context,
recurStartDate Toast.LENGTH_LONG)
.show();
Calendar cal = Calendar.getInstance();
try {
cal.setTime(dateFormat.parse(recurStartDate));
if (frequencyStr.equals("Daily")) {
cal.add(Calendar.DAY_OF_MONTH, 1);
nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
cal.add(Calendar.DAY_OF_MONTH, -1);
} else if (frequencyStr.equals("Weekly")) {
cal.add(Calendar.WEEK_OF_YEAR, 1);
nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
cal.add(Calendar.WEEK_OF_YEAR, -1);
} else if (frequencyStr.equals("Monthly")) {
cal.add(Calendar.MONTH, 1);
nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
cal.add(Calendar.MONTH, -1);
} else if (frequencyStr.equals("Yearly")) {
cal.add(Calendar.YEAR, 1);
nextPaymentDate = dateFormat.format(cal.getTimeInMillis());
cal.add(Calendar.YEAR, -1);
}
} catch (ParseException e) {
e.printStackTrace();
}
// If dates match then execute the SQL statements
if (currentDate.equals(nextPaymentDate)) {
// mDbHelper.createDatabase();
// mDbHelper.open();
TransactionRecModel trm = new TransactionRecModel();
CategoryController cc = new CategoryController(mDbHelper.open());
trm.setDate(currentDate);
trm.setTransDescription(description);
trm.setType(type);
trm.setAmount(Float.parseFloat(amount));
// Get the categoryID based on categoryName
String catID = cc.getCatIDByName(categoryName);
trm.setCategory(catID);
// Check if the recurring record exists before insert new
// transaction record
boolean recurExist = rc.checkRecurExist(recurStartDate,
description, catID);
if (recurExist == true) {
TransactionRecController trc = new TransactionRecController(
mDbHelper.open());
// Check if the transaction record exists to prevent
// duplication
boolean moveNext = trc.checkTransExist(trm);
if (moveNext == false) {
if (trc.addTransactionRec(trm)) {
// Update recurring start date after insertion of
// transaction
RecurringModel rm = new RecurringModel();
rm.setRecurringID(recurID);
rm.setRecurringStartDate(currentDate);
if (rc.updateRecurringDate(rm)) {
mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent
.getActivity(
context,
Integer.parseInt(intent
.getExtras()
.get("NotifyCount")
.toString()),
new Intent(), 0);
notification = new Notification(
R.drawable.ic_launcher, "Notification",
System.currentTimeMillis());
notification.setLatestEventInfo(context,
description, nextPaymentDate,
contentIntent);
mNotificationManager
.notify(Integer.parseInt(intent
.getExtras().get("NotifyCount")
.toString()), notification);
mDbHelper.close();
}
}
}
}
mDbHelper.close();
}
}
mDbHelper.close();
Recurring.updateAlarmLastRun(context);
}
}
问题出在calendar.getTimeInMillis()中
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
setInexactRepeating
引用文档的第二个参数
TriggeratMills使用适当的时钟(取决于报警类型),以毫秒为单位,表示报警首次响起的时间。这是不准确的:在此时间之前警报不会触发,但在第一次调用警报之前,可能会有几乎整个警报间隔的延迟
这意味着它将在您设置它大约一分钟后第一次运行,因为
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0 );
calendar.set(Calendar.MINUTE, 1);
如果你不想在第二天第一次报警,那就做一个
日历.添加(日历.日期,1)`
至于it停止工作,您是否重新启动了de设备?
AlarmCalendar报警不会持续到设备重新启动,您可以注册一个BroadcastReceiver
来接收BOOT\u COMPLETED
事件并再次注册报警检查
更新:根据您的要求,在查看代码后,这里提供了一些帮助
在您的引导\u已完成
接收器类:
public void onReceive(Context context, Intent i) {
if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
ReminderAlarm.scheduleAlarms(this);
}
}
在你的课堂上
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recurring);
if(!alarmInitialized(this) {
scheduleAlarms(this);
}
}
注:
context=this
,因为对象持有对其字段的引用context
,而context
字段持有对可能泄漏的对象的引用接收器
'onReceive`没有您假设的额外功能,如设备完成引导时系统接收到的“notificationCount”updateAlarmLastRun
希望这些都有帮助问题出在
日历中。getTimeInMillis()
中
mgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
setInexactRepeating
引用文档的第二个参数
TriggeratMills使用适当的时钟(取决于报警类型),以毫秒为单位,表示报警首次响起的时间。这是不准确的:在此时间之前警报不会触发,但在第一次调用警报之前,可能会有几乎整个警报间隔的延迟
这意味着它将在您设置它大约一分钟后第一次运行,因为
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 0 );
calendar.set(Calendar.MINUTE, 1);
如果你不想在第二天第一次报警,那就做一个
日历.添加(日历.日期,1)`
至于it停止工作,您是否重新启动了de设备?
AlarmCalendar报警不会持续到设备重新启动,您可以注册一个BroadcastReceiver
来接收BOOT\u COMPLETED
事件并再次注册报警检查
更新:根据您的要求,在查看代码后,这里提供了一些帮助
在您的引导\u已完成
接收器类:
public void onReceive(Context context, Intent i) {
if (i.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
ReminderAlarm.scheduleAlarms(this);
}
}
在你的课堂上
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recurring);
if(!alarmInitialized(this) {
scheduleAlarms(this);
}
}
注:
context=this
,因为对象持有对其字段的引用context
,而context
字段持有对可能泄漏的对象的引用接收器
'onReceive`没有您假设的额外功能,如设备完成引导时系统接收到的“notificationCount”updateAlarmLastRun
希望这些都能有所帮助。“…报警管理器在2014年10月1日下午5时49分执行,这是我设置它并停止工作后的一分钟。”您可以通过将
日历.HOUR of_DAY
设置为0来设置时间。这会立即触发报警,直到第二天00:01才会再次触发。@Squonk您对如何解决此问题有什么想法吗?因为根据我的研究,我认为这样做能够在特定时间触发警报。@Squonk那么我应该把这些代码放在哪里呢?您是否介意将整个部分作为答案发布?@Squonk我是否应该在您之前提供的if语句中包装setInExactRepeating?我其实不太清楚:)把我建议的代码放在calendar.set(calendar.MINUTE,1)之后代码>。看看它是否解决了您的问题,如果解决了,我将发布完整的答案。“…报警管理器在2014年10月1日下午5时49分执行,这是我设置它后的一分钟,它停止工作。”您通过将日历.HOUR OF_DAY
设置为0来设置时间倒退。这会立即触发报警,直到第二天00:01才会再次触发。@Squonk您对如何解决此问题有什么想法吗?因为根据我的研究,我认为这样做能够在特定时间触发警报。@Squonk那么我应该把这些代码放在哪里呢?您是否介意将整个部分作为答案发布?@Squonk我是否应该在您之前提供的if语句中包装setInExactRepeating?我其实不太清楚:)把我建议的代码放在calendar.set(calendar.MINUTE,1)之后代码>。看看它是否能解决您的问题,以及