George
George

Reputation: 1114

Sounding alarm with the Pending Intent in android

I am following a tutorial to build an android app that allow users to store time (hours an minutes) into their local sqlite database. This Time stored is checked with the calendar time, then by using pendingIntent to ring an alarm when the time is equal to the current time.

Below is some of main codes that do the work

public class AlarmManagerHelper extends BroadcastReceiver {

public static final String ID = "id";
public static final String NAME = "name";
public static final String TIME_HOUR = "timeHour";
public static final String TIME_MINUTE = "timeMinute";
public static final String TONE = "alarmTone";
public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";

@Override
public void onReceive(Context context, Intent intent) {
    setAlarms(context);
}

public static void setAlarms(Context context) {
    cancelAlarms(context);

    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms = dbHelper.getAlarms();

    if (alarms != null) {
        for (AlarmModel alarm : alarms) {
            if (alarm.isEnabled) {

                PendingIntent pIntent = createPendingIntent(context, alarm);

                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.HOUR_OF_DAY, alarm.timeHour);
                calendar.set(Calendar.MINUTE, alarm.timeMinute);
                calendar.set(Calendar.SECOND, 00);

                //Find next time to set
                final int nowDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
                final int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
                final int nowMinute = Calendar.getInstance().get(Calendar.MINUTE);
                boolean alarmSet = false;

                //First check if it's later in the week
                for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
                    if (dayOfWeek >= nowDay &&
                            !(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
                            !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {
                        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                        setAlarm(context, calendar, pIntent);
                        alarmSet = true;
                        setStatusBarIcon(context, alarmSet);
                        break;
                    }
                }
                //Else check if it's earlier in the week
                if (!alarmSet) {
                    for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
                        if ( dayOfWeek <= nowDay && alarm.repeatWeekly)  {
                            calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                            calendar.add(Calendar.WEEK_OF_YEAR, 1);

                            setAlarm(context, calendar, pIntent);
                            alarmSet = true;
                            break;
                        }
                    }
                }
            }
        }
    }
}

@SuppressLint("NewApi")
private static void setAlarm(Context context, Calendar calendar, PendingIntent pIntent) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    }
}

public static void cancelAlarms(Context context) {
    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms = dbHelper.getAlarms();

    if (alarms != null) {
        for (AlarmModel alarm : alarms) {
            if (alarm.isEnabled) {
                PendingIntent pIntent = createPendingIntent(context, alarm);

                AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                alarmManager.cancel(pIntent);
            }
        }
    }
}

public static void setStatusBarIcon(Context context, boolean enabled) {

    Intent alarmChanged = new Intent(ACTION_ALARM_CHANGED);
    alarmChanged.putExtra("alarmSet", enabled);
    context.sendBroadcast(alarmChanged);

}

private static PendingIntent createPendingIntent(Context context, AlarmModel model) {
    Intent intent = new Intent(context, AlarmService.class);
    intent.putExtra(ID, model.id);
    intent.putExtra(NAME, model.name);
    intent.putExtra(TIME_HOUR, model.timeHour);
    intent.putExtra(TIME_MINUTE, model.timeMinute);
    intent.putExtra(TONE, model.alarmTone.toString());

    return PendingIntent.getService(context, (int) model.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
   }
 }

Now using the same knowledge above, I want to be able to sound the alarm when a datetime ( thus year,month,day and hours and minute) inserted into the database by the user is due. With this I have a added the year,month,day column to the database.

The problem now is the condition to let the alarm sound when the datetime is due.

This is the tutorial's way of sounding an alarm when the time is due

 for (int dayOfWeek = Calendar.SUNDAY; dayOfWeek <= Calendar.SATURDAY; ++dayOfWeek) {
                    if (dayOfWeek >= nowDay &&
                            !(dayOfWeek == nowDay && alarm.timeHour < nowHour) &&
                            !(dayOfWeek == nowDay && alarm.timeHour == nowHour && alarm.timeMinute <= nowMinute)) {
                        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
                        setAlarm(context, calendar, pIntent);
                        alarmSet = true;
                        setStatusBarIcon(context, alarmSet);
                        break;
                    }
                }

