日历对象时间与安卓手机时间不匹配



我构建了一个小型提醒应用程序演示,用户可以在其中填写一些详细信息并获得通知。当我将通知时间设置为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>

报警接收器

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);
}
}

添加提醒活动:

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);
}

设置闹钟时应使用AlarmManager.RTC_WAKEUP。AlarmManager.RTC_WAKEUP会根据时钟的时间触发闹钟。

示例代码:

mAlarmManager.set(AlarmManager.RTC_WAKEUP, currentTime + diffTime, mPendingIntent);

通过使用TIME_SET接收器,您可以通知系统时间已更改。

每当您创建警报时,只需在本地数据库中节省时间即可。当广播接收器被触发时,调用一个服务,在该服务内部获取所有现有的报警时间与新的系统时间。您应该知道,一旦您更改系统时间,所有警报都将被取消。因此,您应该重新创建所有警报。

>mAlarmManager.set()不会强制在确切的给定时间传递待处理的意图

https://developer.android.com/reference/android/app/AlarmManager.html#set(int,%20long,%20android.app.PendingIntent)

注意:从 API 19 开始,传递给此方法的触发时间被视为不精确:警报不会在此时间之前传递,但可能会延迟并在一段时间后传递。操作系统将使用此策略在整个系统中"批量"警报,从而最大限度地减少设备需要"唤醒"的次数并最大限度地减少电池使用。通常,只要计划在遥远的未来发出警报,在不久的将来安排的警报就不会延迟。

mAlarmManager.setExact()可能适合您要做的事情

如果您有确切的时间和日期(年,月,日,小时和分钟)(您可以使用Android Studio Debugger或LogCat进行检查以打印值),则可以通过以下方式设置闹钟mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, /*your exact time in millis*/, mPendingIntent);

最新更新