简体   繁体   中英

flutter_local_notifications plugin not showing the big image in notification

I need to make like this notification

在此处输入图像描述

My Output code

在此处输入图像描述

my Pubspec.yaml file. I am using latest version of flutter_local_notifications

  flutter_local_notifications: ^9.2.0

This is my Notification Controller code

import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:image/image.dart' as image;
import 'package:path_provider/path_provider.dart';

class NotificationService {
  static final NotificationService _notificationService =
      NotificationService._internal();

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  factory NotificationService() {
    return _notificationService;
  }

  NotificationService._internal();
  Future<void> init(
      Function(int, String?, String?, String?)?
          onDidReceiveLocalNotification) async {
    const AndroidInitializationSettings initializationSettingsAndroid =
        AndroidInitializationSettings('@mipmap/launcher_icon');

    final IOSInitializationSettings initializationSettingsIOS =
        IOSInitializationSettings(
      requestAlertPermission: false,
      requestBadgePermission: false,
      requestSoundPermission: false,
      onDidReceiveLocalNotification:
          (int id, String? title, String? body, String? payload) async {},
    );
    final InitializationSettings initializationSettings =
        InitializationSettings(
      android: initializationSettingsAndroid,
      iOS: initializationSettingsIOS,
    );
    await flutterLocalNotificationsPlugin.initialize(
      initializationSettings,
      onSelectNotification: (String? payload) async {
        if (payload != null) {
          print('notification payload: $payload');
        }
      },
    );
  }

  Future selectNotification(String? payload) async {
    print('selectNotification: $payload');
  }

  Future<String> _downloadAndSaveFile(String url, String fileName) async {
    final Directory? directory = await getExternalStorageDirectory();
    final String filePath = '${directory!.path}/$fileName.png';
    final http.Response response = await http.get(Uri.parse(url));
    final File file = File(filePath);
    await file.writeAsBytes(response.bodyBytes);
    return filePath;
  }

  Future showNotify({
    required String body,
    required String image,
  }) async {
    final String largeIconPath = await _downloadAndSaveFile(
      'https://via.placeholder.com/48x48',
      'largeIcon',
    );
    final String bigPicturePath = await _downloadAndSaveFile(
      image,
      'bigPicture',
    );

    await flutterLocalNotificationsPlugin.show(
      123,
      'New Buisness Sutra Updated',
      body,
      NotificationDetails(
        android: AndroidNotificationDetails(
          'big text channel id',
          'big text channel name',
          ongoing: true,
          priority: Priority.max,
          largeIcon: FilePathAndroidBitmap(largeIconPath),
          channelDescription: 'big text channel description',
          styleInformation: BigPictureStyleInformation(
            FilePathAndroidBitmap(bigPicturePath),
            hideExpandedLargeIcon: false,
            contentTitle: 'overridden <b>big</b> content title',
            htmlFormatContentTitle: true,
            summaryText: 'summary <i>text</i>',
            htmlFormatSummaryText: true,
          ),
        ),
      ),
      payload: 'data',
    );
  }
}

I initialized the firebase and notification on my main.dart file


void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  if (!kIsWeb) {
    await Firebase.initializeApp();
    firebaseCloudMessagingListeners();
    await NotificationService().init();
  }
  runApp(const MyApp());
}

firebaseCloudMessagingListeners() {
  FirebaseMessaging.onBackgroundMessage(_messageHandler);
  FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    print(message);
    _messageHandler(message);
  });
  FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    print("Message opened");
  });
}

Future<void> _messageHandler(RemoteMessage message) async {
  Map<String, dynamic> data = message.data;
  print(data);
  await NotificationService().showNotify(
    body: data["body"],
    image: data["image"],
  );
}

The firebase_messaging plugin works fine. The problem is with the big picture on the notification from flutter_local_notifications. I download the image by using path_provider and http. also this image succesfully downloaded on my app External storage directory. But not shown on the notification

/storage/emulated/0/Android/data/in.myapp.dhrona/files/largeIcon.png /storage/emulated/0/Android/data/in.myapp.dhrona/files/bigIcon.png

Any solutions for this issue

To show network image,

    final http.Response response = await http.get(Uri.parse(URL));
    BigPictureStyleInformation bigPictureStyleInformation =
        BigPictureStyleInformation(
      ByteArrayAndroidBitmap.fromBase64String(base64Encode(image)),
      largeIcon: ByteArrayAndroidBitmap.fromBase64String(base64Encode(image)),
    );
    flutterLocalNotificationsPlugin.show(
      Random().nextInt(1000),
      title,
      description,
      NotificationDetails(
        android: AndroidNotificationDetails(channel.id, channel.name,
            channelDescription: channel.description,
            importance: Importance.high,
            styleInformation: bigPictureStyleInformation),
      ),
    );

To show local image,

    final String filePath = '${directory.path}/$fileName';
    final BigPictureStyleInformation bigPictureStyleInformation =
        BigPictureStyleInformation(FilePathAndroidBitmap(filePath),
            largeIcon: FilePathAndroidBitmap(filePath));
    flutterLocalNotificationsPlugin.show(
      Random().nextInt(1000),
      title,
      description,
      NotificationDetails(
        android: AndroidNotificationDetails(channel.id, channel.name,
            channelDescription: channel.description,
            importance: Importance.high,
            styleInformation: bigPictureStyleInformation),
      ),
    );

With AwesomeNotifications I don't need to download. I just give the url like below:

  Future<void> showNotificationChatMessage(
      RemoteMessage message, MyMessage myMessage) async {
    final chatId = message.data['chatId'];
    NotificationContent? notificationContent;
    if (myMessage.type == MyMessageType.text ||
        myMessage.replyType == MyMessageReplyType.text) {
      notificationContent = NotificationContent(
          id: 10,
          channelKey: 'basic_channel',
          title: message.data['title'].toString(),
          body: message.data['body'].toString(),
          payload: {'chatId': chatId.toString()});
    } else if (myMessage.type == MyMessageType.image ||
        myMessage.replyType == MyMessageReplyType.image) {
      notificationContent = NotificationContent(
          id: 11,
          channelKey: 'big_picture',
          title: message.data['title'].toString(),
          body: 'Image',
          bigPicture: myMessage.message,
          showWhen: true,
          displayOnBackground: true,
          payload: {'chatId': chatId.toString()},
          notificationLayout: NotificationLayout.BigPicture);
    }
    if (notificationContent != null) {
      AwesomeNotifications().createNotification(content: notificationContent);
    }
  }

Although the answer by @Vignesh works, here are some improvements to that answer:

  • response is not used in the example
  • there is no need to set the "largeIcon" property with the same image data as the big image because it will show the same image two times in the notification when the notification is expanded.

the final answer should look like this:

final http.Response response = await http.get(Uri.parse(imageUrl));
        bigPictureStyleInformation = BigPictureStyleInformation(
            ByteArrayAndroidBitmap.fromBase64String(base64Encode(response.bodyBytes)));

      flutterLocalNotificationsPlugin.show(
          notification.hashCode,
          notification.title ?? 'APP_NAME',
          notification.body,
          NotificationDetails(
            android: AndroidNotificationDetails(
              channel.id,
              channel.name,
              channelDescription: channel.description,
              styleInformation: bigPictureStyleInformation,
              // other properties...
            ),
          )
      );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM