Flutter android_alarm_manager plugin doesnt run periodically

后端 未结 2 590
甜味超标
甜味超标 2021-01-16 00:34

Im trying to create background timer in Flutter, that will be called every n seconds. Calling AndroidAlarmManager.periodic should run printHello function every 2 seconds, bu

相关标签:
2条回答
  • 2021-01-16 01:09

    You can't schedule an alarm that frequently with AlarmManager:

    Note: Beginning with API 19 (Build.VERSION_CODES.KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, android.app.PendingIntent) and setExact(int, long, android.app.PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.

    See: https://developer.android.com/reference/android/app/AlarmManager

    0 讨论(0)
  • 2021-01-16 01:09

    @kashlo, Add the following codes inside your main()

    void funTimerMain() async  {
    
      // A few things that you can do with funTimerMain:
    
      // No 1. Do something you want, e.g.
      intCounter += 1;  // intCounter is a GLOBAL VARIABLE (Integer), which was initialized to 0
      print('intCounter: ' + intCounter.toString());
    
      // No 2. Use the following lines only if you use Redux to manage state
      // strCurPage is a GLOBAL VARIABLE (String) that stores which 'page' the user is currently navigating
      if (strCurPage == 'PageHome') {
        // storeHome is the Redux 'STORE' that keep track of the state of Page Home
        // The following line 'Refresh/Re-render' page Home (like a 'setState' in Page Home)
        // i.e. you can 'setState' page Home in an external event, like in this timer function
        storeHome.dispatch(Actions.Increment);
      }
    
      // No 3. Send a message to server every 5 seconds (Instead of 1 second!), using socket.io
      // timLastHeartBeat is a Global Variable (Integer) that was initialized to DateTime.now().millisecondsSinceEpoch;
      if (DateTime.now().millisecondsSinceEpoch - timLastHeartBeat > 5000) {
        socket.emit('HeartBeat', [intCounter]);
        timLastHeartBeat = DateTime.now().millisecondsSinceEpoch;
      }
    
    
      // recall this timer every 1 second
      new Future.delayed(new Duration(milliseconds: 1000), () async { 
        funTimerMain(); 
      }); 
    }
    
    
    // runApp!
    runApp(MyApp());
    
    
    // call the timer for the first time
    funTimerMain();
    

    Question 1: When will no. 1, 2, 3 in funTimerMain run? Ans 1: When the App is in foreground(i.e. user using the App), or When the App is in Background (i.e. user press Home button, or switch to another App).

    Question 2: When will no. 1, 2 stopped to run? Ans 2: When the App is killed by the user, or by the Android System (e.g. killed by battery saving program)

    Question 3: When will no. 3 stopped to run? Ans 3: Same as Ans 2, plus, when user turn off the screen. Starting from Android ? (I forgot the exact version), network access is not allowed when user turn off screen.

    As you can see, the funTimerMain runs every 1 second (Or x seconds), but each task inside funTimerMain can be run every y seconds. (with y >= x, or better be y = Nx with N an integer)

    When I first use this technique, I thought the efficiency would be terrible, but when I run the app in real mobile phone, I can't notice any delay in the mobile phone. So I think by setting an appropriate values of x and y, you can have a responsive app.

    You may use 'await' inside funTimerMain as well, but remember, if the 'function after await' does not return, the timer is paused!

    0 讨论(0)
提交回复
热议问题