Flutter repeat alarm on user selected week days
Add the startAt parameter. In this code it'll start at 8am of the current day. You can change to to whenever you need it to start
AndroidAlarmManager.periodic(
const Duration(minutes: 30), 0,
printHello,
startAt: DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day, 8, 0),
);
Admin
Updated on December 30, 2022Comments
-
Admin over 1 year
If my user sets some data like:
day : "Sunday" startTime: 8:00 A.M endTime: 8:00 P.M frequency: 30 minutes
I want to fire an alarm after each 30 minutes starting from
8:00 A.M
so,8:00 A.M
,8:30 A.M
,9:00 A.M
,9:30 A.M
....Now I'm using android_alarm_manager_plus for my application and this is what I have done till now:
AndroidAlarmManager.periodic( const Duration(minutes: 0, seconds: 1), 0, printHello, // callback function, for now I'm just printing "hello world" );
How can I set an alarm on the user selected day, time and frequency?
Update 1:
AndroidAlarmManager.periodic( const Duration(minutes: _frequency!), //Evaluation of this constant expression throws an exception. 0, printHello, startAt: DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day, _startTime, //The argument type 'TimeOfDay?' can't be assigned to the parameter type 'int' 0, ), );
How I'm storing data:
int? frequency; TimeOfDay? startTime;
My TimeOfDay selector:
void selectStartTime() async { final TimeOfDay? newTime = await showTimePicker( context: context, initialTime: _startTime!, initialEntryMode: TimePickerEntryMode.input, ); if (newTime != null) { setState(() { _startTime = newTime; }); } }
Update 2: Okay, so I checked the source code for android alarm manager plus and I think they don't support what I'm trying to do out of the box.
This is the code for their periodic timer:
static Future<bool> periodic( Duration duration, int id, Function callback, { DateTime? startAt, bool exact = false, bool wakeup = false, bool rescheduleOnReboot = false, }) async { // ignore: inference_failure_on_function_return_type assert(callback is Function() || callback is Function(int)); assert(id.bitLength < 32); final now = _now().millisecondsSinceEpoch; final period = duration.inMilliseconds; final first = startAt != null ? startAt.millisecondsSinceEpoch : now + period; final handle = _getCallbackHandle(callback); if (handle == null) { return false; } final r = await _channel.invokeMethod<bool>('Alarm.periodic', <dynamic>[ id, exact, wakeup, first, period, rescheduleOnReboot, handle.toRawHandle() ]); return (r == null) ? false : r; }
Is it possible to create another custom function to do what I want? The custom function would look something like this:
static Future<bool> customPeriodic( int id, // id Duration repeatAfter, // repeats after each m time(ex: 7 days) int frequency, // fire alarm after each n minutes(ex: 30 mins) Function callBack, { DateTime? startAt, // serve as start tune DateTime? endAt, // serve as end time bool exact = false, bool wakeup = false, bool rescheduleOnReboot = false, }) async { return true; }
-
Admin almost 3 yearshey thanks for the suggestion but it doesn't work. I've updated my post with the updated code. Can you please check it?
-
zinbrox almost 3 yearsYour code seems correct, have you tried picking a time in the future as the first call won't run if the startAt time is already passed.
-
Admin almost 3 yearsHey, I just had to remove the
const
and the first problem is gone. But there's still the issue of dynamically setting the day andstartTime
which should beint
. But I'm storing the data inTimeOfDay
-
zinbrox almost 3 yearsHey sorry for the late reply, if you're using
TimeOfDay
you can access the hour bynewTime.hour
. If you need to select day to start, you can map the day to a DateTime object, but it's probably easier to use this package