PendingIntent с IntentService не работает - PullRequest
0 голосов
/ 03 мая 2018

Следующий код отлично работает для Activity:

Intent intent = new Intent(context, MyActivity.class);
PendingIntent operation = PendingIntent.getActivity(context, 
                              0, 
                              intent, 
                              PendingIntent.FLAG_UPDATE_CURRENT);
alarmmanager.setExact(AlarmManager.RTC_WAKEUP, 
                              startTime.getTimeInMillis(),
                              operation);

Однако, когда я делаю то же самое для IntentService, это работает, только если startTime и время, когда я установил будильник, находятся в один и тот же день. например Если я установил будильник сегодня на 5 часов вечера, он будет выполнен, но когда я установил будильник сегодня на 5 часов вечера завтра, он не будет выполнен. Если это было Activity, то это работает для обоих случаев.

Intent intent = new Intent(context, MyService.class);
PendingIntent operation = PendingIntent.getService(context, 
                              0, 
                              intent, 
                              PendingIntent.FLAG_UPDATE_CURRENT);
alarmmanager.setExact(AlarmManager.RTC_WAKEUP, 
                              startTime.getTimeInMillis(),
                              operation);

Как это решить?

Цель, которую я пытаюсь достичь, состоит в том, чтобы выполнять IntentService каждый день в точное время.

Ответы [ 4 ]

0 голосов
/ 04 мая 2018

Цель, которую я пытаюсь достичь, - запускать IntentService каждый день в точное время.

Google делает это все сложнее от релиза к релизу. См. Android AlarmManager setExact () не является точным . Для вашего случая это может быть два способа:

  1. вы запускаете действие, которое запускает службу (поскольку запуск действия, кажется, работает для вас)
  2. вы используете либо setExactAnd..., либо setAlarmClock. setAlarmClock также запускается в новом режиме «дремания», см. https://stackoverflow.com/a/47049705/1587329.

Другим способом было бы переосмыслить, почему и если вам это действительно нужно ... или если JobScheduler не может более соответствовать вашим целям.

0 голосов
/ 03 мая 2018

ЗДЕСЬ ПОДРОБНЫЙ ОТВЕТ проверьте ссылку внизу для более подробной информации. Надеюсь, это поможет. Возможно, ваша проблема связана с версиями для Android, поэтому проверьте ссылку для получения более подробной информации

Приложение

получает экземпляр AlarmManager и устанавливает сигнал тревоги, используя PendingIntent. Подробнее об использовании и настройке будильника будет рассказано в следующем разделе. AlarmManager является интерфейсом на стороне приложения для поддержки AlarmManagerService. Он абстрагирует детали интерфейса Binder, используемого для связи с системным процессом (system_server), на котором размещается AlarmManagerService. Эти два компонента управляют сигнализацией, установленной приложением, и будут правильно отправлять PendingIntent. Эта архитектура диспетчера / службы используется во всей платформе Android и предназначена для обеспечения безопасности и изоляции. Процесс system_server выполняется с привилегиями, которых нет у обычных приложений. Если вы не знакомы с использованием разрешений Android, см. Эту статью для получения дополнительной информации о процессах приложения и идентификаторах пользователей. Эти дополнительные разрешения - то, что позволяет system_server получать доступ к базовому драйверу тревоги ядра. Драйвер аварийных сигналов - это то, что управляет настройкой аварийных сигналов для пробуждения устройства независимо от состояния сна SoC.

Когда срабатывает сигнал тревоги, устройство пробуждается (если оно спит), и AlarmManagerService получает уведомление об истечении срока действия сигнала тревоги. Затем он отправит PendingIntent соответственно. Это приведет к активации соответствующего компонента в MyApp. Если MyApp не был запущен или его процесс не кэширован, он будет запущен, поэтому компонент можно будет активировать.

основное использование будет как

public class MyActivity extends Activity {
...
private AlarmManager  mAlarmMgr;
...
public void onCreate(Bundle savedInstance) {
    ...
    mAlarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    ...
}
...


}

Давайте создадим PendingIntent для нашей MyActivity, используя имя компонента .

Intent alarmIntent = new Intent(context, MyActivity.class);
PendingIntent pend = PendingIntent.getActivity(context,
                              0,
                              alarmIntent,
                              PendingIntent.FLAG_UPDATE_CURRENT);

Теперь, когда у нас есть PendingIntent и AlarmManager, мы можем установить нашу тревогу так, чтобы наша Активность запускалась, когда истекла тревога. Для этого нам нужно выяснить, когда мы хотим, чтобы сработала наша сигнализация, и должен ли он разбудить устройство или просто быть доставленным при следующем пробуждении устройства. Помните, у нас есть два разных способа указания времени для наших будильников: прошедшее время или время по календарному времени (RTC). Таким образом, наши варианты - ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC или RTC_WAKEUP. Варианты _WAKEUP - это наши «агрессивные» сигналы тревоги, когда мы хотим, чтобы устройство выходило из режима пониженного энергопотребления, чтобы перезвонить нашему приложению. Для нашего примера приложения, давайте настроим это в пользовательском BroadcastReceiver и заставим его активировать нашу активность примерно через 30 секунд после загрузки устройства

public class MyBootReceiver extends BroadcastReceiver {
public void onReceive(Context, context, Intent intent) {
    ...
    AlarmManager alarmMgr =
        (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    long wakeTime = SystemClock.elapsedRealtime() + 30000;
    alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeTime, pend);
}
}

Теперь, когда наше устройство загружается и отправляется широковещательная рассылка BOOT_COMPLETED, процесс нашего приложения будет запущен, и наш получатель установит будильник, чтобы активировать нашу активность через 30 секунд. Обратите внимание, что на устройствах Android 3.1 или более поздней версии вы должны сначала вручную запустить свое приложение до BOOT_COMPLETED.

КРЕДИТ ИДЕТ к автору этого БЛОГ

Если вы хотите установить повторную тревогу с помощью SetExact, вы обязаны остановить все остальные ожидающие намерения в одно и то же время, проверьте эту ссылку , для этого здесь много примеров, как это сделать! снова заслуга этого автора

0 голосов
/ 03 мая 2018

Замените AlarmManager на этот код:

alarmManager.setRepeating(AlarmManager.RTC, 
                          timeMills, 
                          AlarmManager.INTERVAL_DAY, 
                          pendingIntent);

работал для меня.

0 голосов
/ 03 мая 2018

добавить заменить вашу строку этой строкой:

alarmmanager.setRepeating(AlarmManager.RTC_WAKEUP, 
                          startTime.getTimeInMillis(),
                          operation);

будет повторяться через определенный интервал, установленный в диспетчере аварийных сигналов

...