Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
#1

Alarm broadcastIntent убивается через какое-то время - Программирование Android

16.01.2015, 09:47. Просмотров 801. Ответов 18
Метки нет (Все метки)

Привет! Я разрабатываю приложение похожее на будильник. Я использую Android 4.2.2.

Проблема заключается в том, что после некоторого времени (около 1 - 2 часов) alarm pendingIntent убивается кем-то и будильник не срабатывает.

Последовательность шагов следующая
1. Вызов SetAlarm() и установка на срабатывание через 2 часа.
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intentToFire, 0); alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, alarmIntent);
2. Я вижу, что Alarm установлен через "adb shell dumpsys alarm". +1h59m осталось
3. После 10 минут... я вижу, что Alarm установлен через "adb shell dumpsys alarm".+1h49m осталось
4. После 20 минут... я вижу, что Alarm установлен через "adb shell dumpsys alarm".+1h39m осталось
5. И так далее...
6. Но после гле-то 1-2 часов (время варьируется) Oooops. Я больше не вижу alarm pendingIntent в списке "adb shell dumpsys alarm".

Android родной будильник работает нормально.

Код:
Broadcast Receiver, зарегистрированный в AndroidManifest.xml

XML
1
2
3
4
5
6
7
8
9
10
    <receiver android:name=".BrdRcvr" android:exported="true">
        <intent-filter>        
            <action android:name="action.alarm.RI" />
            <action android:name="action.alarm.ERT0" />
            <action android:name="action.alarm.ERT1" />
            <action android:name="action.alarm.ERT2" />
            <action android:name="action.alarm.ERT3" />
            <action android:name="action.alarm.ERT4" />
        </intent-filter>
    </receiver>
Функция установки Alarm'а:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static void setAlarmRI(Context context) {
    //Read time from preferences
    SharedPreferences appPref = 
            context.getSharedPreferences(SettingsActivity.APP_PREF, Context.MODE_PRIVATE);
 
    int timeToAlarmMs = Integer.valueOf(appPref.getInt(SettingsActivity.APP_PREF_RI, 0)) * 1000; //[ms]
 
    //!getSystemService must be called after onCreate() 
    AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    long time = SystemClock.elapsedRealtime() + timeToAlarmMs * 60; //[min]
 
    //Intent
    Intent intentToFire = new Intent(context, BrdRcvr.class);
    intentToFire.setAction("action.alarm.RI");
 
    PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 
            0, intentToFire, 0/*flags*/);
 
    if (timeToAlarmMs > 0) {
        //for API >= 19 AlarmManager.set() triggers not at exact time (for battery saving)
        //and we should use AlarmManager.setExact() instead
        if (Build.VERSION.SDK_INT >= 19)
            alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, alarmIntent);
        else
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, time, alarmIntent);
 
        Log.d(ALARMRI, "API:" + Integer.valueOf(Build.VERSION.SDK_INT).toString());
        Log.d(ALARMRI, "set:" + Long.valueOf(time).toString());
        Log.d(ALARMRI, "cur:" + Long.valueOf(SystemClock.elapsedRealtime()).toString());
        Log.d(ALARMRI, "delta:" + (Long.valueOf(time) -
                Long.valueOf(SystemClock.elapsedRealtime())));
    } else {
        alarmManager.cancel(alarmIntent);
        Log.d(ALARMRI, "unset");
    }
}
У кого-нибудь есть идеи в чем может быть проблема?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
16.01.2015, 10:05     Alarm broadcastIntent убивается через какое-то время #2
Ну...вы сами через set сказали ему отработать и убиться ...

triggerAtMillis time in milliseconds that the alarm should go off, using the appropriate clock (depending on the alarm type).
operation Action to perform when the alarm goes off; typically comes from IntentSender.getBroadcast().
Хотите его лицезреть - используйте setRepeating
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
16.01.2015, 12:25  [ТС]     Alarm broadcastIntent убивается через какое-то время #3
Этот alarm я переустанавливаю, когда он сработает. Проблема в том, что он даже однократно не срабатывает при периоде в 2 часа.

Если установить период в 5 - ~30 минут он срабатывает. Если установить период в 2 часа, то где-то через ~1 час он исчезает из списка "adb shell dumpsys alarm". Такое чувство, что его кто-то убивает (система или какая-то программа оптимизации или еще что-то).
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
16.01.2015, 13:04     Alarm broadcastIntent убивается через какое-то время #4
Тогда непонятно.
Возможно его и вправду система убивает "on low memory".

