Android Alarm Manager 不适用于 Flutter Project App
Android Alarm Manager is not working for Flutter Project App
我已经在我的新 Flutter 应用程序中安装了 Android Alarm Manager 插件。我尝试使用插件的示例代码,但它在控制台中给出了错误。
请建议如何使 Android 警报管理器插件工作。
如何将 Dart 的 android_alarm_manager 集成到应用程序中,以便用户在他们在日程中选择的时间到达时收到警报?
我使用这个 link 中的代码:
https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager
main.dart
:
import 'dart:isolate';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:flutter/material.dart';
void printHello() {
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}
void main() async {
final int helloAlarmID = 0;
await AndroidAlarmManager.initialize();
runApp(MaterialApp(home: Application()));
await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
}
class Application extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
Application.java
:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
当我 运行 此代码时,它向控制台打印以下错误:
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Attempt to invoke interface method 'void io.flutter.plugin.common.PluginRegistry$PluginRegistrantCallback.registerWith(io.flutter.plugin.common.PluginRegistry)' on a null object reference, null)
E/flutter ( 6831): #0 JSONMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:149:7)
E/flutter ( 6831): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:302:33)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #2 AndroidAlarmManager.initialize (package:android_alarm_manager/android_alarm_manager.dart:76:10)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #3 main (package:alarmdemo/main.dart:12:29)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #4 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #5 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #6 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #7 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #8 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #9 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #10 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #11 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method AlarmService.initialized on channel plugins.flutter.io/android_alarm_manager_background)
E/flutter ( 6831): #0 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:300:7)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #1 _alarmManagerCallbackDispatcher (package:android_alarm_manager/android_alarm_manager.dart:49:12)
E/flutter ( 6831): #2 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #3 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #4 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #5 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #6 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #7 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #8 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #9 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
这是我更新后的代码:
main.dart
:
void printHello() {
final DateTime now = new DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId}
function='$printHello'");
}
void main() async {
runApp(MaterialApp(home: Application()));
}
class Application extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: RaisedButton(
child: Text('Hello'),
onPressed: () {
runAlarm();
},
),
),
),
);
}
void runAlarm() {
AndroidAlarmManager.oneShot(
Duration(seconds: 10),
0,
printHello,
wakeup: true,
).then((val) => print(val));
}
static void alarmTest() {
print("test");
}
}
它不会向控制台打印任何错误,但会打印以下两行:
E/AlarmService(11943): Fatal: failed to find callback
I/AlarmService(11943): AlarmService has not yet started.
我也尝试初始化警报管理器,但它向控制台打印错误:
void runAlarm() {
AndroidAlarmManager.periodic(
Duration(seconds: 10),
0,
printHello,
wakeup: true,
).then((val) => print(val)).catchError((e) {
print(e);
});
}
错误:
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Attempt to invoke interface method 'void io.flutter.plugin.common.PluginRegistry$PluginRegistrantCallback.registerWith(io.flutter.plugin.common.PluginRegistry)' on a null object reference, null)
E/flutter ( 6831): #0 JSONMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:149:7)
E/flutter ( 6831): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:302:33)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #2 AndroidAlarmManager.initialize (package:android_alarm_manager/android_alarm_manager.dart:76:10)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #3 main (package:alarmdemo/main.dart:12:29)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #4 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #5 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #6 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #7 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #8 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #9 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #10 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #11 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method AlarmService.initialized on channel plugins.flutter.io/android_alarm_manager_background)
E/flutter ( 6831): #0 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:300:7)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #1 _alarmManagerCallbackDispatcher (package:android_alarm_manager/android_alarm_manager.dart:49:12)
E/flutter ( 6831): #2 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #3 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #4 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #5 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #6 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #7 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #8 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #9 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
您没有初始化警报对象和回调处理程序。
await AndroidAlarmManager.initialize();
当应用程序启动时会发生什么运行宁此:
void main() async {
runApp(MaterialApp(home: Application()));
}
应用程序只是 运行 并为您绘制 UI。单击按钮后,将调用以下方法:
AndroidAlarmManager.oneShot(
Duration(seconds: 10),
0,
printHello,
wakeup: true,
)
此函数只是在指定的延迟时间后安排回调。这将失败,因为回调处理程序未注册。意思是,超时后,它找不到 'anyone' 负责 运行 和 'printHello'。
编辑:
您还需要覆盖一个方法来帮助插件在创建时自行注册。
像下面这样创建一个新文件:
yourapprootfolder/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java
在 .java 文件中,放入:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
或在 Kt 文件中:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
override fun registerWith(registry: PluginRegistry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
如果您只为 android 开发此应用程序,那么您可以为每个给定的时间间隔创建 native foreground/background service
,其中 运行s。然后使用 platform channel
你可以在 button
上调用来自 dart 的服务,如果你想要它 运行 每次在特定条件下或使用 shared prefrence
从 initState()
在你的主页。正如您可能知道的那样,一旦本机服务启动,它将在每个给定的时间间隔( 分钟或 24 小时 )后调用自身。
你是在 AndroidManifest.xml 中引用你 Application
吗?顺便说一句(我会使用不同的名称,以免与 Android 的 Application
混淆,例如 MyFlutterApplication
)。
the documentation of the plugin 中的通知指出:
Which must be reflected in the application's AndroidManifest.xml. E.g.:
<application
android:name=".Application"
...
有关详细信息,请参阅 Android Developers element documentation。
我遇到了同样的问题。只需打开 android 项目。执行 Gradle 同步。接下来,执行 "build -> clean project" 和 "build -> rebuild project".
问题:未处理的异常:MissingPluginException(未在通道 plugins.flutter.io/android_alarm_manager_background 上找到方法 AlarmService.initialized 的实现)
原因:Alarm回调会需要访问其他Flutter插件,包括alarmmanager插件本身,需要教会后台服务如何初始化插件。由于 AlarmManager 使用单独的 isolate,任何在调度代码中使用的插件都需要单独为 AlarmManager 初始化。
解决方案:在Application.java
中注册alarm manager插件本身如下;(已解决官方flutter repo问题#21969)
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
import io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
// GeneratedPluginRegistrant.registerWith(registry);
AndroidAlarmManagerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin"));
}
}
*Note: if you have used another plugins in your project, You would have also add it all into your Application.java
file.
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
// GeneratedPluginRegistrant.registerWith(registry);
//add AndroidAlarmManagerPlugin plugin register if you work with arlarm
AndroidAlarmManagerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin"));
//add PathProviderPlugin plugin register if you work with Access Path Device
PathProviderPlugin.registerWith(registry.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"));
//add SqflitePlugin plugin register if you work with sqflite
SqflitePlugin.registerWith(registry.registrarFor("com.tekartik.sqflite.SqflitePlugin"));
//add PermissionHandlerPlugin plugin register if you work with permission handler
PermissionHandlerPlugin.registerWith(registry.registrarFor("com.baseflow.permissionhandler.PermissionHandlerPlugin"));
//add SharedPreferencesPlugin plugin register if you work with share preferences
SharedPreferencesPlugin.registerWith(registry.registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"));
// something else...
}
}
经过几个小时的努力(但感觉时间长了很多!),我终于自己解决了这个问题。当我实际克隆包含 android_alarm_manager
的 Flutter Plugins Github repository 并查看示例代码并查看它在 IDE 中的布局时,突破出现了,而不是在线查看孤立的文件。
如果您不精通 Android Java 开发,自述文件并不清楚具体要做什么,但是当您查看工作示例代码时就会清楚。
您需要将示例目录中提供的 Application.java
文件放入您的实际项目中,与现有 MainActivity.java
文件位于同一文件夹中。内容应如下所示:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
至于你需要把这个文件放在哪里,他们的例子是这样的,但你的可能是这样的 <your project dir>/android/app/src/main/java/com/example/<your project name>
:
完成此操作后,您必须将Application.java
第一行的包名称从package io.flutter.plugins.androidalarmmanagerexample;
更新为匹配您的项目使用的任何包(请参阅您现有 MainActivity.java
的第一行)。如果您不这样做,gradle 将找不到它并且没有任何效果!
您现在可以按照 Readme 中的建议,添加权限等:
After importing this plugin to your project as usual, add the following to your AndroidManifest.xml
within the <manifest></manifest>
tags:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Next, within the <application></application>
tags, add:
<service
android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<receiver
android:name="io.flutter.plugins.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false"/>
<receiver
android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
最后一部分是我最困惑的部分。听起来他们很含糊,但如果你之前做的一切都完全正确,那实际上正是你需要做的。
Which must be reflected in the application's AndroidManifest.xml. E.g.:
<application
android:name=".Application"
...
只需将您的 android:name
更改为 .Application
,这意味着它现在将利用我们之前添加的 Application.java
。
就是这样!希望您现在可以 运行 您的应用程序。
请建议如何使 Android 警报管理器插件工作。 如何将 Dart 的 android_alarm_manager 集成到应用程序中,以便用户在他们在日程中选择的时间到达时收到警报?
我使用这个 link 中的代码: https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager
main.dart
:
import 'dart:isolate';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:flutter/material.dart';
void printHello() {
final DateTime now = DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId} function='$printHello'");
}
void main() async {
final int helloAlarmID = 0;
await AndroidAlarmManager.initialize();
runApp(MaterialApp(home: Application()));
await AndroidAlarmManager.periodic(const Duration(minutes: 1), helloAlarmID, printHello);
}
class Application extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
Application.java
:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
当我 运行 此代码时,它向控制台打印以下错误:
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Attempt to invoke interface method 'void io.flutter.plugin.common.PluginRegistry$PluginRegistrantCallback.registerWith(io.flutter.plugin.common.PluginRegistry)' on a null object reference, null)
E/flutter ( 6831): #0 JSONMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:149:7)
E/flutter ( 6831): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:302:33)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #2 AndroidAlarmManager.initialize (package:android_alarm_manager/android_alarm_manager.dart:76:10)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #3 main (package:alarmdemo/main.dart:12:29)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #4 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #5 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #6 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #7 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #8 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #9 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #10 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #11 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method AlarmService.initialized on channel plugins.flutter.io/android_alarm_manager_background)
E/flutter ( 6831): #0 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:300:7)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #1 _alarmManagerCallbackDispatcher (package:android_alarm_manager/android_alarm_manager.dart:49:12)
E/flutter ( 6831): #2 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #3 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #4 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #5 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #6 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #7 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #8 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #9 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
这是我更新后的代码:
main.dart
:
void printHello() {
final DateTime now = new DateTime.now();
final int isolateId = Isolate.current.hashCode;
print("[$now] Hello, world! isolate=${isolateId}
function='$printHello'");
}
void main() async {
runApp(MaterialApp(home: Application()));
}
class Application extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: RaisedButton(
child: Text('Hello'),
onPressed: () {
runAlarm();
},
),
),
),
);
}
void runAlarm() {
AndroidAlarmManager.oneShot(
Duration(seconds: 10),
0,
printHello,
wakeup: true,
).then((val) => print(val));
}
static void alarmTest() {
print("test");
}
}
它不会向控制台打印任何错误,但会打印以下两行:
E/AlarmService(11943): Fatal: failed to find callback
I/AlarmService(11943): AlarmService has not yet started.
我也尝试初始化警报管理器,但它向控制台打印错误:
void runAlarm() {
AndroidAlarmManager.periodic(
Duration(seconds: 10),
0,
printHello,
wakeup: true,
).then((val) => print(val)).catchError((e) {
print(e);
});
}
错误:
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: PlatformException(error, Attempt to invoke interface method 'void io.flutter.plugin.common.PluginRegistry$PluginRegistrantCallback.registerWith(io.flutter.plugin.common.PluginRegistry)' on a null object reference, null)
E/flutter ( 6831): #0 JSONMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:149:7)
E/flutter ( 6831): #1 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:302:33)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #2 AndroidAlarmManager.initialize (package:android_alarm_manager/android_alarm_manager.dart:76:10)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #3 main (package:alarmdemo/main.dart:12:29)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #4 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #5 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #6 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #7 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #8 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #9 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #10 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #11 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
E/flutter ( 6831): [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: MissingPluginException(No implementation found for method AlarmService.initialized on channel plugins.flutter.io/android_alarm_manager_background)
E/flutter ( 6831): #0 MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:300:7)
E/flutter ( 6831): <asynchronous suspension>
E/flutter ( 6831): #1 _alarmManagerCallbackDispatcher (package:android_alarm_manager/android_alarm_manager.dart:49:12)
E/flutter ( 6831): #2 _runMainZoned.<anonymous closure>.<anonymous closure> (dart:ui/hooks.dart:189:25)
E/flutter ( 6831): #3 _rootRun (dart:async/zone.dart:1124:13)
E/flutter ( 6831): #4 _CustomZone.run (dart:async/zone.dart:1021:19)
E/flutter ( 6831): #5 _runZoned (dart:async/zone.dart:1516:10)
E/flutter ( 6831): #6 runZoned (dart:async/zone.dart:1500:12)
E/flutter ( 6831): #7 _runMainZoned.<anonymous closure> (dart:ui/hooks.dart:180:5)
E/flutter ( 6831): #8 _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:300:19)
E/flutter ( 6831): #9 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
E/flutter ( 6831):
您没有初始化警报对象和回调处理程序。
await AndroidAlarmManager.initialize();
当应用程序启动时会发生什么运行宁此:
void main() async {
runApp(MaterialApp(home: Application()));
}
应用程序只是 运行 并为您绘制 UI。单击按钮后,将调用以下方法:
AndroidAlarmManager.oneShot(
Duration(seconds: 10),
0,
printHello,
wakeup: true,
)
此函数只是在指定的延迟时间后安排回调。这将失败,因为回调处理程序未注册。意思是,超时后,它找不到 'anyone' 负责 运行 和 'printHello'。
编辑:
您还需要覆盖一个方法来帮助插件在创建时自行注册。
像下面这样创建一个新文件:
yourapprootfolder/android/app/src/main/java/io/flutter/plugins/androidalarmmanagerexample/Application.java
在 .java 文件中,放入:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
或在 Kt 文件中:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
class Application : FlutterApplication(), PluginRegistrantCallback {
override fun onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
override fun registerWith(registry: PluginRegistry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
如果您只为 android 开发此应用程序,那么您可以为每个给定的时间间隔创建 native foreground/background service
,其中 运行s。然后使用 platform channel
你可以在 button
上调用来自 dart 的服务,如果你想要它 运行 每次在特定条件下或使用 shared prefrence
从 initState()
在你的主页。正如您可能知道的那样,一旦本机服务启动,它将在每个给定的时间间隔( 分钟或 24 小时 )后调用自身。
你是在 AndroidManifest.xml 中引用你 Application
吗?顺便说一句(我会使用不同的名称,以免与 Android 的 Application
混淆,例如 MyFlutterApplication
)。
the documentation of the plugin 中的通知指出:
Which must be reflected in the application's AndroidManifest.xml. E.g.:
<application
android:name=".Application"
...
有关详细信息,请参阅 Android Developers element documentation。
我遇到了同样的问题。只需打开 android 项目。执行 Gradle 同步。接下来,执行 "build -> clean project" 和 "build -> rebuild project".
问题:未处理的异常:MissingPluginException(未在通道 plugins.flutter.io/android_alarm_manager_background 上找到方法 AlarmService.initialized 的实现)
原因:Alarm回调会需要访问其他Flutter插件,包括alarmmanager插件本身,需要教会后台服务如何初始化插件。由于 AlarmManager 使用单独的 isolate,任何在调度代码中使用的插件都需要单独为 AlarmManager 初始化。
解决方案:在Application.java
中注册alarm manager插件本身如下;(已解决官方flutter repo问题#21969)
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
import io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
// GeneratedPluginRegistrant.registerWith(registry);
AndroidAlarmManagerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin"));
}
}
*Note: if you have used another plugins in your project, You would have also add it all into your
Application.java
file.
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
// GeneratedPluginRegistrant.registerWith(registry);
//add AndroidAlarmManagerPlugin plugin register if you work with arlarm
AndroidAlarmManagerPlugin.registerWith(registry.registrarFor("io.flutter.plugins.androidalarmmanager.AndroidAlarmManagerPlugin"));
//add PathProviderPlugin plugin register if you work with Access Path Device
PathProviderPlugin.registerWith(registry.registrarFor("io.flutter.plugins.pathprovider.PathProviderPlugin"));
//add SqflitePlugin plugin register if you work with sqflite
SqflitePlugin.registerWith(registry.registrarFor("com.tekartik.sqflite.SqflitePlugin"));
//add PermissionHandlerPlugin plugin register if you work with permission handler
PermissionHandlerPlugin.registerWith(registry.registrarFor("com.baseflow.permissionhandler.PermissionHandlerPlugin"));
//add SharedPreferencesPlugin plugin register if you work with share preferences
SharedPreferencesPlugin.registerWith(registry.registrarFor("io.flutter.plugins.sharedpreferences.SharedPreferencesPlugin"));
// something else...
}
}
经过几个小时的努力(但感觉时间长了很多!),我终于自己解决了这个问题。当我实际克隆包含 android_alarm_manager
的 Flutter Plugins Github repository 并查看示例代码并查看它在 IDE 中的布局时,突破出现了,而不是在线查看孤立的文件。
如果您不精通 Android Java 开发,自述文件并不清楚具体要做什么,但是当您查看工作示例代码时就会清楚。
您需要将示例目录中提供的 Application.java
文件放入您的实际项目中,与现有 MainActivity.java
文件位于同一文件夹中。内容应如下所示:
package io.flutter.plugins.androidalarmmanagerexample;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
AlarmService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
GeneratedPluginRegistrant.registerWith(registry);
}
}
至于你需要把这个文件放在哪里,他们的例子是这样的,但你的可能是这样的 <your project dir>/android/app/src/main/java/com/example/<your project name>
:
完成此操作后,您必须将Application.java
第一行的包名称从package io.flutter.plugins.androidalarmmanagerexample;
更新为匹配您的项目使用的任何包(请参阅您现有 MainActivity.java
的第一行)。如果您不这样做,gradle 将找不到它并且没有任何效果!
您现在可以按照 Readme 中的建议,添加权限等:
After importing this plugin to your project as usual, add the following to your
AndroidManifest.xml
within the<manifest></manifest>
tags:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Next, within the
<application></application>
tags, add:
<service
android:name="io.flutter.plugins.androidalarmmanager.AlarmService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false"/>
<receiver
android:name="io.flutter.plugins.androidalarmmanager.AlarmBroadcastReceiver"
android:exported="false"/>
<receiver
android:name="io.flutter.plugins.androidalarmmanager.RebootBroadcastReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"></action>
</intent-filter>
</receiver>
最后一部分是我最困惑的部分。听起来他们很含糊,但如果你之前做的一切都完全正确,那实际上正是你需要做的。
Which must be reflected in the application's AndroidManifest.xml. E.g.:
<application
android:name=".Application"
...
只需将您的 android:name
更改为 .Application
,这意味着它现在将利用我们之前添加的 Application.java
。
就是这样!希望您现在可以 运行 您的应用程序。