Использование setExact () в широковещательном приемнике для повтора

Сценарий: Работники производственной линии проводят проверки через определенные промежутки времени. В моем приложении пользователь вводит этот временной интервал в текстовое поле. Есть средства выбора даты и времени, чтобы пользователь мог выбрать, когда процесс начался. Я пытаюсь включить сигнализацию за 5 минут до следующей проверки.

Например: Процесс начинается в 2.30. Пользователь входил с интервалом в 20 минут. Следовательно, следующая проверка должна быть произведена в 2.50. Тревога должна звучать в 2.45. Затем этот процесс повторится, поэтому следующая проверка будет 3.10, а сигнал тревоги должен прозвучать в 3.05.

Вот код, который у меня есть:

 MainActivity.calculate();
        commencedTime = new Date();
        mTime = Calendar.getInstance();
        mTime.setTime(alarmTime);
        timeCommenced = trimSecsAndMillisecs(mTime).getTimeInMillis();

        currentTime = new Date();
        currentTime.getTime();

        alertDialogBuilder = new AlertDialog.Builder(MainActivity.this);
        //set alert
        alertDialogBuilder
                .setTitle("IP Check frequency: " + time.getText() + " minutes")
                .setMessage("Processing commenced at \n" + startTime.getText())
                .setCancelable(false)
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {

                        if (currentTime.after(alarmTime)) {
                            Toast.makeText(MainActivity.this, "Missed first alert", Toast.LENGTH_LONG).show();
                        }

                        i = Integer.parseInt(time.getText().toString());
                        long scTime2 = ((i * 60 * 1000)); //TIME ENTERED IN MILLISECONDS

                        intent1 = new Intent(MainActivity.this, MyBroadcastReceiver.class);
                        intent1.putExtra("timeEntered", scTime2);
                        intent1.putExtra("timeCommenced", timeCommenced);
                        sendBroadcast(intent1);

                        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent1, PendingIntent.FLAG_UPDATE_CURRENT);

                        manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
                        manager.setExact(AlarmManager.RTC_WAKEUP, timeCommenced, pendingIntent);

                        Toast.makeText(MainActivity.this, "Alert Set", Toast.LENGTH_SHORT).show();
                        stopped.setVisibility(View.VISIBLE);
                        commenced1.setVisibility(View.GONE);

                        //Change editText to TextView
                        time.setVisibility(View.GONE);
                        timeText.setVisibility(View.VISIBLE);
                        timeText.setText(time.getText().toString());
                        processingText.setText(R.string.processing_commenced);

                    }
                })
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
        alertDialog = alertDialogBuilder.create();
        alertDialog.show();

    }
}

Приемник трансляции:

@Override
public void onReceive(Context context, Intent intent) {
    // Vibrate the mobile phone
    vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    long[] pattern = {0, 10000, 3, 10000};
    vibrator.vibrate(pattern, -1); // vibration for 20 seconds

    //create as instance of the media player
    mediaPlayer = MediaPlayer.create(context, R.raw.alarm_sound);
    mediaPlayer.start();

   createNotification(context, "AlmaIPC", "IP check is due", "Alert");

    AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
    Intent intent2 = new Intent(context, MainActivity.class);
    PendingIntent pi2 = PendingIntent.getActivity(context, 0, intent2, 0);

    Long timeEntered =intent.getLongExtra("timeEntered", 0);


    AlarmManager.AlarmClockInfo ac=
            new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + timeEntered,
                    pi2);

    manager.setAlarmClock(ac, pi);


}

переменная timecommenced, которая у меня есть в моих параметрах setExact (), правильно отлаживает, в какое время она должна активировать тревогу.

Затем внутри моего широковещательного приемника я пытаюсь передать это значение и добавить интервал, введенный пользователем, который сохранит время срабатывания сигнала тревоги. например 2.45, затем 3.05.

По какой-то причине я нажимаю «Обработка начата» вместо того, чтобы звучать тревожный сигнал, когда timecommenced сообщает, что он срабатывает сразу. Затем, после этого тайминги будильника полностью отключены, и он имеет собственное мнение.

Может ли кто-нибудь увидеть, что я делаю неправильно, или дать мне совет?

Спасибо!

setExact не работает, как следует из названия, на Android 6+ [API 21+]. Будет действовать ограничение по дозировке ~, когда устройство не заряжается и экран выключен. Чтобы вызвать надежную тревогу пользователя, следует использовать метод «setAlarmClock» в AlarmManager.

Elletlar 10.05.2018 16:27

