Understanding real-time messages, local notifications, and remote push notifications in IM services (Android)

Not all notifications in the client’s notification bar are remote notifications. This article explains the relationship between IM connection status, app running status, local notifications, and remote notifications.

IM connection status between SDK and RC server

To differentiate between real-time messages and remote push notifications, it’s essential to understand the IM connection statuses:

  • Connected: After the app calls the SDK’s connection method, the SDK establishes a long connection with the RC server, known as the IM connection channel, for sending and receiving messages. The SDK triggers the message listener method when it receives messages through this channel.

  • Disconnected: If the IM connection channel is broken, real-time messages can’t reach the user’s device via the IM long connection. In this case, new messages can only be delivered to the user’s device via a push service (third-party push service).

    The IM connection channel may break due to:

    • The app’s main process being killed or reclaimed.
    • The app actively calling the SDK’s disconnect method to terminate the IM connection.
    • The connection method isn’t called, or the IM connection isn’t established properly.
    • The current logged-in user is banned.
    • The current user’s Token expires or is invalidated.
    • The current user logs in on another device, causing them to be logged out on the current device (affected by the multi-device login restrictions of the current App Key).

App status

To understand the scope of real-time messages, local notifications, and remote push notifications, it’s important to distinguish between the different states of an Android app: foreground status, background active status, and killed status.

  1. Foreground status: The app is running in the foreground (assuming the SDK has established a proper IM connection with the RC server), and the user is actively using the app.
  2. Background active status: When the app moves to the background, the system may restrict network access or process execution, causing the connection to break. However, the timing of this disconnection varies by system. If the IM connection remains after moving to the background, the app can receive real-time messages through the IM connection. If the app integrates the IMKit SDK, IMKit will handle displaying a notification in the notification bar upon receiving a new message—this is called a “local notification.” If the app integrates the IMLib SDK, receiving a new message triggers the IMLib message listener method (note: IMLib doesn’t implement local notifications in this scenario; the developers can create notification in the callback method and display a local notification by yourselves).
  3. Killed status: The system restricts network access or process execution, causing the connection to break, and the app enters a paused state. In this case, the app loses its IM connection with the RC server. If the IM connection channel is broken and a message is sent to the user, the app must rely on the integrated remote push service (e.g., Huawei Push, Xiaomi Push, Oppo Push, FCM Push) to notify the user’s device. Third-party push notifications can be displayed directly in the notification bar via the Android system, independent of IMLib/IMKit implementation.

:tipping_hand_man: When testing push integration, note that some emulators and real devices may only clear the UI interface when cleaning up background apps, but the app process isn’t killed, so the IM connection channel remains intact. In this case, received messages won’t go through the push channel.

In the latter two states, if the app returns to the foreground and re-establishes the IM connection, the SDK can retrieve messages from the RC server.

Real-time messages in IM

Regardless of whether the app is in the foreground or background, if a message is received via the IM connection, the SDK will trigger the message listener callback method.

Here’s an example of the IMKit message listener method:

public boolean onReceived(Message message, int left, boolean hasPackage, boolean offline)

Local notifications

Local notifications are created and sent directly by IMKit or the app client using system APIs when the app is running in the foreground or background. The IMKit SDK has built-in local notification functionality. When the app is in the background and receives a new message, IMKit will display a notification in the notification panel by default, this is a local notification.

Refer to the IMKit 5.X developer documentation: Local notifications

Remote notifications

After integrating a third-party push service, the app can receive notifications of new messages through the vendor’s push channel when the IM connection channel is down.

Refer to the developer documentation: Push 2.0 integration guide

Appendix: SDK notification process diagram

As shown in the diagram, only when the recipient’s main process is killed or reclaimed, or the app actively calls disconnect(), causing the IM long connection channel to break, will the RC server send a notification of a new message through the push channel.