Skip to main content

Local Notification

The IMKit SDK has implemented the creation, display, and redirection behavior of local notifications, enabling developers to quickly build applications.

What is a Local Notification

A local notification refers to a notification (Notification) created and sent directly by IMKit or the application client by calling system APIs when the app is running in the foreground or background. When the app is in the background and receives a new message, IMKit will display a notification reminder in the notification panel by default, which is a local notification.

IMKit's local notification supports the following scenarios:

  • When the app has just entered the background (still in an active background state), IMKit can still receive new messages through the persistent connection channel (recalled messages will also generate recall signaling messages). By default, this triggers a local notification, and clicking it will redirect to the corresponding conversation page.

    tip

    After the app enters an inactive background state (e.g., killed by the system), the IMKit persistent connection is disconnected. At this point, offline push notifications triggered by third-party push services (or RC push) are created and displayed directly by the vendor, independent of IMKit's local notification mechanism.

  • When the app is in the foreground and no conversation page is open (not chatting with anyone), receiving a new message will trigger a ringtone and vibration by default but will not display a notification. You can modify this to silent mode or display only the notification using setForegroundOtherPageAction. Refer to NotificationConfig.java.

Setting Local Notification Categories

Starting September 15, 2023, Huawei Push Service will implement grayscale control over local notifications based on the "Huawei Message Classification Standard." This mainly includes categorizing local notifications sent by apps and uniformly controlling the frequency of marketing messages. If an app has not applied for Huawei's self-classification permissions, all local notifications it sends will be treated as marketing messages (limited to 2 or 5 per day).

To ensure that local notifications sent by IMKit directly calling Huawei device system APIs are displayed, the app must apply for the required self-classification permissions from Huawei. Starting from version 5.6.4, IMKit internally sets the default category of local notifications to CATEGORY_MESSAGE, and the app does not need to call additional APIs to configure this.

You can modify the default local notification category using IMKit's global configuration after initialization:

RongConfigCenter.notificationConfig().setCategoryNotification(Notification.CATEGORY_MESSAGE);

Setting Foreground Local Notification Ringtone and Vibration

tip

This feature is supported starting from SDK version 5.2.3.

Starting from version 5.2.3, IMKit added independent controls for whether the app rings or vibrates when receiving new messages in the foreground while not on a conversation page.

To modify the default behavior, create an rc_config.xml file in the res/values directory of your app and modify the following configuration items (enabled by default):

//Whether to ring when receiving new messages in the foreground while not on a conversation page
<bool name="rc_sound_in_foreground">true</bool>

//Whether to vibrate when receiving new messages in the foreground while not on a conversation page
<bool name="rc_vibrate_in_foreground">true</bool>

For dynamic control over local notification ringtone and vibration behavior, use IMKit's global configuration:

/** Whether to vibrate */
RongConfigCenter.featureConfig().setVibrateInForeground(true)
/** Whether to ring */
RongConfigCenter.featureConfig().setSoundInForeground(false)

Intercepting Local Notifications

IMKit supports intercepting notifications before they are displayed. You can modify the Message object and choose whether to continue displaying the notification. For implementation details, refer to the following files in the IMKit source code:

For more customization, you can fully intercept the notification and handle it yourself.

Intercepting Local Notifications

tip

Starting from SDK version 5.1.4, use the following method to set the interceptor.

You can intercept IMKit's local notifications. After setting the interceptor, you can prevent IMKit from displaying local notifications and handle them as needed. Set the listener after initialization but before establishing the IM connection.

