android alarmManager setRepating时间延迟问题
android alarmManager setRepating time delay problem
我想在我的应用程序中通过警报管理器发送通知。我正在使用 setRepeating 方法,因为它应该是间隔的。但通知总是延迟。
例如,我想在 12:14 收到通知。但通知有时 12:17,有时 12:20
提前致谢
注意:打瞌睡模式关闭
例如:
thatDay 4 月 25 日星期六 16:30:00 GMT+03:00 2020
今天 4 月 25 日星期六 16:07:44 GMT+03:00 2020
thatDay.getTimeInMillis() = 1587821400000
@Override
protected void onStop() {
if (notification) {
Calendar thatDay = Calendar.getInstance();
Calendar today = Calendar.getInstance();
int today_month_day = today.get(Calendar.DAY_OF_MONTH);
int today_month = today.get(Calendar.MONTH);
int today_year = today.get(Calendar.YEAR);
thatDay.setTime(new Date(0));
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day);
thatDay.set(Calendar.MONTH, today_month);
thatDay.set(Calendar.YEAR, today_year);
thatDay.set(Calendar.HOUR_OF_DAY, 8);
thatDay.set(Calendar.MINUTE, 0);
thatDay.set(Calendar.SECOND, 0);
thatDay.set(Calendar.MILLISECOND, 0);
Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.HOUR_OF_DAY) < 23 && calendar.get(Calendar.HOUR_OF_DAY) > 7) {
if (calendar.get(Calendar.MINUTE) < 30) {
thatDay.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
thatDay.set(Calendar.MINUTE, 30);
} else {
thatDay.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
}
} else if (thatDay.getTimeInMillis() - today.getTimeInMillis() < 0) {
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day + 1);
} else {
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day);
}
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("NotificationID", 6);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 7, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Objects.requireNonNull(alarmManager).setRepeating(AlarmManager.RTC_WAKEUP, thatDay.getTimeInMillis(), waterList[waterCheck], pendingIntent);
super.onStop();
}
@SuppressLint("BatteryLife")
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestBattery() {
Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!(Objects.requireNonNull(pm).isIgnoringBatteryOptimizations(packageName))) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(intent, BATTERY_PERMISSION);
}
}
这是因为 setRepeating 仅在后台发生其他事情时触发。这主要是由于节省电池。设置重复警报的最佳方法是使用 setExact 并在第一个警报被触发后设置另一个警报。
警报管理器:
public class AlarmManagerSetup {
public static Boolean alarmActivated;
public static Long milliSeconds;
public void startAlarm(Calendar c, Context context, Database database) {
android.app.AlarmManager alarmManager = (android.app.AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 0);
c.setTimeInMillis(milliSeconds);
//compares to the current time and only adds when it is later than now
if (c.before(Calendar.getInstance())) {
c.add(Calendar.DATE, 1);
}
if (Build.VERSION.SDK_INT >= 23) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
}
然后在 Alert Receiver 中执行此操作:
public class AlertReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Context appContext = context.getApplicationContext();
CalendarSearch calendar = new CalendarSearch(context);
calendar.calendar();
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification(appContext);
notificationHelper.getManager().notify(1, nb.build());
AlarmManagerSetup alarmManager = new AlarmManagerSetup();
Calendar c = Calendar.getInstance();
c.setTimeInMillis(milliSeconds);
c.add(Calendar.DATE, 1);
milliSeconds = c.getTimeInMillis();
alarmManager.startAlarm(c, appContext, database);
}
我想在我的应用程序中通过警报管理器发送通知。我正在使用 setRepeating 方法,因为它应该是间隔的。但通知总是延迟。 例如,我想在 12:14 收到通知。但通知有时 12:17,有时 12:20
提前致谢
注意:打瞌睡模式关闭
例如:
thatDay 4 月 25 日星期六 16:30:00 GMT+03:00 2020
今天 4 月 25 日星期六 16:07:44 GMT+03:00 2020
thatDay.getTimeInMillis() = 1587821400000
@Override
protected void onStop() {
if (notification) {
Calendar thatDay = Calendar.getInstance();
Calendar today = Calendar.getInstance();
int today_month_day = today.get(Calendar.DAY_OF_MONTH);
int today_month = today.get(Calendar.MONTH);
int today_year = today.get(Calendar.YEAR);
thatDay.setTime(new Date(0));
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day);
thatDay.set(Calendar.MONTH, today_month);
thatDay.set(Calendar.YEAR, today_year);
thatDay.set(Calendar.HOUR_OF_DAY, 8);
thatDay.set(Calendar.MINUTE, 0);
thatDay.set(Calendar.SECOND, 0);
thatDay.set(Calendar.MILLISECOND, 0);
Calendar calendar = Calendar.getInstance();
if (calendar.get(Calendar.HOUR_OF_DAY) < 23 && calendar.get(Calendar.HOUR_OF_DAY) > 7) {
if (calendar.get(Calendar.MINUTE) < 30) {
thatDay.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY));
thatDay.set(Calendar.MINUTE, 30);
} else {
thatDay.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 1);
}
} else if (thatDay.getTimeInMillis() - today.getTimeInMillis() < 0) {
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day + 1);
} else {
thatDay.set(Calendar.DAY_OF_MONTH, today_month_day);
}
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("NotificationID", 6);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 7, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Objects.requireNonNull(alarmManager).setRepeating(AlarmManager.RTC_WAKEUP, thatDay.getTimeInMillis(), waterList[waterCheck], pendingIntent);
super.onStop();
}
@SuppressLint("BatteryLife")
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestBattery() {
Intent intent = new Intent();
String packageName = context.getPackageName();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
if (!(Objects.requireNonNull(pm).isIgnoringBatteryOptimizations(packageName))) {
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
intent.setData(Uri.parse("package:" + packageName));
startActivityForResult(intent, BATTERY_PERMISSION);
}
}
这是因为 setRepeating 仅在后台发生其他事情时触发。这主要是由于节省电池。设置重复警报的最佳方法是使用 setExact 并在第一个警报被触发后设置另一个警报。
警报管理器:
public class AlarmManagerSetup {
public static Boolean alarmActivated;
public static Long milliSeconds;
public void startAlarm(Calendar c, Context context, Database database) {
android.app.AlarmManager alarmManager = (android.app.AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1, intent, 0);
c.setTimeInMillis(milliSeconds);
//compares to the current time and only adds when it is later than now
if (c.before(Calendar.getInstance())) {
c.add(Calendar.DATE, 1);
}
if (Build.VERSION.SDK_INT >= 23) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
}
然后在 Alert Receiver 中执行此操作:
public class AlertReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Context appContext = context.getApplicationContext();
CalendarSearch calendar = new CalendarSearch(context);
calendar.calendar();
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification(appContext);
notificationHelper.getManager().notify(1, nb.build());
AlarmManagerSetup alarmManager = new AlarmManagerSetup();
Calendar c = Calendar.getInstance();
c.setTimeInMillis(milliSeconds);
c.add(Calendar.DATE, 1);
milliSeconds = c.getTimeInMillis();
alarmManager.startAlarm(c, appContext, database);
}