2015-03-19 2 views
0

У меня есть приложение, которое отправляет еженедельное уведомление. Он должен выстрелить в 8:15 в четверг утром; однако на этой неделе я получил обновление только после перезагрузки моего телефона (после 8:15 утра). Тревога установлена ​​в MainActivity в первом запуске, и я реализовал BootReceiver, чтобы сброс тревоги был сброшен, если пользователь отключил свой телефон. Кто-нибудь знает, есть ли у меня логическая ошибка где-то, что я пропустил?AlarmManager только при перезапуске устройства

Редактировать: Таким образом, он запускается с каждым перезапуском. Как я могу это исправить? Способ работы уведомлений делает большую проблему отправкой уведомлений при каждом перезапуске (он увеличивает значение точки, используемое для выплаты вознаграждений).

Вот часть кода из MainActivity:

public void manageNotifications() { 
    calendar.setTimeInMillis(System.currentTimeMillis()); 
    calendar.set(java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.THURSDAY); 
    calendar.set(java.util.Calendar.HOUR_OF_DAY, 8); 
    calendar.set(java.util.Calendar.MINUTE, 15); 

    /* 
    sets alarm manager to go off at 8:15 in the morning every 7 days on Thursday 
    */ 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24 * 7, pendingIntent); 
}//end manageNotifications 

Вот мой BootReceiver класс:

public class BootReceiver extends BroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
    if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) { 
     java.util.Calendar calendar = java.util.Calendar.getInstance(); 
     AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
     Intent alarmIntent = new Intent(context, AlarmReceiver.class); 
     PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT); 

     calendar.setTimeInMillis(System.currentTimeMillis()); 
     calendar.set(java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.THURSDAY); 
     calendar.set(java.util.Calendar.HOUR_OF_DAY, 8); 
     calendar.set(java.util.Calendar.MINUTE, 15); 

    /* 
    sets alarm manager to go off at 8:15 in the morning every 7 days on Thursday 
    */ 
     alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24 * 7, pendingIntent); 
    } 
} 

}

И вот код AlarmReceiver, который вызывается из обоих BootReceiver и MainActivity на первый пробег:

public class AlarmReceiver extends BroadcastReceiver { 

NotificationCompat.Builder notificationBuilder; 
Intent notificationResultIntent; 
ArrayList<Show> shows; 
SharedPreferences spSpreadsheets, spNotifications; 
final String showSpreadsheetURL = "https://docs.google.com/spreadsheets/d/1Ax2-gUY33i_pRHZIwR8AULy6-nbnAbM8Qm5-CGISevc/gviz/tq"; 

public void onReceive(Context context, Intent intent) { 
    System.out.println("AlarmReceiver created"); 
    spNotifications = context.getSharedPreferences("notificationToggle", Context.MODE_PRIVATE); 
    spSpreadsheets = context.getSharedPreferences("spreadsheets", Context.MODE_PRIVATE); 

    if (spNotifications.getBoolean("notifications", false)) { 
     int nextRegularShowIndex = 0, i = 0; 

     shows = new ArrayList<>(); 

     try { 
      if (spSpreadsheets.getString("showsSpreadsheet", "").equals("")) 
       getShows(context); 
      shows = processShowsJson(new JSONObject(spSpreadsheets.getString("showsSpreadsheet", ""))); 

      while (shows.get(i).getShowTime() != 0) { 
      /* 
      checks for first instance of a regular showtime 
      */ 
       i++; 
       nextRegularShowIndex = i; 
      } 
      checkForPastShows(); 
      notificationBuilder = new NotificationCompat.Builder(context) 
        .setSmallIcon(R.drawable.applogo) 
        .setContentTitle("Comedy Club of Jacksonville") 
        .setContentText(shows.get(nextRegularShowIndex).getComedian() + " headlines this weekend at the Comedy " + 
          "Club of Jacksonville. Click to read more.") 
        .setDefaults(Notification.DEFAULT_ALL); 
      notificationResultIntent = new Intent(context, ThisWeekendFromNotification.class).putParcelableArrayListExtra("shows", shows); 

      TaskStackBuilder stackBuilder = TaskStackBuilder.create(context); 
      stackBuilder.addParentStack(ThisWeekend.class); 
      stackBuilder.addNextIntent(notificationResultIntent); 
      PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 
      notificationBuilder.setContentIntent(resultPendingIntent); 
      notificationBuilder.setAutoCancel(true); 
      NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
      mNotificationManager.notify(0, notificationBuilder.build()); 
      System.out.println("Notification built"); 

     } catch (Exception e) { 
      e.printStackTrace(); 
     }//end onReceive 
    } 
} 
+0

Используйте ** 'adb shell dumpsys alarm' **, чтобы подтвердить, что будильник установлен как ожидалось. Используйте «Log» вызовы или контрольные точки отладчика, чтобы определить, что из вашего кода выполняется. – CommonsWare

ответ

0

Вслед за моим комментарием reddit: Это определенно похоже, что вы устанавливаете будильник в прошлом. Атрибуты Calendar немного странные.

calendar.setTimeInMillis(System.currentTimeMillis()); 
    calendar.set(java.util.Calendar.DAY_OF_WEEK, java.util.Calendar.THURSDAY); 
    calendar.set(java.util.Calendar.HOUR_OF_DAY, 8); 
    calendar.set(java.util.Calendar.MINUTE, 15); 

Этот код будет установлен календарь будет четверг в 8:15 утра текущей недели. Поэтому, если пользователь перезапустит свой телефон в пятницу утром, на этот раз будет указывать на предыдущий четверг утром. Это заставит AlarmManager немедленно вызвать вашу тревогу за Документы для setRepeating() здесь: https://developer.android.com/reference/android/app/AlarmManager.html

Если заявленное время срабатывания в прошлом, сигнализация срабатывает немедленно, с подсчетом тревоги в зависимости от того, как далеко в прошлое времени срабатывания относительно интервала повторения.

EDIT - следующий на ваш комментарий о том, как исправить:

Быстрый и грязный способ был бы что-то вроде этого

long alarmTime = calendar.getTimeInMillis(); 
if (alarmTime < System.currentTimeMillis()) { 
    alarmTime += DateUtils.WEEK_IN_MILLIS; 
} 

alarmManager.set(... alarmTime ...); 

Я ненавидела, услышав это, задавая вопросы Java Calendar api, но, используя библиотеку Joda-Time (или в вашем случае Joda-Time Android), вы сэкономите много боли в долгосрочной перспективе. С apis гораздо яснее и проще работать.

+0

Это имеет смысл, спасибо за продолжение. Итак, чтобы исправить это, мне нужно запланировать будильник в следующий четверг в BootReceiver? Как и в setTimeInMillis (System.currentTimeInMillis() + 1000 * 60 * 60 * 24 * 7); ? –

Смежные вопросы