Deprecated function: Return type of Drupal\Core\Database\StatementWrapper::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in include() (line 10 of /mnt/web521/d1/47/510241947/htdocs/thomaskaemmerling.de/core/lib/Drupal/Core/Database/StatementWrapper.php).
include('/mnt/web521/d1/47/510241947/htdocs/thomaskaemmerling.de/core/lib/Drupal/Core/Database/StatementWrapper.php') (Line: 444)
Composer\Autoload\includeFile('/mnt/web521/d1/47/510241947/htdocs/thomaskaemmerling.de/vendor/composer/../../core/lib/Drupal/Core/Database/StatementWrapper.php') (Line: 322)
Composer\Autoload\ClassLoader->loadClass('Drupal\Core\Database\StatementWrapper') (Line: 557)
Drupal\Core\Database\Connection->prepareStatement('SELECT "cid", "data", "created", "expire", "serialized", "tags", "checksum" FROM "n99r_cache_container" WHERE "cid" IN ( :cids__0 ) ORDER BY "cid"', Array) (Line: 822)
Drupal\Core\Database\Connection->query('SELECT [cid], [data], [created], [expire], [serialized], [tags], [checksum] FROM {cache_container} WHERE [cid] IN ( :cids__0 ) ORDER BY [cid]', Array, Array) (Line: 97)
Drupal\Core\Database\Driver\mysql\Connection->query('SELECT [cid], [data], [created], [expire], [serialized], [tags], [checksum] FROM {cache_container} WHERE [cid] IN ( :cids[] ) ORDER BY [cid]', Array) (Line: 113)
Drupal\Core\Cache\DatabaseBackend->getMultiple(Array, ) (Line: 92)
Drupal\Core\Cache\DatabaseBackend->get('service_container:prod:9.1.4::Linux:a:1:{i:0;s:82:"/mnt/web521/d1/47/510241947/htdocs/thomaskaemmerling.de/sites/default/services.yml";}') (Line: 547)
Drupal\Core\DrupalKernel->getCachedContainerDefinition() (Line: 892)
Drupal\Core\DrupalKernel->initializeContainer() (Line: 471)
Drupal\Core\DrupalKernel->boot() (Line: 705)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Flutter Benachrichtigungen an Benutzer senden, während die App ausgeschaltet ist | Thomas Kämmerling

Flutter Benachrichtigungen an Benutzer senden, während die App ausgeschaltet ist

Gespeichert von Thomas am Fr., 12.02.2021 - 20:09

Um Benachrichtigungen zu erzeugen kann das Module flutter_local_notifications verwendet werden.

Hiermit kann auf einfache Art eine Benachrichtigung erzeugt werden.

Hinweise zur Installation finden Sie auf der flutter_local_notifications Modulseite.

Damit man auch Nachrichten an den Benutzer senden kann, wenn die App ausgeschaltet ist kann das Modul background_fetch verwendet werden.
Über dieses Modul ist es möglich einen sogenannten Headless Task zu implementieren was es erlaubt dem Benutzer Dart Code in regelmäßigen abständen auszuführen, auch wenn die App wieder geschlossen wurde.

So kann eine Routine implementiert werden, in der eine Benachrichtigung an den Benutzer gesendet wird, auch wenn die App geschlossen ist.

 

Hier ein Beispiel für die Implementierung eines Backgroundservice der Benachrichtigungen über Android versendet:


import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:rxdart/subjects.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:background_fetch/background_fetch.dart';

final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
    FlutterLocalNotificationsPlugin();

/// Streams are created so that app can respond to notification-related events
/// since the plugin is initialised in the `main` function
final BehaviorSubject didReceiveLocalNotificationSubject =
    BehaviorSubject();

final BehaviorSubject selectNotificationSubject =
    BehaviorSubject();

const MethodChannel platform =
    MethodChannel('thomaskaemmerling.de/flutter_local_notifications_beans');

class ReceivedNotification {
  ReceivedNotification({
    @required this.id,
    @required this.title,
    @required this.body,
    @required this.payload,
  });

  final int id;
  final String title;
  final String body;
  final String payload;
}

String selectedNotificationPayload;

class Remindermessage {
  static Databaselayer dbl = new Databaselayer();

  /// This "Headless Task" is run when app is terminated.
  static void backgroundFetchHeadlessTask(String taskId) async {
    print("[BackgroundFetch] Headless event received: $taskId");

    BackgroundFetch.finish(taskId);
    final NotificationAppLaunchDetails notificationAppLaunchDetails =
        await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();

    if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
      selectedNotificationPayload = notificationAppLaunchDetails.payload;
    }

    // Als Parameter wird hier ein Icon 
    // oder ein Bild aus dem Ordner
    // android\app\src\main\res\drawable angegeben werden. 
    // Das kann eine png datei sein. Der Dateinamen wird dann ohne Endung
    // eingetragen

    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings("note");

    /// Note: permissions aren't requested here just to demonstrate that can be
    /// done later
    final IOSInitializationSettings initializationSettingsIOS =
        IOSInitializationSettings(
            requestAlertPermission: false,
            requestBadgePermission: false,
            requestSoundPermission: false,
            onDidReceiveLocalNotification:
                (int id, String title, String body, String payload) async {
              didReceiveLocalNotificationSubject.add(ReceivedNotification(
                  id: id, title: title, body: body, payload: payload));
            });
    const MacOSInitializationSettings initializationSettingsMacOS =
        MacOSInitializationSettings(
            requestAlertPermission: false,
            requestBadgePermission: false,
            requestSoundPermission: false);
    final InitializationSettings initializationSettings =
        InitializationSettings(
            android: initializationSettingsAndroid,
            iOS: initializationSettingsIOS,
            macOS: initializationSettingsMacOS);
    await flutterLocalNotificationsPlugin.initialize(initializationSettings,
        onSelectNotification: (String payload) async {
      if (payload != null) {
        debugPrint('notification payload: $payload');
      }
      selectedNotificationPayload = payload;
      selectNotificationSubject.add(payload);
    });
    _showNotification();
  }

  

  static Future _showNotification() async {
    DrawableResourceAndroidBitmap bmp =
        new DrawableResourceAndroidBitmap("@mipmap/ic_launcher");
    // als Bild kann hier ein App Icon oder Bild aus dem Ordner
    // android\app\src\main\res\drawable angegeben werden. 
    // Das kann eine png datei sein. Der Dateinamen wird dann ohne Endung
    // eingetragen
    
    AndroidNotificationDetails androidPlatformChannelSpecifics =
        AndroidNotificationDetails('thomaskaemmerling.de',
            'flutter_local_notifications_beans', 'beansnotes',
            importance: Importance.max,
            priority: Priority.high,
            ticker: 'ticker',
            largeIcon: bmp);
    NotificationDetails platformChannelSpecifics =
        NotificationDetails(android: androidPlatformChannelSpecifics);
    await flutterLocalNotificationsPlugin.show(
        0,
        'Betreff'‚'Nachricht Lorem ipsum dolor sit amet, consetetur sadipscing elitr',
        platformChannelSpecifics,
        payload: 'unused');
  }

  static void startReminderService() {
    // Regestrieren einer Funktion die als Headless Task ausgeführt werden                
    // soll
    BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
    
    // Headless Ausführung starten im angegenen Intervall
    BackgroundFetch.scheduleTask(TaskConfig(
        taskId: "de.thomaskaemmerling.reminderservice",
        delay: 900000,
        periodic: true,
        forceAlarmManager: true,
        stopOnTerminate: false,
        enableHeadless: true));
  }
}