Not launching the app on notification click? Flutter Local Notifications - android

I am working on a project, I have used Flutter Local Notifications to show periodic notifications,
I'm trying to figure out if there is a way to not to launch the app on notification click, for example, when a user clicks on a notification, it should just disappear from the notification panel.
This is the code I tried so far,
Initialising,
var initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
_notificationPlugin = FlutterLocalNotificationsPlugin();
_notificationPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
Calling,
Future getPeriodicNoification() async {
print("hello");
// Show a notification every minute with the first appearance happening a minute after invoking the method
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your channel id',
'your channel name',
'your channel description',
importance: Importance.Max,
priority: Priority.High,
);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await _notificationPlugin.periodicallyShow(0, 'repeating title',
'repeating body', RepeatInterval.EveryMinute, platformChannelSpecifics);
}
Callback function(On notification click)
Future onSelectNotification(String payload) async {
ThisisAnAsyncFunction();
}
Please help.

You can use the close function under BehaviourSubject that you use when adding the payload.
static final onNotifications = BehaviorSubject<String?>();
then call this when selecting the notification.
onSelectNotification() => onNotifications.close();

Related

Flutter Firebase Messaging: Messages not displayed on Android

I'm working on a Flutter App with Firebase Messaging. The notifications work perfectly fine on iOS. On Android, they work when the app is in the foreground, but are not displayed when the app is in background or terminated. I could already rule out doze mode, as the app has been put to background just seconds before triggering the message. The logfile also says, the message is received by the devices, but somehow not displayed.
The problem also only exists when the app is installed via .apk and not when I build directly with Android Studio, so I thought maybe the fingerprinting could cause the problem. But the messages are received by the device and just not displayed -> so that's not it either, right?
I use firebase_messaging: ^12.0.0 as the plugin.
Here is the implementation of my background handler:
static Future<void> setUp() async {
await Firebase.initializeApp(
name: 'Firebase-App',
options: DefaultFirebaseOptions.currentPlatform,
);
//... iOS stuff
//Enable Foreground-Messages for Android
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.max,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
await configLocalNotification(flutterLocalNotificationsPlugin);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
//Display Foreground-Message on Android
flutterLocalNotificationsPlugin.show(
message.hashCode,
Uri.decodeComponent(message.data['title']).replaceAll('+', ' '),
Uri.decodeComponent(message.data['message']).replaceAll('+', ' '),
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: '#mipmap/ic_launcher',
importance: Importance.max,
),
),
payload: json.encode(message.data),
);
});
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true, badge: true, sound: true);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
static Future<void> _firebaseMessagingBackgroundHandler(
RemoteMessage message) async {
await Firebase.initializeApp();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.max,
);
await flutterLocalNotificationsPlugin.show(
message.hashCode,
Uri.decodeComponent(message.data['title']).replaceAll('+', ' '),
Uri.decodeComponent(message.data['message']).replaceAll('+', ' '),
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
icon: '#mipmap/ic_launcher',
importance: Importance.max,
// other properties...
),
),
payload: json.encode(message.data),
);
}
static Future<void> configLocalNotification(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) async {
const initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
const initializationSettingsIOS = IOSInitializationSettings();
const initializationSettings = InitializationSettings(
iOS: initializationSettingsIOS, android: initializationSettingsAndroid);
//Handle on click event when App is in foreground or background
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
//handle on click event when app is terminated
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
final String? selectedNotificationPayload =
notificationAppLaunchDetails!.payload;
debugPrint(
'notification payload on launch: $selectedNotificationPayload');
await onSelectNotification(selectedNotificationPayload);
}
}
Thanks in advance for your help, I'm really at the end of the line here!

Flutter: How to open the App when notification arrives from FirebaseMessaging (without user action)

