Saving timer to local memory in flutter

70 Views Asked by At

In Flutterd, I have an int timer value that is thrown to the button when the button is pressed, so that this value continues to run even if the application is closed. and when I close and open the application, this remaining time will be displayed instantly in text, but I could not do it, how can I save the timer to local memory?

I tried with shared preferences but I couldn't do it

1

There are 1 best solutions below

0
On

i build this function in flutter with GetX to make user get prize after the user click in yhe prize the timer will be start to 24 hours ,after the user close app and return the timer will be countuned from the last user action by checking the time i saved into local storage and calcualte the different between this time saved and DateTime.now(), this is the code , but i use GetStorage not use the shared preference :

decleare this var

bool canGetPrize = true;
Stringeta = '';

and oninit the class check for the user if can get prize or not

void onInit() {
canGetPrize.value = box.read(GetBoxKey.canGetPrize) ?? true;
_loadTimerState();// this function to load state for timer if data saved 
                 show the timer ETA if not view the button to get The prize
super.onInit();
}

the build the _loadTimerState() function :

 Future<void> _loadTimerState() async {
 try {
  String? nextPrize = box.read("nextPrizeTime");

  if (nextPrize != null) {
    DateTime? nextPrizeTime = DateTime.parse(nextPrize);

    DateTime now = DateTime.now();

    if (now.isAfter(nextPrizeTime)) {
      // User can get the prize now
      canGetPrize= true;
      await box.write("canGetPrize", true);
    } else {
      // Calculate ETA
      _startEtaTimer(nextPrizeTime);
    }
  }
  update();
} catch (e) {
  throw Exception("Error Load Timer $e");
}
}

this the function to getPrize when user click on the button :

void getPrize() async {
try {
    DateTime nextPrizeTime = DateTime.now().add(const Duration(days: 1));
    box.write("nextPrizeTime", nextPrizeTime.toString());
    canGetPrize= false;
    await box.write("canGetPrize", false);
    _startEtaTimer(nextPrizeTime);
} catch (e) {
  throw Exception("Error Get Prize $e");
}
}

and the build ETA Timer in this function

 void _startEtaTimer(DateTime targetTime) {
 try {
  Timer.periodic(const Duration(seconds: 1), (Timer t) async {
    DateTime now = DateTime.now();
    Duration difference = targetTime.difference(now);

    if (difference.isNegative) {
      t.cancel();
      canGetPrize.value = true;
      await box.write(GetBoxKey.canGetPrize, true);
      eta.value = '';
      box.remove(GetBoxKey.nextPrizeTime);
    } else {
      eta.value = _formatDuration(difference);
    }
  });
} catch (e) {
  throw Exception("Error Start ETA Timer $e");
}
}


String _formatDuration(Duration duration) {
int hours = duration.inHours;
int minutes = (duration.inMinutes % 60);
int seconds = (duration.inSeconds % 60);
return '$hours:${minutes.toString().padLeft(2, 
'0')}:${seconds.toString().padLeft(2, '0')}';
}

in youre UI use TimerBuilder package to build timer running like this :

TimerBuilder.periodic(const Duration(seconds: 1),
            builder: (context) {
          return Obx(() {
            return Visibility(
              visible: !controller.canGetPrize &&
                  controller.eta.isNotEmpty,
              child: Text(
                'prize After : ${controller.eta}',
                style:
                    TextStyle(fontSize: 20, color: AppColor.primaryColor),
              ),
            );
          });
        }),