public class MyNotificationInterceptor extends DefaultInterceptor {
/**
* Whether to intercept this local notification, typically used for customizing notification display.
*
* @param message The message corresponding to the local notification
* @return Whether to intercept. true: Intercept the local notification; SDK will not display it, and the user must handle it. false: Do not intercept; SDK will display the local notification.
*/
@Override
public boolean isNotificationIntercepted(Message message) {
...
return true; //true: Intercept the local notification; SDK will no longer handle it.
}

/**
* Whether the message is high-priority. High-priority messages are not affected by global mute settings or conversation Do Not Disturb, e.g., @ messages.
*
* @param message The received message
* @return Whether the message is high-priority
*/
@Override
public boolean isHighPriorityMessage(Message message) {
return false;
}
/**
* Callback before registering the default channel. Use this method to intercept and modify the default channel configuration, then return the modified channel.
*
* @param defaultChannel The default notification channel
* @return The modified notification channel.
*/
@Override
public NotificationChannel onRegisterChannel(NotificationChannel defaultChannel) {
return defaultChannel;
}

/**
* Callback when setting the local notification PendingIntent.
* Apps can use this method to modify the PendingIntent settings and customize the click behavior of local notifications.
* By default, clicking a local notification redirects to the corresponding conversation page.
* @param pendingIntent The default PendingIntent from the SDK
* @param intent The intent carried by the PendingIntent.
* Use the intent to get the following information:
* intent.getStringExtra(RouteUtils.CONVERSATION_TYPE);
* intent.getStringExtra(RouteUtils.TARGET_ID);
* intent.getIntExtra(RouteUtils.MESSAGE_ID, -1);;
* @return The PendingIntent to be configured in the local notification.
*/
@Override
public PendingIntent onPendingIntent(PendingIntent pendingIntent, Intent intent) {
Intent intentNew = new Intent(getApplicationContext(), MainActivity.class); //Custom redirect to the conversation list
PendingIntent pendingIntent1 = PendingIntent.getActivity(getApplicationContext(), 1, intentNew, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent1;
}
}

RongConfigCenter.notificationConfig().setInterceptor(new MyNotificationInterceptor());

Intercepting Local Notifications (< 5.1.4)

tip

Starting from SDK version 5.1.4, the following method is deprecated.

You can intercept IMKit's local notifications. After setting the interceptor, you can prevent IMKit from displaying local notifications and handle them as needed. Set the listener after initialization but before establishing the IM connection.

RongConfigCenter.notificationConfig().setInterceptor(new NotificationConfig.Interceptor() {
/**
* Whether to intercept this local notification, typically used for customizing notification display.
*
* @param message The message corresponding to the local notification
* @return Whether to intercept. true: Intercept the local notification; SDK will not display it, and the user must handle it. false: Do not intercept; SDK will display the local notification.
*/
@Override
public boolean isNotificationIntercepted(Message message) {
...
return true; //true: Intercept the local notification; SDK will no longer handle it.
}

/**
* Whether the message is high-priority. High-priority messages are not affected by global mute settings or conversation Do Not Disturb, e.g., @ messages.
*
* @param message The received message
* @return Whether the message is high-priority
*/
@Override
public boolean isHighPriorityMessage(Message message) {
return false;
}
/**
* Callback before registering the default channel. Use this method to intercept and modify the default channel configuration, then return the modified channel.
*
* @param defaultChannel The default notification channel
* @return The modified notification channel.
*/
@Override
public NotificationChannel onRegisterChannel(NotificationChannel defaultChannel) {
return defaultChannel;
}

/**
* Callback when setting the local notification PendingIntent.
* Apps can use this method to modify the PendingIntent settings and customize the click behavior of local notifications.
* By default, clicking a local notification redirects to the corresponding conversation page.
* @param pendingIntent The default PendingIntent from the SDK
* @param intent The intent carried by the PendingIntent.
* Use the intent to get the following information:
* intent.getStringExtra(RouteUtils.CONVERSATION_TYPE);
* intent.getStringExtra(RouteUtils.TARGET_ID);
* intent.getIntExtra(RouteUtils.MESSAGE_ID, -1);;
* @return The PendingIntent to be configured in the local notification.
*/
@Override
public PendingIntent onPendingIntent(PendingIntent pendingIntent, Intent intent) {
Intent intentNew = new Intent(getApplicationContext(), MainActivity.class); //Custom redirect to the conversation list
PendingIntent pendingIntent1 = PendingIntent.getActivity(getApplicationContext(), 1, intentNew, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent1;
}
});

Customizing Notification Clicks

By default, the SDK handles local notification clicks by redirecting to the corresponding conversation page. You can override the onPendingIntent callback method in the notification interceptor to implement custom redirection logic.

@Override
public PendingIntent onPendingIntent(PendingIntent pendingIntent, Intent intent) {
Intent intentNew = new Intent(getApplicationContext(), MainActivity.class); //Custom redirect to the conversation list
PendingIntent pendingIntent1 = PendingIntent.getActivity(getApplicationContext(), 1, intentNew, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent1;
}