2015-10-15 63 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

總NIT採摘。等待(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現在過濾掉請求,使用上面公佈的代碼。由於錯誤「IllegalMonitorStateException:對象沒有被wait()之前的線程鎖定」,我將wait()方法更改爲Thread.sleep。因爲現在不是週末,所以我設置了一個虛擬條件來進行測試。以前,如果條件是真的,應用程序崩潰了,但現在可以。 – joshgoldeneagle

+0

更改使用try catch塊檢查sharedPreferences是否存在,以使用內置的sharedPreferences方法contains()檢查是否存在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) 

通知括號固定。