Кроме того, сигнал тревоги обычно срабатывает сразу же, когда начальное время находится в прошлом. Из кода я думаю, вы уже знаете, что RTC_WAKEUP основан на System.currentTimeMillis (). Этот инструмент Конвертер EPOCH полезен для перевода времени из миллисекунд в человеческое время.

Elletlar 10.05.2018 16:37

@Elletlar, спасибо за ответ, хорошо, я могу попробовать метод setAlarmClock? а также правильно ли я кодирую "повтор" в приемнике вещания? еще раз спасибо

TheAlmac2 10.05.2018 17:17

Для устройств Android 5 и ниже необходимо использовать setExact. Для Android 6 и выше следует использовать setAlarmClock. Таким образом, вам, вероятно, потребуется реализовать оба варианта, если минимальный API не установлен на 21. Вы проверили время повтора в конвертере EPOCH по времени на телефоне?

Elletlar 10.05.2018 17:42

Привет, @Elletlar. Первый сигнал срабатывает, поэтому я проверил его там, и он сработал в 9.07, когда мой чек должен был состояться в 9.12, так что это правильно. Единственное, как я могу повторить это сейчас в приемнике вещания?

TheAlmac2 11.05.2018 10:08

@Elletlar Я обновил код своего широковещательного приемника. Кажется, что всякий раз, когда у меня есть код, чтобы попытаться повторить его, он нарушает начальную тревогу и работает неправильно. Не могли бы вы взглянуть и увидеть, что я делаю не так?

TheAlmac2 11.05.2018 11:39

Создание уникального кода в каждом PendingIntent должно предотвратить замену ваших сигналов тревоги друг на друга. Это исправит?

Elletlar 11.05.2018 12:12

@Elletlar, как я могу это сделать?

TheAlmac2 11.05.2018 12:26

извинения, я только что увидел ваше обновление под @Elletlar. так что скажем, что в моей деятельности мой код запроса тревоги равен 0 в моих ожидающих сообщениях, а в широковещательном приемнике коды запросов равны 1, это должно сработать?

TheAlmac2 11.05.2018 12:35

Извините, у меня не было времени запустить ваш код, но это должно помочь ...

Elletlar 11.05.2018 12:43

Я думаю, это сработало !! @Elletlar большое спасибо

TheAlmac2 11.05.2018 13:04

Np. Большой! :) :) :)

Elletlar 11.05.2018 13:26
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
12
218
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

setExact не работает, как следует из названия, на Android 6+ [API 21+]. Ограничения по дозировке будут действовать примерно тогда, когда устройство не заряжается и экран выключен. [Примечание: проблема стоит более остро, начиная с Android 7, поскольку он имеет гораздо более агрессивную форму Doze]

Чтобы вызвать надежную тревогу пользователя, следует использовать метод «setAlarmClock» в AlarmManager.

AlarmManager am =
  (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, myReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
Intent intent2 = new Intent(context, myActivity.class);
PendingIntent pi2 = PendingIntent.getActivity(context, 0, i2, 0);

AlarmManager.AlarmClockInfo ac=
  new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + DELAY,
    pi2);

am.setAlarmClock(ac, pi);

Из документов:

setAlarmClock добавлен в API уровня 21

void setAlarmClock (AlarmManager.AlarmClockInfo info, 
            PendingIntent operation)

Запланируйте будильник, который представляет собой будильник, который будет использоваться для уведомления пользователя, когда он сработает. Ожидается, что при срабатывании этого сигнала тревоги приложение разбудит устройство, чтобы сообщить пользователю о тревоге - включении экрана, воспроизведении звука, вибрации и т. д. Таким образом, система обычно также будет использовать эту информацию. поставляется здесь, чтобы сообщить пользователю о предстоящем сигнале тревоги, если это необходимо.

Из-за природы этого типа сигналов тревоги, аналогичных setExactAndAllowWhileIdle (int, long, PendingIntent), эти сигналы тревоги могут срабатывать, даже если система находится в режиме ожидания с низким энергопотреблением (он же дремота).

Документы диспетчера аварийных сигналов

Чтобы установить более 1 будильника, присвойте каждому уникальный 'requestCode' в PendingIntent:

 static PendingIntent   getBroadcast(Context context, int requestCode, Intent intent, int flags)

Я попробую! Это повторяется?

TheAlmac2 10.05.2018 17:28

У меня это работало какое-то время, затем, когда я пошел на демонстрацию, это вообще не сработало. (Стандарт для демонстраций) Мне просто интересно, знаете ли вы, почему, или испытали это?

TheAlmac2 08.06.2018 11:27

Другие вопросы по теме