跳到主要内容

本地通知

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 会自动处理权限请求,但建议在应用启动时进行权限检查。

性能优化

本地通知的创建和显示不会阻塞消息接收和处理流程,不会影响应用的正常使用。

限制说明

本地通知只在应用进程存活时有效。如果应用被系统完全终止,需要依赖远程推送通知来提醒用户。