android alarmManager setRepating проблема задержки времени - PullRequest
0 голосов
/ 25 апреля 2020

Я хочу отправить уведомление с менеджером тревог в моем приложении. Я использую метод setRepeating, потому что он должен быть в интервалах. но уведомления всегда приходят с задержкой. Например, я хотел бы получить уведомление в 12:14. но приходит уведомление иногда 12:17, иногда 12:20

Заранее спасибо

Примечание: режим ожидания выключен

Например:

thatDay Sat 25 апреля 16:30:00 GMT + 03: 00 2020

сегодня сб 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);
       }
   }

1 Ответ

0 голосов
/ 25 апреля 2020

Это потому, что setRepeating запускается только когда что-то еще происходит в фоновом режиме. В основном это связано с экономией батареи. Лучший способ установить повторяющуюся тревогу - это использовать setExact и установить другую тревогу после срабатывания первой.

Alarmmanager:

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

А внутри Приемника оповещений вы делаете это:

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

}
...