Android Alarm Manager不适用于Flutter Project App

时间:2019-02-19 04:59:30

标签: android dart flutter alarmmanager

Error 我已经在New Flutter应用中安装了Android Alarm Manager插件。我使用了Plugin-的示例代码,但它在控制台中给出了错误。

请提出如何使android警报管理器插件正常工作的建议。 如何将Dart的android_alarm_manager集成到应用程序中,以便用户在计划中选择的时间到达时收到警报?

我使用此链接中的代码: 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);
        }
    }



///// When I run this code it gives error in console as given below://////

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");
  }

}

It does not give any Error in console but print two statements as below:

E/AlarmService(11943): Fatal: failed to find callback
I/AlarmService(11943): AlarmService has not yet started.


I also initialize the alarm manager but it gives error in console:


 void runAlarm() {
    AndroidAlarmManager.periodic(
      Duration(seconds: 10),
      0,
      printHello,
      wakeup: true,
    ).then((val) => print(val)).catchError((e) {
      print(e);
    });
  }


Error:

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): 

enter image description here

6 个答案:

答案 0 :(得分:3)

经过几个小时的努力,我终于自己解决了这个问题(但是感觉更长了!)。当我真正克隆包含android_alarm_manager的{​​{3}}并浏览示例代码并查看其在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>之类的地方:

Flutter Plugins Github repository

完成此操作后,您必须Application.java更新package io.flutter.plugins.androidalarmmanagerexample;第一行的软件包名称,以匹配您的项目使用的任何软件包(请参见您的第一行现有MainActivity.java)。如果您不这样做,则gradle找不到它,并且一切正常!

您现在可以按照The Application.java file goes in the same folder as your MainActivity.java中的建议,添加权限等:

  

将此插件照常导入项目后,请在AndroidManifest.xml标签内的<manifest></manifest>中添加以下内容:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
  

接下来,在<application></application>标签内,添加:

<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>

最后一部分是最让我困惑的部分。听起来他们好像很模糊,但是如果您早些时候就做完了其他所有事情,那实际上就是您需要做的事情。

  

必须在应用程序的AndroidManifest.xml中反映出来。例如:

    <application
        android:name=".Application"
        ...

只需将您的android:name更改为.Application,这意味着它将利用我们先前添加的Application.java

就是这样!希望您现在可以运行您的应用。

答案 1 :(得分:1)

我有同样的问题。只需打开android项目。执行Gradle同步。接下来,执行“构建->清理项目”和“构建->重建项目”。

答案 2 :(得分:1)

问题:未处理的异常:MissingPluginException(在通道plugins.flutter.io/android_alarm_manager_background上未针对方法AlarmService.initialized找到实现)

原因:警报回调将需要访问其他Flutter插件,包括警报管理器插件本身,有必要教后台服务如何初始化插件。由于AlarmManager使用单独的隔离,因此需要单独为AlarmManager初始化计划代码中使用的任何插件。

解决方案:如下所述在Application.java中注册警报管理器插件本身;(已解决的官方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"));
  }
}

答案 3 :(得分:0)

您没有初始化警报对象和回调处理程序。

  

等待AndroidAlarmManager.initialize();

当应用程序开始运行时会发生什么:

 void main() async {
    runApp(MaterialApp(home: Application()));
 }

该应用程序将运行并为您绘制UI。单击按钮后,将调用以下方法:

AndroidAlarmManager.oneShot(
   Duration(seconds: 10),
   0,
   printHello,
   wakeup: true,
)

此函数只是在指定的延迟时间之后安排回调。这将失败,因为未注册回调处理程序。意思是,在超时后,找不到负责运行“ 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);
      }
}

答案 4 :(得分:0)

如果您仅为Android开发此应用,则可以创建native foreground/background service,该应用在每个给定的时间间隔内运行。然后,使用platform channel可以从dart调用服务,如果您希望每次都在特定条件下运行,请在button上点击,或者使用shared prefrenceinitState()调用本地服务在您的首页中。您可能知道,一旦启动本机服务,它就会在每个给定的时间间隔(如分钟或24小时)后调用自身。

答案 5 :(得分:0)

您是否在AndroidManifest.xml中引用了Application?顺便说一句(我将使用其他名称来与Android的Application保持一致,例如MyFlutterApplication)。

the documentation of the plugin中的通知中指出:

  

必须在应用程序的AndroidManifest.xml中反映出来。例如:

<application
    android:name=".Application"
    ...

有关更多信息,请参见Android Developers element documentation