我需要发出这样的通知
我的输出代码
我的 Pubspec.yaml 文件。我正在使用最新版本的 flutter_local_notifications
flutter_local_notifications: ^9.2.0
这是我的通知控制器代码
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',
);
}
}
我在 main.dart 文件上初始化了 firebase 和通知
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"],
);
}
firebase_messaging 插件工作正常。问题在于来自 flutter_local_notifications 的通知的整体情况。 我使用 path_provider 和 http 下载图像。此图像也成功下载到我的应用程序外部存储目录中。但通知上没有显示
/storage/emulated/0/Android/data/in.myapp.dhrona/files/largeIcon.png
/storage/emulated/0/Android/data/in.myapp.dhrona/files/bigIcon.png
这个问题有什么解决办法吗
虽然 @Vignesh 的 answer 有效,但以下是对该答案的一些改进:
最终答案应该是这样的:
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...
),
)
);
显示网络图像,
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),
),
);
显示本地图像,
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),
),
);
使用 AwesomeNotifications,我不需要下载。我只是给出如下网址:
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);
}
}
我使用 flutter_local_notifications 的示例代码并成功显示带有大图标或大图片的通知。下面的例子中我只显示了largeIcon,如果你想显示bigPicture,你需要使用styleInformation来代替。
Future<String> _downloadAndSaveFile(String url, String fileName) async {
final Directory directory = await getApplicationDocumentsDirectory();
final String filePath = '${directory.path}/$fileName';
final http.Response response = await http.get(Uri.parse(url));
final File file = File(filePath);
await file.writeAsBytes(response.bodyBytes);
return filePath;
}
Future<void> _showLocalNotification(CustomNotification notification) async {
if (!notification.image!.isNullOrEmpty) {
_flutterLocalNotificationsPlugin.show(
notification.id,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
_channel.id,
_channel.name,
channelDescription: _channel.description,
importance: Importance.max,
priority: Priority.high,
enableVibration: true,
color: AppColor.colorPrimary,
icon: '@drawable/ic_vota',
largeIcon: FilePathAndroidBitmap(await _downloadAndSaveFile(
notification.image ?? '', 'largeIcon')),
),.....
有效负载看起来像这样
{
"to": "fcm-token",
"data": {
"body": "",
"title": "",
"imageUrl": ""
},
"notification": {
"body": "",
"title": ""
}
}