Я бы ради интереса врубил еще один AlarmManager на каждую минуту, например, который бы смотрел "висит" ли или нет твой PendingIntent alarmIntent и писал бы в лог состояние.
Так увидишь когда он пропадет.

А может они и оба пропадут до того
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
16.01.2015, 14:36  [ТС]     Alarm broadcastIntent убивается через какое-то время #5
Боюсь это не даст мне никакой полезной информации о причине пропадания alarm'а.

Я уже испытывал так: запускал 5 алармов на точное время срабатывания (скажем на 9:00, 12:00 и т. д.) и один аларм с периодом повторения 30 минут. Каждый из этих алармов переустанавливает сам себя после приема Broadcast Intent.

Результат такой, что все работало хорошо. Аларм с периодом в 30 минут срабатывал, алармы на точно время срабатывания (9:00, 12:00 и т. д.) тоже срабатывали. Однако, где-то через 5 часов (каждый раз по-разному) все алармы неожиданно и беспричинно пропали.
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
16.01.2015, 15:00     Alarm broadcastIntent убивается через какое-то время #6
Запустите на другом девайсе
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
16.01.2015, 15:24  [ТС]     Alarm broadcastIntent убивается через какое-то время #7
Я тестировал на Huawei Y330 (Android 4.2.2) и Huawei Ascend P1 (Android 4.0)

Но родной андроидовский будильник com.android.deskclock работает исправно! Я его вижу в списке "adb shell dumpsys alarm". Он регистрирует себя как RTC_WAKEUP.

Я регистрирую свой аларм как ELAPSED_WAKEUP.
androbro
323 / 283 / 59
Регистрация: 17.10.2014
Сообщений: 836
16.01.2015, 16:08     Alarm broadcastIntent убивается через какое-то время #8
Giekelberri, попробуйте на эмуляторе) или на устройстве без всяких там программ "оптимизаций"
Tester64
395 / 356 / 43
Регистрация: 22.05.2013
Сообщений: 2,518
18.01.2015, 21:27     Alarm broadcastIntent убивается через какое-то время #9
Сам замечал подобное при работе с алармами.
До сих пор надежности не добился!

Кому-нибудь удавалось надежности добиться?
Что лучше для будильника? один аларм на программу каждые 5 минут с проверкой или десяток на каждый день месяца?
Стоит ли делать несколько алармов перезапускающих друг-дружку?
Заметил что гугл наплодил больше 20 алармов.
Спасибо за команду "adb shell dumpsys alarm" - не знал чем подобное мониторить. Правда не удобный список получается - слишком много пустых строк(всего 729 строк получилось), нет фильтра по классам (например только свои ищу) - может можно упростить поиск? Пока пишу в текстовый файл и ищу поиском нужное.
Еще, может кому поможет, взаимный перезапуск двух частых алармов приводил к резкому увеличению сьедаемой памяти. И при очень частом срабатывании (3-5 раз в секунду с вызовом бродкаста) вызывал перезапуск мобилки через 1.5-2.5 часа. Алармы при этом часто умирали.
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
19.01.2015, 12:47  [ТС]     Alarm broadcastIntent убивается через какое-то время #10
2 androbro: эту неделю попробую на эмуляторе и других устройствах.

2 Tester64:
1) Чтобы параметризовать вывод adb можно, например, ввести в командной строке:
adb shell dumpsys alarm | fgrep my_alarm_name

2) Я рассматривал вариант запустить аларм с интервалом 5 минут, который бы проверял запущен ли другой аларм. Но, согласитесь, это неправильно. Так не должно быть. Если я установил аларм на срабатывание через 2 часа, то он должен сработать. Тем более, что родной аларм com.android.deskclock работает исправно.
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
19.01.2015, 13:09     Alarm broadcastIntent убивается через какое-то время #11
Цитата Сообщение от Giekelberri Посмотреть сообщение
2) Я рассматривал вариант запустить аларм с интервалом 5 минут, который бы проверял запущен ли другой аларм.
К сожалению, я думаю, что такой возможности нет.
Я вверху погорячился с этим.
Поверить есть или нет можно только соответствующий PendingIntent, но это не дает ровным счётом ничего.
Вот давеча, установил прверку по PendingIntent для 5-ти минутного аларма.
Аларм издох, а PendingIntent под него еще прекрасно себя чувствовал часа 3, пока до него не добрался мусорщик, я так думаю.

Вообще, какой-то этот AlarmManager недоделанный, в смысле "пришибленный".

Почему у AlarmManager нет события аналогичного onDestroy у Service?

