2025-02-10 09:45:36 +08:00
|
|
|
|
import 'dart:convert';
|
|
|
|
|
|
import 'dart:typed_data';
|
|
|
|
|
|
import 'package:flutter/services.dart' show rootBundle;
|
|
|
|
|
|
|
|
|
|
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
|
|
|
|
import 'package:http/http.dart' as http;
|
|
|
|
|
|
|
|
|
|
|
|
class NotificationService {
|
|
|
|
|
|
factory NotificationService() {
|
|
|
|
|
|
return _instance;
|
|
|
|
|
|
}
|
|
|
|
|
|
NotificationService._internal();
|
|
|
|
|
|
static final NotificationService _instance = NotificationService._internal();
|
|
|
|
|
|
|
|
|
|
|
|
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
|
|
|
|
|
FlutterLocalNotificationsPlugin();
|
|
|
|
|
|
|
|
|
|
|
|
void init() {
|
|
|
|
|
|
const AndroidInitializationSettings initializationSettingsAndroid =
|
|
|
|
|
|
AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
|
|
|
|
|
|
|
|
|
|
const InitializationSettings initializationSettings =
|
|
|
|
|
|
InitializationSettings(android: initializationSettingsAndroid);
|
|
|
|
|
|
|
|
|
|
|
|
_flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// **📌 方法1:显示普通文本通知**
|
|
|
|
|
|
Future<void> showTextNotification(String title, String body) async {
|
|
|
|
|
|
const AndroidNotificationDetails androidPlatformChannelSpecifics =
|
|
|
|
|
|
AndroidNotificationDetails(
|
|
|
|
|
|
'1',
|
|
|
|
|
|
'flutter_channel',
|
|
|
|
|
|
importance: Importance.max,
|
|
|
|
|
|
priority: Priority.high,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const NotificationDetails platformChannelSpecifics =
|
|
|
|
|
|
NotificationDetails(android: androidPlatformChannelSpecifics);
|
|
|
|
|
|
|
|
|
|
|
|
await _flutterLocalNotificationsPlugin.show(
|
2025-02-18 10:42:08 +08:00
|
|
|
|
1,
|
2025-02-10 09:45:36 +08:00
|
|
|
|
title,
|
|
|
|
|
|
body,
|
|
|
|
|
|
platformChannelSpecifics,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// **📌 方法2:显示带图片的推送通知**
|
|
|
|
|
|
Future<void> showImageNotification(
|
|
|
|
|
|
String title, String body, String imageUrl) async {
|
|
|
|
|
|
// //读取网络下载图片
|
|
|
|
|
|
// final ByteArrayAndroidBitmap? bigPicture = await _downloadImage(imageUrl);
|
|
|
|
|
|
// 读取本地图片
|
2025-02-18 10:42:08 +08:00
|
|
|
|
final ByteData imageData = await rootBundle.load('images/call_me_icon.png');
|
2025-02-10 09:45:36 +08:00
|
|
|
|
final Uint8List imageBytes = imageData.buffer.asUint8List();
|
|
|
|
|
|
final ByteArrayAndroidBitmap bigPicture =
|
|
|
|
|
|
ByteArrayAndroidBitmap(imageBytes);
|
|
|
|
|
|
|
|
|
|
|
|
if (bigPicture == null) {
|
|
|
|
|
|
showTextNotification(title, body);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
final BigPictureStyleInformation bigPictureStyleInformation =
|
|
|
|
|
|
BigPictureStyleInformation(
|
|
|
|
|
|
bigPicture,
|
|
|
|
|
|
contentTitle: title,
|
|
|
|
|
|
summaryText: body,
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
final AndroidNotificationDetails androidPlatformChannelSpecifics =
|
|
|
|
|
|
AndroidNotificationDetails(
|
|
|
|
|
|
'1',
|
|
|
|
|
|
'flutter_channel',
|
|
|
|
|
|
importance: Importance.max,
|
|
|
|
|
|
priority: Priority.high,
|
|
|
|
|
|
styleInformation: bigPictureStyleInformation,
|
2025-02-18 10:42:08 +08:00
|
|
|
|
sound: const RawResourceAndroidNotificationSound('ring_wx'), // 自定义铃声
|
2025-02-10 09:45:36 +08:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
final NotificationDetails platformChannelSpecifics =
|
|
|
|
|
|
NotificationDetails(android: androidPlatformChannelSpecifics);
|
|
|
|
|
|
|
|
|
|
|
|
await _flutterLocalNotificationsPlugin.show(
|
2025-02-18 10:42:08 +08:00
|
|
|
|
1,
|
2025-02-10 09:45:36 +08:00
|
|
|
|
title,
|
|
|
|
|
|
body,
|
|
|
|
|
|
platformChannelSpecifics,
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// **📌 辅助方法:下载网络图片**
|
|
|
|
|
|
Future<ByteArrayAndroidBitmap?> _downloadImage(String url) async {
|
|
|
|
|
|
try {
|
|
|
|
|
|
final http.Response response = await http.get(Uri.parse(url));
|
|
|
|
|
|
if (response.statusCode == 200) {
|
|
|
|
|
|
return ByteArrayAndroidBitmap.fromBase64String(
|
|
|
|
|
|
base64Encode(response.bodyBytes));
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
print('❌ 图片下载失败: $e');
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
2025-02-18 10:42:08 +08:00
|
|
|
|
|
|
|
|
|
|
/// 取消所有本地通知
|
|
|
|
|
|
Future<void> cancelAllNotifications() async {
|
|
|
|
|
|
await _flutterLocalNotificationsPlugin.cancelAll();
|
|
|
|
|
|
}
|
2025-02-10 09:45:36 +08:00
|
|
|
|
}
|