As notificações alertam os usuários sobre informações importantes sobre os aplicativos e serviços que eles assinaram. Eles têm como objetivo melhorar a experiência do usuário e aumentar o envolvimento em um aplicativo.

Quando se trata de aplicativos móveis, há dois tipos de notificações: notificações push e notificações locais. Neste artigo, implementaremos notificações locais nas plataformas Android e iOS usando o flutter
_local_notifications
pacote.

Usar notificações locais é uma maneira de interagir com seus usuários e chamar a atenção deles de volta para o seu aplicativo sem o uso de uma conexão com a Internet e aplicativos como Reminder e aplicativos de tarefas fazem uso pesado deles. Eles geralmente são pré-programados e disparam quando certas ações são realizadas pelo usuário no aplicativo.

A principal diferença entre notificações locais e push é que as notificações locais são agendadas por um aplicativo localmente e são entregues pelo mesmo dispositivo, enquanto as notificações push são enviadas de um servidor remoto. Vamos construir um projeto para que você possa ver como as notificações locais funcionam.

Adicionando dependências ao aplicativo Flutter

A primeira etapa é executar o comando abaixo em seu terminal para adicionar o mais recente versão de flutter_local_notifications para seu arquivo pubspec.yaml.

//execute este comando no terminal $ flutter pub add flutter_local_notifications

Em seguida, crie um novo arquivo Dart chamado notification_service.dart. Você pode dar a ele qualquer nome de arquivo que desejar, mas prefiro nomear os arquivos de acordo com sua funcionalidade.

No Flutter, é uma prática recomendada isolar sua lógica de sua IU. Para fazer isso, criaremos uma classe chamada NotificationService no arquivo notification_service.dart. Esta classe tratará de toda a lógica de notificação e exporá métodos para criar, enviar, agendar e cancelar notificações.