This is how I have tried to sound the alarm with the below condition, but it doesnt seem to work

 if( alarm.DateDay== nowDateDay && alarm.DateMonth== nowDateMonth){
     setAlarm(context, calendar, 
     alarmSet = true;
     break;
 }

I am lost of ideas at this stage, please any help will much appreciated. Thanks in advance

UPDATE

The tutorials allows users to set an alarm based on the time (thus hour and minute), I however want to allow users to set an alarm based on the date ( thus day and month and year)

Forinstance if a user set the alarm date to 11th February 2016, the alarm is suppose to sound when the date is due. So in this case the alarm would be sounding tommorrow since tommorrow is 11th February 2016. Now I want a way to make this condition work as explained above.

Thanks for helping

Upvotes: 1

Views: 161

Answers (1)

Zahan Safallwa
Zahan Safallwa

Reputation: 3904

I just edited your code as per your necessity. The alarm date is 11th February 2016. Be sure to replace with your database data. I think you have the AlarmService and AlarmScreen class done. If not you can let me know i will edit. For now the AlarmManagerHelper should look like below.

public class AlarmManagerHelper extends BroadcastReceiver {

public static final String ID = "id";
public static final String NAME = "name";
public static final String TIME_HOUR = "timeHour";
public static final String TIME_MINUTE = "timeMinute";
public static final String TONE = "alarmTone";

@Override
public void onReceive(Context context, Intent intent) {
    setAlarms(context);
}

public static void setAlarms(Context context) {
    cancelAlarms(context);

    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms =  dbHelper.getAlarms();

    for (AlarmModel alarm : alarms) {
        if (alarm.isEnabled) {

            PendingIntent pIntent = createPendingIntent(context, alarm);

            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.DAY_OF_MONTH,11); //sample date
            calendar.set(Calendar.YEAR,2016);//sample year. plz add yours from db
            calendar.set(Calendar.MONTH,01);//sample month
            calendar.set(Calendar.HOUR_OF_DAY, alarm.timeHour);
            calendar.set(Calendar.MINUTE, alarm.timeMinute);
            calendar.set(Calendar.SECOND, 00);


            //Find next time to set
            final int nowDay = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
            final int nowHour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
            final int nowMinute = Calendar.getInstance().get(Calendar.MINUTE);
            final int nowDate = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
            final int nowMonth = Calendar.getInstance().get(Calendar.MONTH);
            final int nowYear = Calendar.getInstance().get(Calendar.YEAR);
            boolean alarmSet = false;
            if(nowYear<=2016 && nowMonth<=01 && nowDate<=11 ) //change 2016,01,11 with user given data (from database)
            {
                if(nowHour<=alarm.timeHour)
                        {
                            if (nowMinute<alarm.timeMinute)
                            {
                                setAlarm(context, calendar, pIntent);
                                alarmSet = true;


                            }
                    }
           }
        }
    }
}

@SuppressLint("NewApi")
private static void setAlarm(Context context, Calendar calendar, PendingIntent pIntent) {
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
    }
}

public static void cancelAlarms(Context context) {
    AlarmDBHelper dbHelper = new AlarmDBHelper(context);

    List<AlarmModel> alarms =  dbHelper.getAlarms();

    if (alarms != null) {
        for (AlarmModel alarm : alarms) {
            if (alarm.isEnabled) {
                PendingIntent pIntent = createPendingIntent(context, alarm);

                AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
                alarmManager.cancel(pIntent);
            }
        }
    }
}

private static PendingIntent createPendingIntent(Context context, AlarmModel model) {
    Intent intent = new Intent(context, AlarmService.class);
    intent.putExtra(ID, model.id);
    intent.putExtra(NAME, model.name);
    intent.putExtra(TIME_HOUR, model.timeHour);
    intent.putExtra(TIME_MINUTE, model.timeMinute);
    intent.putExtra(TONE, model.alarmTone.toString());

    return PendingIntent.getService(context, (int) model.id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}

Upvotes: 4

Related Questions