I'm working on a communication app, and currently implementing Video and Voice calls.
I want when a notification arrives to the app, I want the app to open on specific screen.
I've done something like that by showing a notification and the app opens when user press on the notification.
But when a call arrives I want the app open without the action of the user.
I've tried to open the app with external_app_launcher but it doesn't open.
Here is the code.
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print('Message In background: ${message.data}');
LaunchApp.openApp(androidPackageName: "com.example.chat_app");
}
This is the code I tried to do to open the app.
And here is my old code that shows a notification(It works without any problem)
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print('Message In background: ${message.data}');
var initializationSettingsAndroid =
const AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOs = const IOSInitializationSettings();
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOs,
);
//when the app is in foreground state and you click on notification.
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String? payload) {
if (payload != null) {
Map<String, dynamic> data = json.decode(payload);
goToNextScreen(data, true);
}
});
flutterLocalNotificationsPlugin.show(
Random().nextInt(1000000000),
message.data['title'],
message.data["body"],
NotificationDetails(
android: AndroidNotificationDetails(channel.id, channel.name,
channelDescription: channel.description,
importance: Importance.max,
priority: Priority.high,
playSound: true,
sound: RawResourceAndroidNotificationSound("ringtone1"),
fullScreenIntent: true),
),
payload: json.encode(message.data));
}
As far as I know, it is not possible to automatically open an app on the receipt of an FCM message.
As a user, I'd probably immediately uninstall any app that does this.

Flutter android_alarm_manager_plus does not work reliably

I want to schedule daily notifications at a specific daytime with the android_alarm_manager_plus and the local_notifications plugins.
However, the notifications come in very irregulary. The delay of the notifications increases each consecutive day.
For example, the app should send a reminder everyday at 8:00 am. The first day, the notification comes in at around the right time. The next day, it sends it 15 minutes delayed and the following days, no notification gets send at all.
I tested this on a Motorola Moto G9 Play with Android 11 and I have deactivated the energy-saving mode and made sure that battery-optimizations are turned off for this app.
In the following I created a litte (hopefully) reproducable example:
// initializing similar to the official example
Future<FlutterLocalNotificationsPlugin> _initNotificationsPlugin() async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('flutter_logo');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings();
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
return flutterLocalNotificationsPlugin;
}
Future<void> scheduleNotifications() async {
int id = 0;
AndroidAlarmManager.periodic(Duration(days: 1), id, sendNotification,
exact: true,
allowWhileIdle: true,
rescheduleOnReboot: true,
wakeup: true);
log("Notifications scheduled");
}
// Top-level callback for the AndroidAlarmManager
Future<void> sendNotification() async {
FlutterLocalNotificationsPlugin flutterNotificationsPlugin =
await _initNotificationsPlugin();
await flutterNotificationsPlugin.cancelAll();
final now = DateTime.now();
int id =
now.second + now.minute * 60 + now.hour * 60 * 60; // Daytime in seconds
// Copied from the example with edited channel id, etc.
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'my very own channel id', 'my very own channel name',
channelDescription: 'my channel description',
importance: Importance.max,
priority: Priority.high,
ticker: 'ticker');
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
//
final body = "Notification sent at ${now.hour}:${now.minute}:${now.second}";
await flutterNotificationsPlugin.show(
id, "Test notification", body, platformChannelSpecifics);
log(body);
}
Future<void> cancelAllAlarmsAndNotifications() async {
await AndroidAlarmManager.cancel(0);
}
And when the user clicks a button, the following code is executed:
onPressed: () {
cancelAllAlarmsAndNotifications().then((value) {
scheduleNotifications();
});
},
Also, the main method:
void main() {
WidgetsFlutterBinding.ensureInitialized();
AndroidAlarmManager.initialize().then((value) {
runApp(const MyApp());
});
}
I really hope that you see some mistake I make that is easy fixable :)
Thanks in advance!

Why Flutter Android Alarm Manager is not working in device once the App is closed?

