我已经构建了一个小提醒应用程序演示,其中用户填写了一些详细信息并得到通知。当我设置通知时间时,将当前时间设置为5分钟后,例如当前时间是14:55,那么我将当前日期设置为15:00。现在,通知正好按时到来,当我什么也不做时,只需等待5分钟即可结束。
但是,当我手动转到我的Android手机并将时间设置为4分钟(14:59)之后,等待1分钟后,通知不会发出。为什么?
代码: 清单:
<application
...
<receiver android:name=".Receiver.AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
<receiver android:name=".Receiver.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
</receiver>
</application>
AlarmReceiver
public void setAlarm(Context context, Calendar calendar, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Put Reminder ID in Intent Extra
Intent intent = new Intent(context, AlarmReceiver.class);
intent.putExtra(REMINDER_ID, Integer.toString(ID));
mPendingIntent = PendingIntent.getBroadcast(context, ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
/*mPendingIntent = PendingIntent.getBroadcast(context, requestCode, new Intent(context, AlarmReceiver.class),
PendingIntent.FLAG_NO_CREATE);
isAlarmSet = (mPendingIntent != null);
if (isAlarmSet) {
showLog("isAlarmSet: " + isAlarmSet);
} else {
showLog("isAlarmSet: " + isAlarmSet);
}*/
// Calculate notification time
Calendar c = Calendar.getInstance();
long currentTime = c.getTimeInMillis();
long diffTime = calendar.getTimeInMillis() - currentTime;
// Start alarm using notification time
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + diffTime,
mPendingIntent);
// Restart alarm if device is rebooted
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 cancelAlarm(Context context, int ID) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
// Cancel Alarm using Reminder ID
mPendingIntent = PendingIntent.getBroadcast(context, ID, new Intent(context, AlarmReceiver.class), 0);
mAlarmManager.cancel(mPendingIntent);
// Disable alarm
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
private void showLog(String msg) {
Log.d(TAG, msg);
}
}
AddReminderActivity:
private void setReminderAlarm(int id) {
String mDate = tvDueDate.getText().toString();
if (mDate.equals("")) {
mDate = CommonUtils.getDate();
}
String mTime = tvAlarmTime.getText().toString();
String[] mDateSplit = mDate.split("-");
String[] mTimeSplit = mTime.split(":");
mDay = Integer.parseInt(mDateSplit[2]);
mMonth = Integer.parseInt(mDateSplit[1]) - 1;
mYear = Integer.parseInt(mDateSplit[0]);
mHour = Integer.parseInt(mTimeSplit[0]);
mMinute = Integer.parseInt(mTimeSplit[1]);
// Check repeat type
long mRepeatTime = 0;
// Create a new notification
int day = mDay - notificationDay;
mCalendar.set(Calendar.DAY_OF_MONTH, mDay - notificationDay);
mCalendar.set(Calendar.MONTH, mMonth);
mCalendar.set(Calendar.YEAR, mYear);
mCalendar.set(Calendar.HOUR_OF_DAY, mHour);
mCalendar.set(Calendar.MINUTE, mMinute);
mCalendar.set(Calendar.SECOND, 0);
new AlarmReceiver().setAlarm(getApplicationContext(), mCalendar, id);
}
答案 0 :(得分:1)
设置警报时,应使用AlarmManager.RTC_WAKEUP。 AlarmManager.RTC_WAKEUP将根据时钟时间触发警报。
示例代码:
mAlarmManager.set(AlarmManager.RTC_WAKEUP,
currentTime + diffTime,
mPendingIntent);
答案 1 :(得分:0)
通过使用TIME_SET
接收器,您可以通知系统时间已更改。
无论何时创建警报,也只需将时间保存在本地数据库中。触发广播接收器时,调用服务,在该服务内部将获取所有现有警报时间以及新的系统时间。您应注意,更改系统时间后所有警报将被取消。因此,您应该重新创建所有警报。
答案 2 :(得分:0)
mAlarmManager.set()
不会强制在确切的给定时间交付待定意图
注意:从API 19开始,传递给此方法的触发时间被认为是不精确的:警报不会在此时间之前发送,但可能会延迟并在一段时间后发送。操作系统将使用此策略,以便将警报在整个系统中“分批”在一起,从而最大程度地减少设备需要“唤醒”的次数,并最大程度地减少电池消耗。通常,只要将来的警报时间长,就不会延迟不久的警报时间。
mAlarmManager.setExact()
可能符合您的尝试
如果您具有确切的时间和日期(年,月,日,小时和分钟)(您可以使用android studio调试器或logcat进行检查以显示值),则可以使用
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, /*your exact time in millis*/, mPendingIntent
)