flutter_local_notifications icon indicating copy to clipboard operation
flutter_local_notifications copied to clipboard

make actions without open app

Open Mohamed1226 opened this issue 1 year ago • 5 comments

can i make action with payload without open the app

Mohamed1226 avatar Dec 24 '24 17:12 Mohamed1226

What platform are you on? Have you tried setting AndroidNotificationAction.showsUserInterface to false?

Levi-Lesches avatar Dec 24 '24 17:12 Levi-Lesches

this is my code

import 'dart:developer'; import 'dart:io';

import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:get_it/get_it.dart'; import 'package:injectable/injectable.dart'; import 'package:open_file_plus/open_file_plus.dart'; import 'package:osos/core/localization/translate.dart'; import 'package:osos/core/services/file_service/app_file_service.inject.dart';

class LocalNotification { static final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

static Future init() async { const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher',); final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings(

    notificationCategories: [
      DarwinNotificationCategory(
        'demoCategory',
        actions: <DarwinNotificationAction>[
          DarwinNotificationAction.plain(
            'id_1',
            'Action 2',
            options: <DarwinNotificationActionOption>{
              DarwinNotificationActionOption.destructive,
            },
          ),
        ],
        options: <DarwinNotificationCategoryOption>{
          DarwinNotificationCategoryOption.hiddenPreviewShowTitle,
        },
      )
    ],);
 InitializationSettings initializationSettings =
    InitializationSettings(
        android: initializationSettingsAndroid,
        iOS: initializationSettingsDarwin);

await flutterLocalNotificationsPlugin.initialize(
  initializationSettings,
  onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
  onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
);
final launchDetails =
    await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
if (launchDetails != null && launchDetails.didNotificationLaunchApp) {
  final response = launchDetails.notificationResponse;
  if (response != null) {
    // print(
    //     'got notification launched details: $launchDetails with payload ${response.payload}');
    if (response.payload != null) {
      await openFile(response.payload!);
    }
  }
}

}

static void onDidReceiveNotificationResponse( NotificationResponse response) async { final String? payload = response.payload; if (payload != null) { final file = File(payload); if (file.existsSync()) { await GetIt.I<AppFileService>().openFileWithPath(payload); } else { log('This notification payload is not a valid file path or file does not exist'); } } }

static Future showDownloadNotification(String filePath) async { const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( 'download_channel', 'File Download', channelDescription: 'Notification for downloaded files', importance: Importance.max, priority: Priority.high, playSound: true, actions: <AndroidNotificationAction>[ AndroidNotificationAction('OPEN_FILE_ACTION', 'View', showsUserInterface: false,), ], );

const NotificationDetails platformChannelSpecifics =
    NotificationDetails(android: androidNotificationDetails);

await flutterLocalNotificationsPlugin.show(
  0,
  Translate.s.download_finished,
  '',
  platformChannelSpecifics,
  payload: filePath,
);

} }

@pragma('vm:entry-point') void notificationTapBackground( NotificationResponse notificationResponse) async { print('notificationTapBackground'); print('notification(${notificationResponse.id}) action tapped: ' '${notificationResponse.actionId} with' ' payload: ${notificationResponse.payload}'); if (notificationResponse.actionId == 'id_1') { log("action tapped");

final String? payload = notificationResponse.payload; log("action tapped with payload $payload"); if (payload != null) { await openFile(payload); } }

}

Future openFile(String payload) async { final file = File(payload); if (file.existsSync()) { await OpenFile.open( file.path, ); } else { log('This notification payload is not a valid file path or file does not exist'); } }

Mohamed1226 avatar Dec 24 '24 17:12 Mohamed1226

