2015-09-26 3 views
-1

Я использую андроид-студию для разработки приложения, которое будет извлекать информацию о времени из базы данных и будет устанавливать будильник, чтобы побудить пользователя, что пришло время выпить лекарство, моя проблема в том, что будильник слишком раноAndroid Alarms слишком рано

, например, извлеченный время 12:50 АМ и текущее время 12:40 утра несмотря на то, что есть разница в 10 минут сигнал гаснет сразу

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm"); 
try { 
     Calendar Cnow = Calendar.getInstance(); 
     long now=Cnow.getTimeInMillis(); 
     Calendar time=Calendar.getInstance(); 
     time.setTimeInMillis(0); 
     Date dTime=sdf.parse(strAlarmDate + " " + strTime1); 
//example strAlarmDate="2015-09-27" and strTime1="12:50 AM" and now="12:40 AM" in millis 
//dTime="...... 2015-09-27 00:50" 
     time.setTime(dTime); 
     //Date dNow=now.getTime(); 
     //time.setTime(date); 
     //long trigger=time.getTimeInMillis()-now.getTimeInMillis(); 
     long trigger=time.getTimeInMillis()-now; 
     if(trigger>0) { 
      ctr++; 
      Intent i = new Intent(Login.this, AlarmReceiver.class); 
      i.putExtra("message", strMedname); 
      i.putExtra("line", strLine); 
      final int _id = (int) System.currentTimeMillis(); 
      PendingIntent pi = PendingIntent.getActivity(Login.this, _id, i, 0); 
      AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); 
//   am.set(AlarmManager.RTC_WAKEUP, trigger, pi); 
//   am.setExact(AlarmManager.RTC_WAKEUP, trigger, pi); 
      am.set(AlarmManager.RTC_WAKEUP, trigger, pi); 
     } 
    }catch(ParseException ex) 
    { 
      ex.printStackTrace(); 
    } 

ответ

1

проблема заключается в том чтобы вы отключили будильник в момент времени trigger, который является минусом текущего времени.

Вместо этого вы должны принять time.getTimeInMillis().

Так замените строку с

am.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi); 
    } 
0

Из официального docs:

Примечание: Начиная с API 19 (KITKAT) доставка сигнала тревоги неточна: операционная система будет смещаться сигналы для того, чтобы свести к минимуму пробуждения и использования батареи. Существуют новые API-интерфейсы для поддержки приложений, требующих строгих гарантий доставки; см. setWindow (int, long, long, PendingIntent) и setExact (int, long, PendingIntent). Приложения, чья targetSdkVersion ранее, чем API 19, будут продолжать видеть предыдущее поведение, при котором все аварийные сигналы доставляются точно по запросу.

0

Bas van Stein является правильным. AlarmManager использует абсолютное время: миллисекунды с эпохи, 1 января 1970 года. Вы пытаетесь установить его в относительное время: миллисекунды с момента установки будильника. AlarmManager интерпретирует это как некоторое время, очень близкое к эпохе, около 1 января 1970 года, в 12:10. Поскольку это время давно прошло, тревога срабатывает немедленно.

Решение заключается в использовании time.getTimeInMillis() в set вместо trigger.

Некоторые другие ноты для ведения такого рода работы, так как ваше приложение похоже на намерении шахты:

  • Большинство тревог начиная с API 19 будет неточным, так как Франк Н. Штейн указал. Степень этой неточности зависит от реализации, а также от того, как далеко в будущем создается тревога. Для чего-то вроде медицины, которая, вероятно, по крайней мере ежедневно, во всех моих тестах будильник срабатывал в течение минуты предполагаемого времени.

  • Вы используете текущее время как requestCode в своем PendingIntent. Установив это на число, имеющее смысл для вашей программы и сохраняющее это значение, вы можете позже обновить или отменить этот сигнал, воссоздав тот же самый PendingIntent.

  • С уровня API 23 и вперед, экстренные сигналы тревоги, такие как аварийные сигналы от лекарств, должны использоваться setAndAllowWhileIdle(), чтобы обеспечить их предупреждение при низких состояниях бездействия. Я еще не знаю, достаточно ли использовать set с RTC_WAKEUP, чтобы обеспечить такое поведение.