Даже наследуемый от Object и ограниченный в своём применении finalize вы не сможете переопределить (если сможете - скажите как )

Я тут думал скрестить как-то AlarmManager и Service, породив монстра, который бы при убиении возвопил "Я умираю" и испустил onDestroy()...но не смог...
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
19.01.2015, 13:13     Alarm broadcastIntent убивается через какое-то время #12
smail00, пашоль вон
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
19.01.2015, 13:20  [ТС]     Alarm broadcastIntent убивается через какое-то время #13
2 Armagedo:
1) Да, да, да. Возможности проверить установлен ли Alarm нет. Я имел ввиду, что каждые 5 минут переустанавливать долгосрочный Alarm заново. Ведь если установить Alarm, который был установлен до этого, он просто перезаписывается.

Сейчас тестирую на эмуляторе... о результатах отпишу завтра.
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
19.01.2015, 13:29     Alarm broadcastIntent убивается через какое-то время #14
Giekelberri, а сервис+таймер не тестировали для своих целей?

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

Добавлено через 2 минуты
Кстати, все везде аппелируют к встроенным будильникам и прочим гуглам.
F они точно знают, что при реализации сих зверей использовался AlarmManager?
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
19.01.2015, 13:41  [ТС]     Alarm broadcastIntent убивается через какое-то время #15
2 Armagedo:
1) "сервис + таймер" насколько я понимаю по-прожорливей в плане ресурсов будет. Поэтому не хочу.
2) Пытался найти исходный код родного андроидовского будильника - пока не нашел. Но вот что странно: есть такое разрешение com.android.alarm.permission.SET_ALARM, которое логично было бы надо указать в AndroidManifest.xml. Но оно никак не влияет на работу alarm. И в документации на alarmManager про это разрешение ничего не сказано.
Armagedo
208 / 208 / 60
Регистрация: 22.08.2014
Сообщений: 644
19.01.2015, 13:46     Alarm broadcastIntent убивается через какое-то время #16
Цитата Сообщение от Giekelberri Посмотреть сообщение
насколько я понимаю
интересно узнать

Добавлено через 1 минуту
Цитата Сообщение от Giekelberri Посмотреть сообщение
есть такое разрешение com.android.alarm.permission.SET_ALARM
http://developer.android.com/referen...larmClock.html
Spelcrawler
526 / 496 / 111
Регистрация: 12.03.2014
Сообщений: 1,648
Завершенные тесты: 1
19.01.2015, 13:46     Alarm broadcastIntent убивается через какое-то время #17
Цитата Сообщение от Giekelberri Посмотреть сообщение
Но вот что странно: есть такое разрешение com.android.alarm.permission.SET_ALARM
Это для установки системного будильника. У меня сам аларм отрабатывает хорошо, но есть проблема: аларм запускает сервис, и через некоторое время (когда приложение выгружается из памяти) сервис запускается, но у него интент=null. Как это возможно и как это поправить?
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
19.01.2015, 14:21  [ТС]     Alarm broadcastIntent убивается через какое-то время #18
2 Armagedo:
Цитата Сообщение от Armagedo Посмотреть сообщение
интересно узнать
читаю Meier R. - "Professional Android 4 Application Development"
с. 342. Timer is generally poor form.
с. 351. Unlike Timers, Alarms operated outside the scope of your application...
Alarms are an effective means to reducing your application's resource requierments...

Поэтому мне кажется гораздо проще с Alarm. "Установил и забыл".
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.01.2015, 12:54     Alarm broadcastIntent убивается через какое-то время
Еще ссылки по теме:
Alarm manager не запускается чаще чем раз в час Android
Снова Alarm Manager: как запустить на API выше 19-го? Android
Android Выключение службы через определенное время
Переход между Activity через заданное время. Как лучше? Android
Процесс не убивается ни через cmd, ни через Process Explorer Windows 7

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Giekelberri
0 / 0 / 0
Регистрация: 16.01.2015
Сообщений: 9
23.01.2015, 12:54  [ТС]     Alarm broadcastIntent убивается через какое-то время #19
Резюме по тестированию.

1) В эмуляторе. Тестировал 12 часов. Работает.

2) На устройстве Huawei Y330 (Android 4.2.2) Alarm поработал ~24 часа, затем отрубился.

Вобщем, мало что изменилось - Alarm уничтожается в непредвиденный момент непонятно кем.
Yandex
Объявления
23.01.2015, 12:54     Alarm broadcastIntent убивается через какое-то время
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru