Как создать постоянный AlarmManager

Изменить: Уточненный вопрос, основанный на ответе CommonsWare

Мы планируем будильник через AlarmManager запускать каждые 60 секунд. Когда наше приложение убито, наши тревоги, похоже, больше не выполняются. Есть ли способ, чтобы эти аварийные сигналы сохранялись, даже когда приложение было убито вручную или системой?

Это проблема для нас, потому что у нас есть приложение виджета, которое отображает время. Это означает, что нам нужно обновлять время каждую минуту. Чтобы обойти 30-минутное ограничение на обновление метода onUpdate для AppWidgetProvider, мы используем AlarmManager. Обычно это работает очень хорошо, но некоторые пользователи сообщают о времени выхода из синхронизации. Поговорив с несколькими из них, мое подозрение в том, что наше приложение убивается вручную с помощью приложения-убийцы задач или Android сам по себе убивает наше приложение.

Также приветствуются любые другие альтернативные решения проблемы с корнем (поддерживающие синхронизацию времени в виджетах).

Вот код, который мы выполняем, чтобы запланировать нашу тревогу:

Intent intent = new Intent(UPDATE_TIME); PendingIntent pIntent = PendingIntent.getBroadcast(ctx, 0 /* no requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT ); // get alarm params Date d = new Date(); long timeTilMinuteChange = 60*1000-d.getSeconds()*1000; long startTime = System.currentTimeMillis() + + timeTilMinuteChange; AlarmManager am = (AlarmManager) ctx.getSystemService(Context. am.cancel(pIntent); am.set(AlarmManager.RTC, System.currentTimeMillis(), pIntent); am.setRepeating(AlarmManager.RTC, startTime, 60000, pIntent); 

Всякий раз, когда наше приложение убивается, AlarmManager также убивается.

AlarmManager не убит. Однако ваш будильник отменяется. Если пользователь останавливает или останавливает выполнение задачи, ваши аварийные сигналы незапланированы. На Android 3.1+, если пользователь принудительно останавливает вас, ничто из вашего кода не запустится до тех пор, пока пользователь не запускает одно из ваших действий вручную.

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

В идеале, ваше приложение не должно быть написано таким образом, что у Android будет какая-то причина, чтобы избавиться от вас. Для чего-то вроде того, что вы описываете, вы должны либо использовать getBroadcast() PendingIntent указывающий на зарегистрированный манифеста BroadcastReceiver , либо вы должны использовать getService() PendingIntent указывающий на IntentService . В любом случае ваш код будет работать ненадолго, и тогда ваш процесс будет иметь право на восстановление на Android без проблем, если возникнет такая необходимость.

Убийцы задач, будь то ручные или автоматические, кажутся гораздо более вероятными виновниками аварийных сигналов, отмененных, ИМХО.

О диспетчере аварий в Документах – объяснение несколько сбивает с толку, и я честно все еще не понимаю его полностью. У меня есть этот бит кода для части виджета, который решил проблему в моем случае.

 package com.test.mytestwidget; import java.util.Calendar; import android.app.AlarmManager; import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.content.Intent; public class MyWidgetProvider extends AppWidgetProvider { private PendingIntent service = null; public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); final Calendar TIME = Calendar.getInstance(); TIME.set(Calendar.MINUTE, 0); TIME.set(Calendar.SECOND, 0); TIME.set(Calendar.MILLISECOND, 0); final Intent i = new Intent(context, UpdateWidgetService.class); if (service == null) { service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); } m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 30000, service); } @Override public void onDisabled(Context context) { final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); m.cancel(service); super.onDisabled(context); } }