Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent repeating alarm from occurring on weekend

I have an alarm app using the AlarmManager class that allows user to set a one-time alarm, or a repeating alarm. I would like to expand the capabilities so that the user can exclude the alarm from going off, for example, on the weekend.

I have put the code to block the alarm on weekends into AlarmReceiver.java.

  1. I am not sure if AlarmReceiver.java is the correct place to put the code that blocks alarms on the weekend.
  2. I am not sure if the code I am using to block the alarm on weekends is correct. Basically I tell AlarmReceiver to do nothing if today is Saturday or Sunday. Else, fire off the alarm.

AlarmActivity.java code that sets the alarm:

  //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 (corrected code)

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;
    }
}
like image 417
joshgoldeneagle Avatar asked Oct 15 '15 00:10

joshgoldeneagle


People also ask

How do I set an alarm for multiple days on Android?

Calendar object is used to store one specific date. Therefore, in order to get set alarms for several days, you need to set each of the alarms separately. For this reason you may create separate Calendar objects or reuse one by changing the time. However, you have same receiver class for both alarms.

How is AlarmManager different from WorkManager?

Unlike WorkManager, AlarmManager wakes a device from Doze mode.

How do you schedule notifications using alarm Manager explain with an example?

Handling the broadcast:Alarm service will invoke this receiver on scheduled time. Here we can trigger the local notification with the respective details(title, content, icon). The below code will help you to handle the broadcast. Now inside your onReceive() function, you need to initiate the notification.


2 Answers

Your approach is fine. Anyway I suggest you to avoid using hardcoded strings for the weekend check. You already have a Calendar object defined in your code, just use it:

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

And update your code accordingly:

  //...
  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();
        }
    }
  //...
like image 118
bonnyz Avatar answered Sep 20 '22 11:09

bonnyz


In addition to dnellis74's answer you also need some brackets here:

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

becomes

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

also I think you do not need

 try {
      wait(1);  //waits for one-thousandth of a millisecond
     } catch (InterruptedException e) {
                e.printStackTrace();
     }
like image 36
leonardkraemer Avatar answered Sep 18 '22 11:09

leonardkraemer