2015-10-15 2 views
10

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

Я поместил код, чтобы заблокировать будильник в выходные дни в AlarmReceiver.java.

  1. Я не уверен, что AlarmReceiver.java является правильным местом для размещения кода, который блокирует сигналы тревоги в выходные дни.
  2. Я не уверен, что код, который я использую, чтобы заблокировать будильник по выходным дням, верен. В основном я говорю AlarmReceiver ничего не делать, если сегодня суббота или воскресенье. Иначе, сработайте будильник.

AlarmActivity.java код, который устанавливает тревогу:

//Set a one time alarm 
      if (repeatInterval == 0) { 
        alarmManager.set(AlarmManager.RTC, alarmTime.getTimeInMillis(), pendingIntent); 
        AlarmReceiver alarmReceiver = new AlarmReceiver(this); //http://stackoverflow.com/questions/16678763/the-method-getapplicationcontext-is-undefined 

        Toast.makeText(AlarmActivity.this, "Your one time reminder is now set for " + hourSet + ":" + minuteSetString + amPmlabel, Toast 
          .LENGTH_LONG) 
          .show(); 
      } 

      //Set a repeating alarm 
      else { 
       alarmManager.setRepeating(AlarmManager.RTC, alarmTime.getTimeInMillis(), repeatIntervalMilliseconds, pendingIntent); 
       AlarmReceiver alarmReceiver = new AlarmReceiver(this); //http://stackoverflow.com/questions/16678763/the-method-getapplicationcontext-is-undefined 

        Toast.makeText(AlarmActivity.this, "Your reminder is now set for " + hourSet + ":" + minuteSetString + amPmlabel + " and will " + 
          "repeat " + 
          "every " + 
          repeatInterval + " minutes.", Toast.LENGTH_LONG).show(); 
     } 

AlarmService.Java:

package com.joshbgold.move.backend; 

import android.app.IntentService; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.support.v4.app.NotificationCompat; 

import com.joshbgold.move.R; 
import com.joshbgold.move.main.AlarmActivity; 

public class AlarmService extends IntentService { 
    private NotificationManager alarmNotificationManager; 

    public AlarmService() { 
     super("AlarmService"); 
    } 

    @Override 
    public void onHandleIntent(Intent intent) { 

      sendNotification("Move reminder"); 

    } 

    private void sendNotification(String msg) { 
     alarmNotificationManager = (NotificationManager) this 
       .getSystemService(Context.NOTIFICATION_SERVICE); 

     PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 
       new Intent(this, AlarmActivity.class), 0); 

     NotificationCompat.Builder alarmNotificationBuilder = new NotificationCompat.Builder(
       this).setContentTitle("Reminder").setSmallIcon(R.mipmap.ic_launcher) 
       .setStyle(new NotificationCompat.BigTextStyle().bigText(msg)) 
       .setContentText(msg); 


     alarmNotificationBuilder.setContentIntent(contentIntent); 
     alarmNotificationManager.notify(1, alarmNotificationBuilder.build()); 
    } 

} 

AlarmReceiver.Java:

package com.joshbgold.move.backend; 

import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.preference.PreferenceManager; 
import android.support.v4.content.WakefulBroadcastReceiver; 

import java.text.SimpleDateFormat; 
import java.util.Calendar; 
import java.util.Date; 

public class AlarmReceiver extends WakefulBroadcastReceiver { 

    Context myContext; 
    public AlarmReceiver(Context context){ 
     myContext = context; 
    } 

    public AlarmReceiver(){ 

    } 

    //get the current day 
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE"); 
    Date date = new Date(); 
    String dayOfTheWeek = simpleDateFormat.format(date); 

    Calendar calendar = Calendar.getInstance(); 
    int currentHour = calendar.HOUR_OF_DAY; 

    boolean noWeekends = true; 
    boolean workHoursOnly = true; 