I am new to flutter.
Alarm functionality is working unless the app is closed.
After closing the app android alarm manager is not working.
I have put all the tags in AndroidManifest.xml.
On call back this _ringAlarm() method has been called.
Future<void> _ringAlarm() async {
NotificationManager n = new NotificationManager();
n.initNotificationManager();
n.showNotificationWithDefaultSound("Keep it,it's YOURS", widget.text.split("_")[1]);
//n.showNotificationWithAlarmSound();
//Working in Simulator but not in Device
//n._showNotificationCustomSound();
//FlutterRingtonePlayer.playAlarm();
FlutterRingtonePlayer.play(
android: AndroidSounds.alarm,
ios: IosSounds.glass,
looping: false, // Android only - API >= 28
volume: 1, // Android only - API >= 28
asAlarm: false, // Android only - all APIs
);
Future.delayed(const Duration(milliseconds: 4000), () {
FlutterRingtonePlayer.stop();
});
print(Const.todoTextList);
}
Here is implementation of notification manager class
class NotificationManager
{
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
AndroidInitializationSettings initializationSettingsAndroid;
IOSInitializationSettings initializationSettingsIOS;
InitializationSettings initializationSettings;
void initNotificationManager()
{
initializationSettingsAndroid = new AndroidInitializationSettings('#mipmap/ic_launcher');
initializationSettingsIOS = new IOSInitializationSettings();
initializationSettings = new InitializationSettings(initializationSettingsAndroid, initializationSettingsIOS);
flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
void showNotificationWithDefaultSound(String title, String body)
{
var androidPlatformChannelSpecifics = new AndroidNotificationDetails('your channel id', 'your channel name', 'your channel description', importance: Importance.Max, priority: Priority.High);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
flutterLocalNotificationsPlugin.show(0, title, body, platformChannelSpecifics);
}
static const MethodChannel platform = MethodChannel('your channel name');
/* Future<void> showNotificationWithAlarmSound() async {
/// this calls a method over a platform channel implemented within the
/// example app to return the Uri for the default alarm sound and uses
/// as the notification sound
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
final String alarmUri = await platform.invokeMethod('getAlarmUri');
final UriAndroidNotificationSound uriSound =
//UriAndroidNotificationSound(AndroidSounds.alarm.toString());
UriAndroidNotificationSound(alarmUri);
final AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'uri channel id', 'your channel name', 'your channel description',
sound: uriSound,
styleInformation: const DefaultStyleInformation(true, true));
final NotificationDetails platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics,iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0, 'uri sound title', 'uri sound body', platformChannelSpecifics);
}*/
//For custom notification
Future<void> _showNotificationCustomSound() async {
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(
'your other channel id',
'your other channel name',
'your other channel description',
sound: RawResourceAndroidNotificationSound('easy_going'),
);
const IOSNotificationDetails iOSPlatformChannelSpecifics =
IOSNotificationDetails(sound: 'easy_going');
//const MacOSNotificationDetails macOSPlatformChannelSpecifics =
//MacOSNotificationDetails(sound: 'slow_spring_board.aiff');
const NotificationDetails platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
'custom sound notification title',
'custom sound notification body',
platformChannelSpecifics);
}
}
It is working good if I don't close actual app.Once I close the app notification will not work.I am unable to reproduce this issue in simulator.If I get any suggestion how to reproduce this in simulator that also will be helpful to me.

Dismiss notification on click

I am using Flutter Local Notification to trigger periodic notifications in my app.
It provides a callback, which is executed when user taps on the notification,
I want to use the callback to run a async function, but i don't want to launch the app when the user clicks on it. I simply want to dismiss the notification.
Is there any way to achieve it?
Here is my code.
var initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
_notificationPlugin = FlutterLocalNotificationsPlugin();
_notificationPlugin.initialize(
initializationSettings,
onSelectNotification: onSelectNotification,
);
My callback function,
Future onSelectNotification(String payload) async {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text("Hello"),
content: Text("content"),
),
);
AnAsyncFunction();
}
Notification triggering function,
Future getPeriodicNoification() async {
print("hello");
// // Show a notification every minute with the first appearance happening a minute after invoking the method
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your channel id',
'your channel name',
'your channel description',
importance: Importance.Max,
priority: Priority.High,
);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await _notificationPlugin.periodicallyShow(0, 'repeating title',
'repeating body', RepeatInterval.EveryMinute, );
}

Categories

Resources