I need to run a receiver that action USER_PRESENTonly receives for a specific duration on certain days of the week. Here, the duration and days of the week are selected by the user.
What I tried uses Preferencesc AlarmManagerto achieve this, and I would really like to use something else besides Alarmsc Preferencesto achieve this, since it is too difficult to test alarms with weekly alarms that start after a user-selected duration and for selected user days of the week.
Is there any other way to do this work than using Alarmsand Preferences. Sample code is very useful!
See my approach using Alarmswith Preferences:
Now, at first I calculate the starting time, allowing the user to select the hour and minutes by DialogFragmentwhich TimePickerDialogswells, so the user can select the start and I get hrsand minto call back onTimeSet(), and then I know the start time of reception of the receiver.
The code snippet looks something like this to calculate the start time in milliseconds from hrsand min:
Calendar calSet = Calendar.getInstance();
int day = calSet.get(Calendar.DAY_OF_WEEK);
calSet.set(Calendar.DAY_OF_WEEK, day);
calSet.set(Calendar.HOUR_OF_DAY, hrs);
calSet.set(Calendar.MINUTE, min);
calSet.set(Calendar.SECOND, 0);
calSet.set(Calendar.MILLISECOND, 0);
Long milliseconds = calSet.getTimeInMillis();
Long daily = 24L * 60L * 60L * 1000L;
if (milliseconds < System.currentTimeMillis()) {
milliseconds = milliseconds + daily;
}
And then I save this calculated millisecond time in preference, say:SharedPreferences.Editor.putLong("PeriodicLockStartTimeInMillis", milliseconds);
Now I save the days that the user selected using checkBoxesand the settings Preferencesfor each day.
SharedPreferences.Editor.putBoolean("DAYNAME", true);
, , :
SharedPreferences.Editor.putLong("LockDurationInMillis", minutesinmillis);
AlarmManager , BroadcastReceiver, PeriodicLockService, PendingIntent, .
:
Intent reminderIntent = new Intent(getActivity(), PeriodicLockService.class);
reminderIntent.setAction("ACTION_REPEATING_ALARM_RECEIVER");
pendingIntent = PendingIntent.getBroadcast(getActivity(), PeriodicLockService.REPEATING_ALARM_UNIQUE_ID, reminderIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, milliseconds, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, milliseconds, pendingIntent);
}
PeriodicLockService, onReceive , , , , preference :
Calendar calendar = Calendar.getInstance();
int day = calendar.get(Calendar.DAY_OF_WEEK);
switch (day) {
case Calendar.SUNDAY:
if (Preferences.getBooleanPreference(context, SUN_DAY)) {
startLockNow(context);
}
break;
case Calendar.MONDAY:
if (Preferences.getBooleanPreference(context, MON_DAY)) {
startLockNow(context);
}
break;
case Calendar.TUESDAY:
if (Preferences.getBooleanPreference(context, TUES_DAY)) {
startLockNow(context);
}
break;
case Calendar.WEDNESDAY:
if (Preferences.getBooleanPreference(context, WED_DAY)) {
startLockNow(context);
}
break;
case Calendar.THURSDAY:
if (Preferences.getBooleanPreference(context, THURS_DAY)) {
startLockNow(context);
}
break;
case Calendar.FRIDAY:
if (Preferences.getBooleanPreference(context, FRI_DAY)) {
startLockNow(context);
}
break;
case Calendar.SATURDAY:
if (Preferences.getBooleanPreference(context, SAT_DAY)) {
startLockNow(context);
}
break;
}
private void startLockNow(Context context) {
Long lockStartTimeInMillis = Preferences.getLongPreference(context, "PeriodicLockStartTimeInMillis");
Long LockDurationInMillis = Preferences.getLongPreference(context, "LockDurationInMillis");
Long newEndTime = lockStartTimeInMillis + LockDurationInMillis;
Intent intent = new Intent(context, FinalUnlockedBroadcast.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, newEndTime + 1000, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, newEndTime + 1000, pendingIntent);
}
milliseconds = Preferences.getLongPreference(context, "PeriodicLockStartTimeInMillis") + 24L * 60L * 60L * 1000L;
Intent reminderIntent = new Intent(context, PeriodicLockService.class);
reminderIntent.setAction("ACTION_REPEATING_ALARM_RECEIVER");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, REPEATING_ALARM_UNIQUE_ID, reminderIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, milliseconds , pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, milliseconds , pendingIntent);
}
}
, , , .
, , Alarms Preferences