    @Override 
    public void onReceive(final Context context, Intent intent) { 


     try { //this value could be null if user has not set it... 
      noWeekends = loadPrefs("noWeekends", noWeekends); 
      workHoursOnly = loadPrefs("workHoursOnly", workHoursOnly); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 


     if(dayOfTheWeek == "Saturday" || dayOfTheWeek == "Sunday" && noWeekends == true) { 
      //Alarm is not wanted on the weekend 
      try { 
       wait(1); //waits for one-thousandth of a millisecond 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     else if ((currentHour < 9 || currentHour > 17) && workHoursOnly == true){ 
      //Alarm outside of work hours 
      try { 
       wait(1); //waits for one-thousandth of a millisecond 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     else { 

      Intent myIntent = new Intent(); 
      myIntent.setClassName("com.joshbgold.move", "com.joshbgold.move.main.ReminderActivity"); 
      myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      context.startActivity(myIntent); 
     } 
    } 

    //get prefs 
    private boolean loadPrefs(String key,boolean value) { 
     SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(myContext); 
     boolean data = sharedPreferences.getBoolean(key, value); 
     return data; 
    } 
} 

AlarmReceiver.java (исправленный код)

package com.joshbgold.move.backend; 

import android.content.Context; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.preference.PreferenceManager; 
import android.support.v4.content.WakefulBroadcastReceiver; 
import java.util.Calendar; 

public class AlarmReceiver extends WakefulBroadcastReceiver { 

    Context myContext; 
    public AlarmReceiver(Context context){ 
     myContext = context; 
    } 

    public AlarmReceiver() { 

    } 

    private boolean workHoursOnly = false; 
    private boolean noWeekends = false; 

    @Override 
    public void onReceive(final Context context, Intent intent) { 

     Calendar calendar = Calendar.getInstance(); 
     int currentHour = calendar.get(Calendar.HOUR_OF_DAY); 
     int today = calendar.get(Calendar.DAY_OF_WEEK); 
     boolean isWeekend = (today == Calendar.SUNDAY) || (today == Calendar.SATURDAY); 
     boolean isOutsideWorkHours = (currentHour < 9) || (currentHour > 16); 

     //checkPrefs checks whether a preferences key exists 
     if (checkPrefs("workHoursOnlyKey")){ 
      workHoursOnly = loadPrefs("workHoursOnlyKey", workHoursOnly); 
     } 

     if(checkPrefs("noWeekendsKey")){ 
      noWeekends = loadPrefs("noWeekendsKey", noWeekends); 
     } 

     /* try { //this value could be null if user has not set it... 
      workHoursOnly = loadPrefs("workHoursOnly", workHoursOnly); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     */ 

     /*try { //this value could be null if user has not set it... 
     noWeekends = loadPrefs("noWeekends", noWeekends); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     }*/ 

     if(isWeekend && noWeekends) { 
      //Alarm is not wanted on the weekend 
      try { 
       Thread.sleep(1); //waits for millisecond 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     else if (isOutsideWorkHours && workHoursOnly){ 
      //Alarm not wanted outside of work hours 
      try { 
       Thread.sleep(1); //waits for millisecond 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 

     else { 
      //Alarm is wanted, and should go off 
      Intent myIntent = new Intent(); 
      myIntent.setClassName("com.joshbgold.move", "com.joshbgold.move.main.ReminderActivity"); 
      myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      context.startActivity(myIntent); 
     } 
    } 

    //check if a prefs key exists 
    private boolean checkPrefs(String key){ 
     SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(myContext); 
     boolean exists = sharedPreferences.contains(key); 
     return exists; 
    } 

    //get prefs 
    private boolean loadPrefs(String key,boolean value) { 
     SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(myContext); 
     boolean data = sharedPreferences.getBoolean(key, value); 
     return data; 
    } 
} 
+0

Итого комплектование нита. wait (1) - одна миллисекунда, а не одна тысячная миллисекунды. – dnellis74

+0

Что происходит не так? Проводили ли вы тест в выходные, а будильник был уволен? Вы отлаживали его в выходные и проверяли ценность «dayOfTheWeek», чтобы увидеть, что внутри? Какова ценность repeatIntervalMilliseconds? – Christian

ответ

7

Ваш подход не подходит.Во всяком случае, я предлагаю вам избежать использования жестко закодированных строк для проверки . У вас уже есть Calendar объекта, определенный в коде, просто использовать его:

Calendar calendar = Calendar.getInstance(); 
//.. 
int today = calendar.get(Calendar.DAY_OF_WEEK); 
boolean isWeekend = (today == Calendar.SUNDAY) || (today == Calendar.SATURDAY); 

И обновить свой код соответственно:

//... 
    int today = calendar.get(Calendar.DAY_OF_WEEK); 
    boolean isWeekend = (today == Calendar.SUNDAY) || (today == Calendar.SATURDAY); 
    if(isWeekend && noWeekends == true) { 
     //Alarm is not wanted on the weekend 
     try { 
      Thread.sleep(1); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    //... 
+0

Я успешно могу запустить запрос тревоги, а затем отфильтровать запрос в AlarmReceiver сейчас, используя в значительной степени код, который вы разместили выше. Я изменил метод wait() на Thread.sleep из-за ошибки «IllegalMonitorStateException: объект не заблокирован потоком до ожидания()». Я установил манекен, если условие для тестирования, так как сейчас не выходные. Раньше, когда одно из условий if было истинным, приложение терпело крах, но сейчас OK. – joshgoldeneagle

+0

Изменяя использование блока try catch, чтобы проверить, существует ли sharedPreferences, использовать встроенный метод sharedPreferences(), чтобы проверить наличие ключей sharedPreferences. – joshgoldeneagle

+0

Еще одна проблема, которую я нашел с sharedPreferences, заключается в том, что поскольку AlarmReceiver расширяет wakefulBroadcastReceiver, он не получает контекст приложения автоматически. Мне пришлось перейти в контексте приложения из mainactivity к методу onReceive и от метода onReceive к методам sharedPrefences – joshgoldeneagle

0

Полностью spitballing здесь, я не разработчик Android. Переменная вашего дня недели:

Date date = new Date(); 
String dayOfTheWeek = simpleDateFormat.format(date); 

является переменной-членом класса. Он будет установлен только при создании экземпляра класса. Если это происходит только в каком-то цикле запуска, dayOfTheWeek НЕ МОЖЕТ ИЗМЕНИТЬ. Поэтому, если я прав, если вы установите будильник в среду, этот код всегда будет думать, что это среда, даже в субботу.

Переместите эти две строки кода внутри фактической функции onReceive(), и я готов поспорить, что этот день недели начнет подниматься.

3

В дополнение к ответу dnellis74 вы также нужны скобки здесь:

if(dayOfTheWeek == "Saturday" || dayOfTheWeek == "Sunday" && noWeekends == true) 

становится

if((dayOfTheWeek == "Saturday" || dayOfTheWeek == "Sunday") && noWeekends == true) 

также я думаю, что вам не нужно

try { 
     wait(1); //waits for one-thousandth of a millisecond 
    } catch (InterruptedException e) { 
       e.printStackTrace(); 
    } 
0

1 .) Это отлично прекратить, чтобы запустить событие, а затем фильтровать/обрабатывать его у абонента (BroadcastReceiver). Для этого они созданы.

2.)

if((dayOfTheWeek == "Saturday" || dayOfTheWeek == "Sunday") && noWeekends == true) 

уведомление скобки исправить.

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