2015-10-15 8 views
10

Ho un'app di allarme che utilizza la classe AlarmManager che consente all'utente di impostare un allarme una tantum o un allarme ripetuto. Mi piacerebbe espandere le funzionalità in modo che l'utente possa escludere la sveglia, ad esempio, nel fine settimana.Evitare che si ripeta l'allarme nel fine settimana

Ho inserito il codice per bloccare l'allarme nei fine settimana su AlarmReceiver.java.

  1. Non sono sicuro se AlarmReceiver.java è il posto corretto in cui inserire il codice che blocca gli avvisi nel fine settimana.
  2. Non sono sicuro che il codice che sto usando per bloccare l'allarme nei fine settimana sia corretto. Fondamentalmente dico a AlarmReceiver di non fare nulla se oggi è sabato o domenica. Altrimenti, spegni l'allarme.

codice AlarmActivity.java che imposta l'allarme:

//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 (corretto codice)

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

totale nit picking. wait (1) è un millisecondo, non un millesimo di millisecondo. – dnellis74

+0

Cosa non va? L'hai provato durante un fine settimana e l'allarme è stato sparato? Hai eseguito il debug in un fine settimana e controllato il valore di "dayOfTheWeek" per vedere cosa c'è dentro? Qual è il valore di repeatIntervalMilliseconds? – Christian

risposta

7

L'approccio è corretto.Comunque ti suggerisco di evitare l'uso di stringhe codificate per il controllo del weekend . Hai già un oggetto Calendar definito nel codice, basta usarlo:

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

E aggiornare il codice di conseguenza:

//... 
    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

Sono in grado di attivare una richiesta di allarme e quindi filtrare la richiesta in AlarmReceiver ora, utilizzando praticamente il codice che hai postato sopra. Ho modificato il metodo wait() su Thread.sleep a causa dell'errore "IllegalMonitorStateException: oggetto non bloccato da thread before wait()". Ho impostato un manichino se la condizione per i test in quanto non è il fine settimana ora. In precedenza, quando le condizioni if ​​erano vere, l'app si bloccava, ma ora OK. – joshgoldeneagle

+0

Cambiando dall'utilizzo del blocco catch try per verificare se esistono sharedPreferences, utilizzare il metodo sharedPreferences incorporato contains() per verificare l'esistenza di chiavi sharedPreferences. – joshgoldeneagle

+0

Un altro problema che ho riscontrato con sharedPreferences è che poiché AlarmReceiver estende wakefulBroadcastReceiver, non riceve automaticamente il contesto dell'applicazione. Ho dovuto passare nel contesto dell'applicazione dal mainactivity al metodo onReceive e dal metodo onReceive ai metodi sharedPrefences – joshgoldeneagle

0

Totalmente spitballing qui, non sono uno sviluppatore Android. La variabile del giorno della settimana:

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

è una variabile membro della classe. Verrà impostato solo quando la classe viene istanziata. Se ciò accade solo in una sorta di ciclo di avvio, dayOfTheWeek NON cambierà mai. Quindi, se ho ragione, se imposti la sveglia di mercoledì, questo codice penserà sempre che è mercoledì, anche sabato.

Sposta quelle due righe di codice all'interno della funzione effettiva su Ricevi() e scommetto che il giorno della settimana inizierà a essere prelevato.

3

Oltre alla risposta di dnellis74 è necessario anche alcune parentesi qui:

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

diventa

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

anche Penso che non hai bisogno di

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

1 .) È perfettamente bene per attivare un evento e quindi filtrarlo/elaborarlo in un abbonato (BroadcastReceiver). Questo è quello per cui sono fatti.

2.)

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

preavviso le parentesi fix.

Problemi correlati