Flatter android\u alarm\u管理器插件不定期运行

Flatter android\u alarm\u管理器插件不定期运行,android,flutter,Android,Flutter,我试图在颤振中创建背景计时器,它将每n秒调用一次。调用AndroidAlarmManager.periodic应该每2秒运行一次printHello函数,但它看起来是以更大的间隔随机调用的。我做错了什么 import 'package:android_alarm_manager/android_alarm_manager.dart'; void runTimer() async{ await AndroidAlarmManager.periodic(const Duration(sec

我试图在颤振中创建背景计时器,它将每n秒调用一次。调用AndroidAlarmManager.periodic应该每2秒运行一次printHello函数,但它看起来是以更大的间隔随机调用的。我做错了什么

import 'package:android_alarm_manager/android_alarm_manager.dart';


void runTimer()  async{
  await AndroidAlarmManager.periodic(const Duration(seconds: 2), 0, printHello, exact: true);
}

void printHello(){
  print("Hello");
}

main() async {
  await AndroidAlarmManager.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: Scaffold(
        body: Center(
          child: InkWell(onTap: runTimer,
              child: Container(child: Text('Run Timer'))),
        ),
      ),
    );
  }
}

您不能使用
AlarmManager
计划频繁的报警:

注意:从API 19(Build.VERSION_CODES.KITKAT)开始,警报传递是不准确的:操作系统将切换警报,以尽量减少唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,android.app.pendingent)和setExact(int,long,android.app.pendingent)。targetSdkVersion早于API 19的应用程序将继续看到之前的行为,其中所有警报都会在请求时准确传递


请参阅:

您不能使用
AlarmManager
计划频繁的报警:

注意:从API 19(Build.VERSION_CODES.KITKAT)开始,警报传递是不准确的:操作系统将切换警报,以尽量减少唤醒和电池使用。有新的API支持需要严格交付保证的应用程序;请参阅setWindow(int,long,long,android.app.pendingent)和setExact(int,long,android.app.pendingent)。targetSdkVersion早于API 19的应用程序将继续看到之前的行为,其中所有警报都会在请求时准确传递


请参阅:

@kashlo,在main()中添加以下代码

问题1:funTimerMain的1号、2号、3号将在何时运行?回答1:当应用程序位于前台时(即用户使用应用程序),或当应用程序位于后台时(即用户按下主页按钮,或切换到其他应用程序)

问题2:1号、2号何时停止运行?Ans 2:当应用程序被用户或Android系统终止时(例如,被节电程序终止)

问题3:3号何时停止跑步?Ans 3:与Ans 2相同,另外,当用户关闭屏幕时。从Android开始?(我忘记了确切的版本),当用户关闭屏幕时,不允许网络访问

如您所见,funTimerMain每1秒(或x秒)运行一次,但是funTimerMain中的每个任务可以每y秒运行一次。(y>=x,最好是y=Nx,N为整数)

当我第一次使用这种技术时,我认为效率会很糟糕,但是当我在真实的手机上运行应用程序时,我没有注意到手机上有任何延迟。因此,我认为通过设置适当的x和y值,您可以拥有一个响应迅速的应用程序


您也可以在funTimerMain中使用'wait',但请记住,如果'function after wait'没有返回,计时器将暂停

@kashlo,在main()中添加以下代码

问题1:funTimerMain的1号、2号、3号将在何时运行?回答1:当应用程序位于前台时(即用户使用应用程序),或当应用程序位于后台时(即用户按下主页按钮,或切换到其他应用程序)

问题2:1号、2号何时停止运行?Ans 2:当应用程序被用户或Android系统终止时(例如,被节电程序终止)

问题3:3号何时停止跑步?Ans 3:与Ans 2相同,另外,当用户关闭屏幕时。从Android开始?(我忘记了确切的版本),当用户关闭屏幕时,不允许网络访问

如您所见,funTimerMain每1秒(或x秒)运行一次,但是funTimerMain中的每个任务可以每y秒运行一次。(y>=x,最好是y=Nx,N为整数)

当我第一次使用这种技术时,我认为效率会很糟糕,但是当我在真实的手机上运行应用程序时,我没有注意到手机上有任何延迟。因此,我认为通过设置适当的x和y值,您可以拥有一个响应迅速的应用程序


您也可以在funTimerMain中使用'wait',但请记住,如果'function after wait'没有返回,计时器将暂停

我使用的技术可以在后台运行计时器(例如,用户按下home按钮),但当应用程序被终止时计时器停止。如果这是您想要的,请告诉我,我会发布一个答案。@Kenneth Li我正在尝试创建一个冥想计时器,以用户提供的间隔播放声音。用户可以锁定屏幕,但带有声音的计时器仍应工作。如果您认为您的解决方案对我的情况有帮助,我将非常感谢您的解决方案我正在使用一种可以在后台运行计时器的技术(例如,用户按home按钮),但当应用程序被终止时计时器停止。如果这是您想要的,请告诉我,我会发布一个答案。@Kenneth Li我正在尝试创建一个冥想计时器,以用户提供的间隔播放声音。用户可以锁定屏幕,但带有声音的计时器仍应工作。如果您认为您的解决方案对我的情况有帮助,我们将不胜感激
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();