In the future, please surround your code with three backticks (the key on top of the Tab key, so `, not '), like this:

```dart YOUR CODE HERE ```

Also, you didn't really answer the question. Your code includes details for iOS and Android -- which platform is showing the issue? I assume Android? Then you only really want to focus on this code, right?

static Future showDownloadNotification(String filePath) async {
  const androidNotificationDetails = AndroidNotificationDetails(
    'download_channel',
    'File Download',
    channelDescription: 'Notification for downloaded files',
    importance: Importance.max,
    priority: Priority.high,
    playSound: true,
    actions: [
      AndroidNotificationAction('OPEN_FILE_ACTION', 'View', showsUserInterface: false,),
    ],
  );

  const platformChannelSpecifics = NotificationDetails(android: androidNotificationDetails);
  
  await flutterLocalNotificationsPlugin.show(
    0,
    Translate.s.download_finished,
    '',
    platformChannelSpecifics,
    payload: filePath,
  );
}

In the future, please only include the portions of code that are relevant to the issue, instead of dumping everything for us to sort through.

Anyway, this code looks correct... what device did you run it on? Can you push your code to a GitHub repo and share the link here so we can try to reproduce it?

Levi-Lesches avatar Dec 24 '24 17:12 Levi-Lesches

yes i used android and i add showsUserInterface to false it just close notification without any action

i add all code to see the cycle i just send file path to payload and need to open file without open the app i add action with view title it just close notification

i try to add

        <receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" />

but it not working

import 'dart:developer';
import 'dart:io';

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'package:open_file_plus/open_file_plus.dart';
import 'package:osos/core/localization/translate.dart';
import 'package:osos/core/services/file_service/app_file_service.inject.dart';


class LocalNotification {
 static final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
     FlutterLocalNotificationsPlugin();

 static Future<void> init() async {
   const AndroidInitializationSettings initializationSettingsAndroid =
       AndroidInitializationSettings('@mipmap/ic_launcher',);
   final DarwinInitializationSettings initializationSettingsDarwin = DarwinInitializationSettings(

       notificationCategories: [
         DarwinNotificationCategory(
           'demoCategory',
           actions: <DarwinNotificationAction>[
             DarwinNotificationAction.plain(
               'id_1',
               'Action 2',
               options: <DarwinNotificationActionOption>{
                 DarwinNotificationActionOption.destructive,
               },
             ),
           ],
           options: <DarwinNotificationCategoryOption>{
             DarwinNotificationCategoryOption.hiddenPreviewShowTitle,
           },
         )
       ],);
    InitializationSettings initializationSettings =
       InitializationSettings(
           android: initializationSettingsAndroid,
           iOS: initializationSettingsDarwin);

   await flutterLocalNotificationsPlugin.initialize(
     initializationSettings,
     onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,
     onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
   );
   final launchDetails =
       await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
   if (launchDetails != null && launchDetails.didNotificationLaunchApp) {
     final response = launchDetails.notificationResponse;
     if (response != null) {
       // print(
       //     'got notification launched details: $launchDetails with payload ${response.payload}');
       if (response.payload != null) {
         await openFile(response.payload!);
       }
     }
   }
 }

 static void onDidReceiveNotificationResponse(
     NotificationResponse response) async {
   final String? payload = response.payload;
   if (payload != null) {
     final file = File(payload);
     if (file.existsSync()) {
       await GetIt.I<AppFileService>().openFileWithPath(payload);
     } else {
       log('This notification payload is not a valid file path or file does not exist');
     }
   }
 }

 static Future<void> showDownloadNotification(String filePath) async {
   const AndroidNotificationDetails androidNotificationDetails =
   AndroidNotificationDetails(
     'download_channel',
     'File Download',
     channelDescription: 'Notification for downloaded files',
     importance: Importance.max,
     priority: Priority.high,
     playSound: true,
     actions: <AndroidNotificationAction>[
       AndroidNotificationAction('id_1', 'View', showsUserInterface: false,),
     ],
   );


   const NotificationDetails platformChannelSpecifics =
       NotificationDetails(android: androidNotificationDetails);

   await flutterLocalNotificationsPlugin.show(
     0,
     Translate.s.download_finished,
     '',
     platformChannelSpecifics,
     payload: filePath,
   );
 }
}

@pragma('vm:entry-point')
void notificationTapBackground(
   NotificationResponse notificationResponse)  {
 print('notificationTapBackground');
 print('notification(${notificationResponse.id}) action tapped: '
     '${notificationResponse.actionId} with'
     ' payload: ${notificationResponse.payload}');
 if (notificationResponse.actionId == 'id_1') {
  log("action tapped");

  final String? payload = notificationResponse.payload;
  log("action tapped with payload $payload");
  if (payload != null) {
     openFile(payload);
  }
 }

}

Future<void> openFile(String payload) async {
 final file = File(payload);
 if (file.existsSync()) {
   await OpenFile.open(
     file.path,
   );
 } else {
   log('This notification payload is not a valid file path or file does not exist');
 }
}

Mohamed1226 avatar Dec 24 '24 17:12 Mohamed1226

Can you provide a link to a repo hosting a minimal app that can reproduce this?

MaikuB avatar Feb 08 '25 06:02 MaikuB