本地通知
Flutter IM Kit 已内置本地通知功能,当应用在后台运行时接收到新消息,会自动创建并显示本地通知提醒。
什么是本地通知
本地通知是指应用在前台或后台运行时,由 Flutter IM Kit 直接调用系统接口创建并发送的通知。与远程推送通知不同,本地通知不需要通过推送服务器,直接由应用客户端生成。
Flutter IM Kit 的本地通知支持以下场景:
- 应用后台运行:应用进入后台但仍在内存中运行时,接收到新消息会显示本地通知
- 会话未打开:应用在前台但未打开对应会话页面时,可选择是否显示通知
- 多消息类型:支持文本、图片、语音、文件等多种消息类型的通知显示
启用本地通知
基本设置
在应用初始化时启用本地通知:
Dart
final engineProvider = Provider.of<RCKEngineProvider>(context, listen: false);
// 启用本地通知
await engineProvider.setupLocalNotification(enable: true);
权限配置
Android 配置
在 android/app/src/main/AndroidManifest.xml
中添加必要权限:
xml
<!-- 本地通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
iOS 配置
iOS 平台会自动请求通知权限,无需额外配置。
通知内容定制
默认通知内容
不同消息类型的默认通知内容:
消息类型 | 通知内容 |
---|---|
文本消息 | 显示消息文本内容 |
图片消息 | 显示 "[图片]" |
语音消息 | 显示 "[语音]" |
文件消息 | 显示 "[文件]" |
视频消息 | 显示 "[视频]" |
位置消息 | 显示 "[位置]" |
自定义消息 | 显示消息类型标识 |
自定义通知内容
通过实现 CustomInfoProvider
可以自定义通知显示内容:
Dart
class MyCustomInfoProvider extends CustomInfoProvider {
String? getDisplayName(String userId) {
// 返回自定义用户显示名称
return _getUserDisplayName(userId);
}
String? getPortraitUrl(String userId) {
// 返回自定义头像URL
return _getUserAvatar(userId);
}
String? getGroupName(String groupId) {
// 返回自定义群组名称
return _getGroupName(groupId);
}
}
// 应用自定义信息提供者
final engineProvider = Provider.of<RCKEngineProvider>(context, listen: false);
engineProvider.setCustomInfoProvider(MyCustomInfoProvider());
通知过滤
免打扰过滤
设置免打扰的会话不会显示本地通知:
Dart
void _onReceiveMessage() {
final message = engineProvider.receiveMessageNotifier.value;
// 检查会话是否被免打扰
bool isBlocked = _checkConversationBlocked(message);
// 只有非免打扰会话才显示通知
if (!isBlocked && message != null) {
engineProvider.showLocalNotification(message);
}
}
自定义过滤逻辑
可以实现自定义的消息过滤逻辑:
Dart
class CustomNotificationFilter {
static bool shouldShowNotification(RCIMIWMessage message) {
// 过滤系统消息
if (message.messageType == RCIMIWMessageType.unknown) {
return false;
}
// 过滤特定时间段的消息
final now = DateTime.now();
if (now.hour >= 22 || now.hour <= 8) {
return false; // 夜间免打扰
}
// 过滤特定用户的消息
if (_isBlockedUser(message.senderUserId)) {
return false;
}
return true;
}
}
全局通知开关
控制通知开关
提供全局开关控制所有通知:
Dart
class NotificationSettings {
static bool _globalNotificationEnabled = true;
static bool get isEnabled => _globalNotificationEnabled;
static Future<void> setEnabled(bool enabled) async {
_globalNotificationEnabled = enabled;
final engineProvider = Provider.of<RCKEngineProvider>(
navigatorKey.currentContext!,
listen: false
);
await engineProvider.setupLocalNotification(enable: enabled);
}
}
设置界面集成
在设置页面中提供通知开关:
Dart
class NotificationSettingsWidget extends StatelessWidget {
Widget build(BuildContext context) {
return Consumer<RCKEngineProvider>(
builder: (context, engineProvider, child) {
return SwitchListTile(
title: Text('接收消息通知'),
subtitle: Text('关闭后将不再显示消息通知'),
value: engineProvider.enableLocalNotification,
onChanged: (value) async {
await engineProvider.setupLocalNotification(enable: value);
},
);
},
);
}
}
通知点击处理
基本点击处理
本地通知被点击时的处理逻辑:
Dart
void setupNotificationClickHandling() {
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
// 处理通知点击
flutterLocalNotificationsPlugin.initialize(
InitializationSettings(
android: AndroidInitializationSettings('@mipmap/ic_launcher'),
iOS: IOSInitializationSettings(),
),
onSelectNotification: (String? payload) async {
if (payload != null) {
// 解析payload,导航到对应会话
_navigateToConversation(payload);
}
},
);
}
导航到会话
点击通知后导航到对应的会话页面:
Dart
void _navigateToConversation(String payload) {
try {
final data = json.decode(payload);
final conversation = RCIMIWConversation(
conversationType: _parseConversationType(data['type']),
targetId: data['targetId'],
channelId: data['channelId'],
);
Navigator.pushNamed(
context,
'/chat',
arguments: conversation,
);
} catch (e) {
print('Failed to parse notification payload: $e');
}
}
高级配置
通知渠道设置 (Android)
为不同类型的消息设置不同的通知渠道:
Dart
const AndroidNotificationChannel messageChannel = AndroidNotificationChannel(
'messages',
'消息通知',
description: '即时消息通知',
importance: Importance.high,
sound: RawResourceAndroidNotificationSound('notification_sound'),
);
const AndroidNotificationChannel systemChannel = AndroidNotificationChannel(
'system',
'系统通知',
description: '系统消息通知',
importance: Importance.defaultImportance,
);
通知样式定制
定制通知的显示样式:
Dart
AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
'messages',
'消息通知',
channelDescription: '即时消息通知',
importance: Importance.high,
priority: Priority.high,
ticker: 'ticker',
icon: '@mipmap/ic_launcher',
largeIcon: DrawableResourceAndroidBitmap('@mipmap/ic_launcher'),
styleInformation: BigTextStyleInformation(''),
);
IOSNotificationDetails iosDetails = IOSNotificationDetails(
presentAlert: true,
presentBadge: true,
presentSound: true,
sound: 'notification_sound.aiff',
);
注意事项
权限要求
在 Android 13 (API 33) 及以上版本,需要在运行时请求 POST_NOTIFICATIONS
权限。Flutter IM Kit 会自动处理权限请求,但建议在应用启动时进行权限检查。
性能优化
本地通知的创建和显示不会阻塞消息接收和处理流程,不会影响应用的正常使用。
限制说明
本地通知只在应用进程存活时有效。如果应用被系统完全终止,需要依赖远程推送通知来提醒用户。