import’package: flutter_local_notifications/flutter_local_notifications.dart’; class NotificationService {//Padrão Singleton static final NotificationService _notificationService=NotificationService._internal (); Factory NotificationService () {return _notificationService; } NotificationService._internal ();//instância de FlutterLocalNotificationsPlugin final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin=FlutterLocalNotificationsPlugin (); }

Vamos analisar o que está acontecendo no código acima:

Usamos o padrão singleton para criar a classe NotificationService. Além disso, na linha 12, criamos uma instância do FlutterLocalNotificationsPlugin, que inicializa as configurações de notificação local do Flutter para as plataformas Android e iOS.

Definindo configurações de inicialização específicas da plataforma

Vamos examinar como podemos definir as configurações de inicialização para as plataformas Android e iOS.

Definindo as configurações de inicialização do Android
Para definir as configurações de inicialização do Android, precisamos passar em um único necessário argumento, que é o ícone do aplicativo que seria exibido na barra de notificação:

final AndroidInitializationSettings initializationSettingsAndroid=AndroidInitializationSettings (‘app_icon’);

Agora precisamos adicionar nosso ícone como um recurso drawable ao projeto principal do Android. Este é o caminho completo para fazer isso:

YOUR_APPLICATION_FOLDER_NAME \ android \ app \ src \ main \ res \ drawable \ YOUR_APP_ICON.png

Definição das configurações de inicialização para iOS
Definir essas configurações para iOS é um pouco mais complicado porque temos que considerar as várias maneiras pelas quais as notificações são tratadas em diferentes versões do sistema operacional iOS.

Primeiro, adicione as seguintes linhas para o método didFinishLaunchingWithOptions no arquivo AppDelegate.swift de seu projeto iOS.

if #available (iOS 10.0, *) {UNUserNotificationCenter.current (). delegate=self as? UNUserNotificationCenterDelegate}

Nosso arquivo AppDelegate.swift deve ser parecido com este:

import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate {aplicativo de substituição (_ application: UIApplication, didFinishLaunchingWithOptions: [UIApplication.LithOpplictions: ]?)-> Bool {if #available (iOS 10.0, *) {UNUserNotificationCenter.current (). Delegate=self as UNUserNotificationCenterDelegate} GeneratedPluginRegistrant.register (with: self) return super.application (application, didFinishLaunchingWithOptions: launchOptions)}

O objeto IOSInitializationSettings aceita três argumentos: requestSoundPermission, requestBadgePermission e requestAlertPermission. Esses argumentos controlam qual permissão está sendo solicitada do usuário.

Dependendo do seu caso de uso, você pode optar por definir todas as permissões de notificação como falsas e, em seguida, chamar o método requestIOSPermissions com as permissões desejadas no ponto apropriado em seu aplicativo, conforme mostrado abaixo.

//Configurações de inicialização para dispositivos iOS final IOSInitializationSettings initializationSettingsIOS=IOSInitializationSettings (requestSoundPermission: false, requestBadgePermission: false, requestAlertPermission: false,); void requestIOSPermissions (FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) {flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation ()?.requestPermissions, badge: true; true; }

Criando o objeto InitializationSettings

A próxima etapa é criar um objeto InitializationSettings. Este plug-in é usado para inicializar as configurações das plataformas Android e iOS.

Geralmente, o InitializationSettings tem três parâmetros opcionais nomeados, android, iOS e macOS, e eles aceitam os argumentos das configurações de inicialização da plataforma correspondentes.

final InitializationSettings initializationSettings=InitializationSettings (android: initializationSettingsAndroid, iOS: initializationSettingsIOS);

Seguindo a configuração de nossas configurações de inicialização específicas da plataforma, criaríamos o método init, que conteria toda a nossa lógica de configurações de inicialização e seria chamado de nosso arquivo main.dart na inicialização do aplicativo.

Future init () async {//Configurações de inicialização para Android final AndroidInitializationSettings initializationSettingsAndroid=AndroidInitializationSettings (‘app_icon’);//Configurações de inicialização para iOS final IOSInitializationSettings initializationSettingsIOS=IOSInitializationSettings (requestSoundPermission: false, requestBadgePermission: false, requestAlertPermission: false,);//InitializationSettings para configurações de inicialização para ambas as plataformas (Android e iOS) final InitializationSettings initializationSettings=InitializationSettings (android: initializationSettingsAndroid, iOS: initializationSettingsIOS); aguarde flutterLocalNotificationsPlugin.initialize (initializationSettings,); }

No código acima, passamos nossas configurações de inicialização específicas da plataforma para o objeto InitializationSettings.

A próxima etapa é chamar o método initialize no objeto FlutterLocalNotificationsPlugin. Este método aceita dois argumentos, o objeto InitializationSettings e a propriedade onSelectNotification.

A propriedade onSelectNotification aceita uma função de retorno de chamada que será disparada quando a notificação for tocada. Esta função contém um único argumento obrigatório chamado de carga útil, que contém todos os dados que são passados ​​pela notificação.

Future selectNotification (String payload) async {await Navigator.push (context, MaterialPageRoute (builder: (context )=> SecondScreen (carga útil)),); }

Aqui, esta função de retorno de chamada acionará a navegação para SecondScreen e exibirá a carga associada à notificação quando o usuário tocar na notificação.

Nosso método init deve se parecer com este agora:

Future init () async {//Configurações de inicialização para Android final AndroidInitializationSettings initializationSettingsAndroid=AndroidInitializationSettings (‘app_icon’);//Configurações de inicialização para iOS final IOSInitializationSettings initializationSettingsIOS=IOSInitializationSettings (requestSoundPermission: false, requestBadgePermission: false, requestAlertPermission: false,);//InitializationSettings para configurações de inicialização para ambas as plataformas (Android e iOS) final InitializationSettings initializationSettings=InitializationSettings (android: initializationSettingsAndroid, iOS: initializationSettingsIOS); aguarde flutterLocalNotificationsPlugin.initialize (initializationSettings, onSelectNotification: selectNotification); } Future selectNotification (String payload) async {await Navigator.push (context, MaterialPageRoute (builder: (context)=> SecondScreen (payload)),); }

Vamos voltar ao nosso arquivo main.dart. Na função principal, chamaremos o método init e o método requestiOSPermissions para solicitar permissões do usuário assim que o aplicativo for iniciado em dispositivos iOS.

Future main () async {WidgetsFlutterBinding.ensureInitialized (); aguardar NotificationService (). init ();//aguarda NotificationService (). requestIOSPermissions ();//runApp (MyApp ()); }

Exibindo uma notificação no Flutter

Para exibir uma notificação, precisamos criar uma instância NotificationDetails específica da plataforma, que leva em argumentos que são exclusivos para cada plataforma.

AndroidNotificationDetails lida com a configuração de notificações em dispositivos Android. Aceita vários argumentos, como channelID, channelName, channelDescription, priority, priority e assim por diante.

O iOSNotificationDetails lida com a configuração de notificações em dispositivos iOS e aceita argumentos como presentAlert, presentBadge, badgeNumber , subtítulo, som, etc.

Esta é a aparência da instância AndroidNotificationDetails:

AndroidNotificationDetails _androidNotificationDetails=AndroidNotificationDetails (‘ID do canal’,’nome do canal’,’descrição do canal’, playSound: true, prioridade: Prioridade.alta, importância: Importância.alta,);

Esta é a aparência da instância iOSNotificationDetails:

IOSNotificationDetails _iosNotificationDetails=IOSNotificationDetails (presentAlert: bool ?, presentBadge: bool ?, presentSound: bool ?, badgeNumber: int? attachments: List ? subtitle:? , threadIdentifier: String?);

Agora, a próxima etapa é criar um objeto NotificationDetails que recebe nossos objetos de detalhes de notificação específicos da plataforma como argumentos.

const NotificationDetails platformChannelSpecifics=NotificationDetails (android: _androidNotificationDetails, iOS: _iOSNotificationDetails);

Em seguida, precisamos chamar o método show do FlutterLocalNotificationsPlugin. O método show é responsável por criar notificações push e espera alguns argumentos como id, title, body, notificationDetails e payload.

id: identificador único de uma notificação
título: título para a notificação
corpo: a mensagem de notificação
notificationDetails: onde passamos o objeto notificationDetails
carga útil: contém os dados que são passados ​​pela notificação quando a notificação é tocada

aguarde flutterLocalNotificationsPlugin.show (0,’Título de notificação’,’Este é o corpo de notificação’, platformChannelSpecifics, carga útil:’Carga útil de notificação’,);

Agora, vamos criar um método showNotification e envolver toda essa lógica nele, então podemos chamar esse método de qualquer lugar para exibir uma notificação.

class NotificationService {…. Future showNotifications () async {await flutterLocalNotificationsPlugin.show (0,’Notification Title’,’This is the Notification Body’, platformChannelSpecifics, payload:’Notification Payload’,); }}

Agendando uma notificação local no Flutter

Para agendar uma notificação, precisamos chamar o método zoneSchedule do FlutterLocalNotificationsPlugin. Este método espera uma instância da classe TZDateTime, que é fornecida pelo pacote timezone.

Como o plug-in flutter_local_notifications já depende do pacote timezone, não há necessidade de adicionar o pacote timezone como uma dependência em nosso pubspec. arquivo yaml. Só temos que importá-lo em nosso arquivo notification_service.dart e inicializá-lo.

import’package: flutter_local_notifications/flutter_local_notifications.dart’; import’package: timezone/data/latest.dart’como tz; import’package: timezone/timezone.dart’como tz;…. Future init () async {final AndroidInitializationSettings initializationSettingsAndroid=AndroidInitializationSettings (‘app_icon’); final IOSInitializationSettings initializationSettingsIOS=IOSInitializationSettings (requestSoundPermission: false, requestBadgePermission: false, requestAlertPermission: false,); final InitializationSettings initializationSettings=InitializationSettings (android: initializationSettingsAndroid, iOS: initializationSettingsIOS);//inicializa o pacote de fuso horário aqui tz.initializeTimeZones ();//—-aguarda flutterLocalNotificationsPlugin.initialize (initializationSettings, onSelectNotification: selectNotification); }

O método zoneSchedule aceita vários argumentos, incluindo id, title, body, scheduleDate, notificationDetails, payload, uiLocalNotificationDateInterpretation e androidAllowWhileIdle.

O parâmetro scheduleDate especifica quando uma notificação deve ser exibida. androidAllowWhileIdle, quando definido como verdadeiro, garante que as notificações programadas sejam exibidas independentemente de o dispositivo estar no modo de baixa energia.

await flutterLocalNotificationsPlugin.zonedSchedule (0,”Título de notificação”,”Esta é a notificação Body!”, Tz.TZDateTime.now (tz.local).add (const Duração (segundos: 5)), platformChannelSpecifics, androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime);

Agora, vamos criar um método scheduleNotification e envolver toda essa lógica nele, então podemos chamar esse método de qualquer lugar para criar uma notificação agendada.

class NotificationService {…. Future scheduleNotifications ( ) async {await flutterLocalNotificationsPlugin.zonedSchedule (0,”Notification Title”,”This is the Notification Body!”, tz.TZDateTime.now (tz.local).add (const Duration (minutes: 5)), platformChannelSpecifics, androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime); }}

Cancelamento de uma notificação local no Flutter

Ao cancelar uma notificação, você pode cancelar uma notificação específica ou cancelar todas as notificações pendentes. Vamos ver como você pode fazer isso:

Cancelando uma única notificação
Para cancelar uma notificação específica, vamos criar um novo método chamado cancelNotification, que conterá o cancel método do objeto FlutterLocalNotificationsPlugin. Este método espera um argumento, que é o id da notificação.

class NotificationService {…. Future cancelNotifications () async {await flutterLocalNotificationsPlugin.cancel (NOTIFICATION_ID); }}

Cancelando todas as notificações
Para cancelar todas as notificações pendentes, vamos criar um novo método cancelAllNotifications, que conterá o método cancelAll do objeto FlutterLocalNotificationsPlugin.

Ao contrário de cancelar uma única notificação em que seu método aceita um único argumento, este método não aceita nenhum argumento.

class NotificationService {…. Future cancelAllNotifications () async {await flutterLocalNotificationsPlugin.cancelAll () ; }}

Este é um repositório GitHub que contém todo o código deste tutorial. Se você gostaria de ver a compilação final, simplesmente clone esse repositório e execute-o em seu computador.

Conclusão

Notificações locais são incrivelmente úteis para notificar ou alertar usuários sobre informações importantes , e podem ser implementados sem uma conexão com a Internet.

Você pode ler a documentação do pacote flutter_local_notifications para aprender outras maneiras de usar a notificação local em seus projetos.