【问题标题】:Fluttter Alarm Manager Missing Plugin ExceptionFlutter 警报管理器缺少插件异常
【发布时间】:2019-12-21 13:43:41
【问题描述】:

我无法设置完成某些功能的日常任务。我已经设法让 android_alarm_manager 工作,目前已将其设置为每分钟在日志中打印一条消息以进行测试,但每天完成后都会设置。以下是我的代码:

void printHello() async{
  final DateTime now = DateTime.now();
  final int isolateId = Isolate.current.hashCode;
  print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");

  int myValue = await getData();

  print("Test Value: $myValue");
}

Future<int> getData() async{
  SharedPreferences sharedPreferences = await SharedPreferences.getInstance();

  return sharedPreferences.getInt("testInt");
}

main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final int helloAlarmID = 0;
  await AndroidAlarmManager.initialize();
  runApp(MyApp());
  await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
}

当警报触发时,我会收到示例中的正常打印消息和类似这样的错误

I/flutter (22910): [2019-12-21 13:34:09.526343] Hello, world! isolate=957159586 function='Closure: () => void from Function 'printHello': static.'
E/flutter (22910): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
E/flutter (22910): #0      getData (package:my_jungle_2/main.dart:34:41)
E/flutter (22910): <asynchronous suspension>
E/flutter (22910): #1      printHello (package:my_jungle_2/main.dart:28:23)
E/flutter (22910): #2      _alarmManagerCallbackDispatcher.<anonymous closure> (package:android_alarm_manager/android_alarm_manager.dart:43:14)
E/flutter (22910): #3      MethodChannel._handleAsMethodCall (package:flutter/src/services/platform_channel.dart:402:55)
E/flutter (22910): #4      MethodChannel.setMethodCallHandler.<anonymous closure> (package:flutter/src/services/platform_channel.dart:370:54)
E/flutter (22910): #5      _DefaultBinaryMessenger.handlePlatformMessage (package:flutter/src/services/binding.dart:200:33)
E/flutter (22910): #6      _invoke3.<anonymous closure> (dart:ui/hooks.dart:303:15)
E/flutter (22910): #7      _rootRun (dart:async/zone.dart:1126:13)
E/flutter (22910): #8      _CustomZone.run (dart:async/zone.dart:1023:19)
E/flutter (22910): #9      _CustomZone.runGuarded (dart:async/zone.dart:925:7)
E/flutter (22910): #10     _invoke3 (dart:ui/hooks.dart:302:10)
E/flutter (22910): #11     _dispatchPlatformMessage (dart:ui/hooks.dart:162:5)

我仍然是 Android 和 Flutter 的新手,并且正在努力理解如何为警报管理器提供我需要它使用的插件。

您甚至可以提供诸如共享首选项之类的警报管理器插件吗?

提前感谢您为我解决此问题提供的任何帮助。如果我不理解警报管理器是如何正常工作的,请致歉。

【问题讨论】:

  • 在使用 shared_preferences 依赖项保存 pubspec.yml 后,您是否运行了 flutter pub get
  • @Benjamin 我有。我可以在我的应用程序的其他地方使用shared_preferences。只是不在警报管理器功能中。
  • @MichaelJohnston 你有什么解决方案吗,因为我遇到了同样的问题
  • @DeepakRana 我没有解决这个问题,不,因为最终只是使用应用程序的正常通知,而不是设置每日警报管理器检查。

标签: android flutter dart alarmmanager android-alarms


【解决方案1】:

我是android_alarm_manager 插件的主要维护者。

假设这不是在 Flutter 1.12 之上创建的全新项目,你不能在后台使用其他插件而不跳过更多的环节。

当您执行警报回调时,该回调实际上在另一个 Isolate 上运行(基本上是 Dart 的线程版本,不与其他线程共享内存)。当 Flutter 启动应用程序的主隔离时,它需要使用该隔离注册应用程序中的所有插件,以便所有插件都可以初始化并准备好处理来自 Dart 代码的消息。这是在 Flutter 启动时调用 GeneratedPluginRegistrant.registerWith 时完成的,这是一个自动生成的方法,用于处理应用程序的插件注册。但是,这不会在后台自动完成,因为由 android_alarm_manager 插件生成的隔离不会经历与主隔离相同的初始化,因为它可以随时生成以处理警报事件,所以生成隔离的插件负责注册所有插件。

TL;DR:您必须遵循android_alarm_manager 插件here 的自述文件中列出的几个步骤,但基本上您需要执行以下操作:

  • Application 添加一个自定义实现,它扩展FlutterApplication 并实现PluginRegistrantCallback。在onCreate 中,您需要致电AlarmService.setPluginRegistrant(this)。最后,您需要实现void registerWith(PluginRegistry registry) 并调用GeneratedPluginRegistrant.registerWith(registry)

完成后,您的 Application 类应如下所示:

public class Application extends FlutterApplication implements PluginRegistrantCallback {
  @Override
  public void onCreate() {
    super.onCreate();
    AlarmService.setPluginRegistrant(this);
  }

  // This method is called by AlarmService to register the plugins with the
  // isolate it spawns to execute code in the background.
  @Override
  public void registerWith(PluginRegistry registry) {
    // GeneratedPluginRegistrant is auto-generated and contains all the plugin
    // registration code.
    GeneratedPluginRegistrant.registerWith(registry);
  }
}
  • 一旦您的Application 类被实现,您还需要更新AndroidManifest.xml 以使用您的自定义Application 作为入口点:
   <application
        android:name=".Application"
        ...

完成此操作后,您应该可以使用package:android_alarm_manager 生成的隔离区中的其他插件。 一个例外是,如果您在 Flutter 1.12 发布后创建了一个全新的 Flutter 应用程序,在这种情况下,最新版本的插件应该会自动为您执行此操作。可能已损坏,您需要在 GitHub 上提交问题。

【讨论】:

  • 谢谢你,看来它会解决我一直遇到的问题。令人烦恼的是,直到圣诞节之后才能回到我的电脑上尝试一下。
  • @Ben 我正在使用 v1.12 并且仍然遇到同样的问题
【解决方案2】:

我正在使用 Flutter v1.12,但我还遇到了 MissingPluginException。我解决了我的问题,在我的 Application 类中注册 SharedPreferences:

import io.flutter.app.FlutterApplication
import io.flutter.plugin.common.PluginRegistry
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback
import io.flutter.plugins.androidalarmmanager.AlarmService
import io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin


class Application : FlutterApplication(), PluginRegistrantCallback {
    override fun onCreate() {
        super.onCreate()
        AlarmService.setPluginRegistrant(this)
    }

    override fun registerWith(registry: PluginRegistry?) {
        //Register sharedPreferences here        
        SharedPreferencesPlugin.registerWith(registry?.registrarFor(
        "io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-12
    • 1970-01-01
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多