Message Sending
Update time: 2024/08/20 15:45:46
Overview
The SDK provides a set of messaging management features, such as sending and receiving messages, storing messages, uploading and downloading attachments. You are allowed to send text, audio messages, image, video, file, location, and custom messages.
The message structure is IMMessage
and different message types are distinguished by MsgTypeEnum
.IMMessage
does not support inheritance or extension.
- Parameters for IMMessage
Return | Method | Description |
---|---|---|
String | getUuid() | Get message client ID. |
long | getServerId() | Get message server ID. |
String | getSessionId() | Get chat object ID or group ID. |
String | getFromAccount() | Get account of the message sender. |
SessionTypeEnum | getSessionType() | Get session type, for example, group chat. |
int | getFromClientType() | Get type of message sender. |
String | getFromNick() | Get display name of message sender. |
MsgTypeEnum | getMsgType() | Get message type. |
int | getSubtype() | Get subtype of message. |
void | setSubtype | Set subtype of message. |
MsgStatusEnum | getStatus() | Get message sending or receiving status. |
MsgDirectionEnum | getDirect() | Get message direction. |
boolean | isInBlocklist() | Send a message to a recipient, and determine whether you are added to a blocklist. |
String | getContent() | Get message content. Except text message and tip, others are null. |
long | getTime() | Get message time. Unit: ms. |
void | setAttachment | Set message attachment object. See MsgAttachment parameter. |
MsgAttachment | getAttachment() | Get message attachment object. It is valid only when getMsgType() returns non-text content. |
AttachStatusEnum | getAttachStatus() | Get sending or receiving status of message attachment. |
CustomMessageConfig | getConfig() | Get message configuration See CustomMessageConfig parameter. |
Map<String, Object> | getRemoteExtension() | Get the extension field. |
void | setRemoteExtension (Map remoteExtension) |
Set extension field (The field will be sent to other clients), with max. length 1024. Developers must ensure that the Map can be transformed into JsonObject. |
Map<String, Object> | getLocalExtension() | Get local extension field (valid for local client only). |
void | setLocalExtension (Map localExtension) |
Set local extension field (The field is valid for local client and will not be sent to other clients), with max. length 1024. Developers must ensure that the Map can be transformed into JsonObject. |
String | getCallbackExtension | Get customer extension field returned from the third-party invocation. |
String | getPushContent() | Get APNS text. |
void | setPushContent(String pushContent) | Set push content. |
Map<String, Object> | getPushPayload() | Get push configuration. |
void | setPushPayload (Map pushPayload) |
Set push property (the developer must ensure that the Map can be transformed into JsonObject), with max. length 2048. |
MemberPushOption | getMemberPushOption() | Get forced push property of group members. |
boolean | isRemoteRead() | Determine that message is read by recipient in one-to-one chat scenario. |
NIMAntiSpamOption | getNIMAntiSpamOption() | Get anti-spam configuration option. |
String | getYiDunAntiCheating() | Get GuardEase Anti-spam field. |
void | setYiDunAntiCheating | Set GuardEase Anti-spam field, with Json format. |
boolean | isSessionUpdate() | Determine that message is updated to session service. |
void | setSessionUpdate | Set whether message is updated to session service. |
The available message types:
MsgTypeEnum parameter | Description |
---|---|
text | Text message. |
image | Image message. |
audio | Audio message. |
video | Video message. |
location | Location message. |
file | File message. |
avchat | Message of audio & video call event. |
notification | Notification message. |
tip | Message alert. |
custom | Custom message. |
Sending messages
You must create corresponding message object using MessageBuilder
provided interface and then call sendMessage
interface under MsgService
to send messages.
java/**
* Send a message
* @param msg - Message body to be sent, constituted by {@link MessageBuilder}
* @param resend - If a message is sent unsuccessfully and then re-sent, it is marked as "true". Otherwise, as "false"
* @return InvocationFuture - Configurable callback feature. It can be invoked only when the message is sent. If an error occurs, detailed error code will be returned.
*/
public InvocationFuture<Void> sendMessage(IMMessage msg, boolean resend);
Sending a text message
Creation prototype of text messages.
java/**
* Create a text message.
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @param text - Content of text messages.
* @return IMMessage - Generated message object.
*/
public static IMMessage createTextMessage(String sessionId, SessionTypeEnum sessionType, String text);
- Parameters
Parameter | Description |
---|---|
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum. group is group chat type. |
text | Content of text messages. |
- Example
java// The account is taken for an example.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
String text = "this is an example";
// Create a text message.
IMMessage textMessage = MessageBuilder.createTextMessage(account, sessionType, text);
// Send to the other party.
NIMClient.getService(MsgService.class).sendMessage(textMessage, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Send image messages
Creation prototype of image messages:
java/**
* Create an image message.
*
* @param sessionId - Chat object ID.
* @param sessionType Session type.
* @param file - Image file.
* @param displayName - Display name of an image file. It can be different from file name.
* @param nosTokenSceneKey - File resource scene.
* @return IMMessage - Generated message object.
*/
public static IMMessage createImageMessage(String sessionId, SessionTypeEnum sessionType, File file, String displayName);
// Or: Create an image message and specify the file resource scene used for uploading the specified image.
public static IMMessage createImageMessage(String sessionId, SessionTypeEnum sessionType, File file, String displayName, String nosTokenSceneKey);
- Parameters
Parameter | Description |
---|---|
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum.Group is group chat type. |
file | Image file object. |
displayName | Display name of image file. It can be different from file name or set to "null". |
nosTokenSceneKey | nos scene used for uploading image. Default value is NimNosSceneKeyConstant.NIM_DEFAULT_IM. See "File resource scenario". |
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
// Example image. It requires developers to have the image under related directory.
File file = new File("/sdcard/test.jpg");
// Create an image message
IMMessage message = MessageBuilder.createImageMessage(account, sessionType, file, file.getName());
// Or: Create an image message and specify the file resource scene used for uploading the specified image. "nos_scene_key" must be replaced with the one configured by developers.
IMMessage message = MessageBuilder.createImageMessage(account, sessionType, file, file.getName(),"nos_scene_key");
// Send to the other party
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Send an audio message
Creation prototype of audio messages:
java/**
* Create an audio message
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @param file - Audio file object.
* @param duration - Duration of an audio file. Unit: ms.
* @param nosTokenSceneKey - File resource scene.
* @return IMMessage - Generated message object.
*/
public static IMMessage createAudioMessage(String sessionId, SessionTypeEnum sessionType, File file, long duration);
// Or: Create an audio message and specify the file resource scene used for uploading the specified audio file
public static IMMessage createAudioMessage(String sessionId, SessionTypeEnum sessionType, File file, long duration, String nosTokenSceneKey);
- Parameters
Parameter | Description |
---|---|
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum.Group is group chat type. |
file | Audio file object |
duration | Duration of audio file. Unit: ms |
nosTokenSceneKey | nos scene used for uploading audio file. Default value is NimNosSceneKeyConstant.NIM_DEFAULT_IM. See "File resource scenario". |
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
// Example audio files. It requires developers to have the file under related directory.
File audioFile = new File("/sdcard/testAudio.mp3");
// Audio duration; time is taken for an example.
long audiolength = 2000;
// Create an audio message.
IMMessage audioMessage = MessageBuilder.createAudioMessage(account, sessionType, audioFile, audioLength);
// Or: Create an audio message and specify the file resource scene used for uploading the specified audio file. "nos_scene_key" must be replaced with the one configured by developers.
IMMessage audioMessage = MessageBuilder.createAudioMessage(account, sessionType, audioFile, "nos_scene_key");
// Send to the other party.
NIMClient.getService(MsgService.class).sendMessage(audioMessage, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Send a video message
Creation prototype of video messages:
java/**
* Create a video message
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @param file - Video file object.
* @param duration - Duration of a video file.
* @param width - Video width.
* @param height - Video height.
* @param displayName - Display name of a video file. It can be null.
* @param nosTokenSceneKey - File resource scene.
* @return - Video messages.
*/
public static IMMessage createVideoMessage(String sessionId, SessionTypeEnum sessionType, File file, long duration, int width, int height, String displayName);
// Or: Create a video message and specify the file resource scene used for uploading the specified video file.
public static IMMessage createVideoMessage(String sessionId, SessionTypeEnum sessionType, File file, long duration, int width, int height, String displayName, String nosTokenSceneKey)
- Parameters
Parameter | Description |
---|---|
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum.Group is group chat type. |
file | Video file object. |
duration | Duration of video file. Unit: ms. |
width | Video width. |
height | Video height. |
displayName | Display name of video file. It can be set to null. |
nosTokenSceneKey | nos scene used for uploading video file. Default value is NimNosSceneKeyConstant.NIM_DEFAULT_IM. See "File resource scenario". |
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
// Example video. It requires developers to have the file under related directory.
File file = new File("/sdcard/testVideo.mp4");
// Get video mediaPlayer.
MediaPlayer mediaPlayer;
try {
mediaPlayer = MediaPlayer.create(context, Uri.fromFile(file));
} catch (Exception e) {
e.printStackTrace();
}
// Duration of a video file.
long duration = mediaPlayer == null ? 0 : mediaPlayer.getDuration();
// Video height.
int height = mediaPlayer == null ? 0 : mediaPlayer.getVideoHeight();
// Video width.
int width = mediaPlayer == null ? 0 : mediaPlayer.getVideoWidth();
// Create a video message.
IMMessage message = MessageBuilder.createVideoMessage(account, sessionType, file, duration, width, height, null);
// Or: Create a video message and specify the file resource scene used for uploading the specified video file. "nos_scene_key" must be replaced with the one configured by developers.
IMMessage message = MessageBuilder.createVideoMessage(account, sessionType, file, duration, width, height, null,"nos_scene_key");
// Send to the other party.
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Send a file message
Creation prototype of file messages:
java/**
* Create a file message.
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @param file -File.
* @param displayName - Display name of a file. It can be different from file name.
* @param nosTokenSceneKey - File resource scene.
* @return IMMessage - Generated message object.
*/
public static IMMessage createFileMessage(String sessionId, SessionTypeEnum sessionType, File file, String displayName);
// Or: Create a file message and specify the file resource scene used for uploading the specified file.
public static IMMessage createFileMessage(String sessionId, SessionTypeEnum sessionType, File file, String displayName, String nosTokenSceneKey)
- Parameters
Parameter | Description |
---|---|
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum.Group is group chat type. |
file | File. |
displayName | Display name of file. It can be different from file name. |
nosTokenSceneKey | nos scene used for uploading file. Default value is NimNosSceneKeyConstant.NIM_DEFAULT_IM. See "File resource scenario". |
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
// Example file. It requires developers to have the file under related directory.
File file = new File("/sdcard/test.txt");
// Create a file message.
IMMessage message = MessageBuilder.createFileMessage(account, sessionType, file, file.getName());
// Or: Create a file message and specify the file resource scene used for uploading the specified file. "nos_scene_key" must be replaced with the one configured by developers.
IMMessage message = MessageBuilder.createFileMessage(account, sessionType, file, file.getName(),"nos_scene_key");
// Send to the other party
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Sending a location message
Creation prototype of location messages:
java/**
* Create a geolocation information.
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @param lat - Latitude.
* @param lng - Longitude.
* @param addr - Description information about geographical location.
* @param nosTokenSceneKey - File resource scene.
* @return IMMessage - Generated message object.
*/
public static IMMessage createLocationMessage(String sessionId, SessionTypeEnum sessionType, double lat, double lng, String addr);
- Parameters
Parameter | Description |
---|---|
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum.Group is group chat type. |
lat | Latitude. |
lng | Longitude. |
addr | Description information about geographical location. |
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
// Latitude.
double lat = 30.3;
// Longitude.
double lng = 120.2;
// Description information about geographical location.
String addr = "Hangzhou";
// Create a geolocation information.
IMMessage message = MessageBuilder.createLocationMessage(account, sessionType, lat, lng, addr);
// Send to the other party
NIMClient.getService(MsgService.class).sendMessage(message, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Send a tip message
Independent message type MsgTypeEnum.tip is available. A tip message is mainly used for notification tip in a session and can be considered as simplified custom message. It is different from a custom message. A tip message does not support setAttachment now. If you want to use Attachment, please send a custom message. The tip message scenarios include welcome message in session or tip message containing sensitive words in session. Definitely, you can send a custom message, but it may be relatively complex.
Creation prototype of tip messages:
java/**
* Create a tip message
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @return IMMessage - Generated message object.
*/
public static IMMessage createTipMessage(String sessionId, SessionTypeEnum sessionType);
- Example
java// A tip message is sent to a group, so that the group can be shown immediately on the list of recent contacts (list of sessions) to meet requirements of developers.
Map<String, Object> content = new HashMap<>(1);
content.put("content", "Successfully create an advanced group");
// Create a tip message. teamId must be the group ID of existing group configured by developers.
IMMessage msg = MessageBuilder.createTipMessage(teamId, SessionTypeEnum.Team);
msg.setRemoteExtension(content);
// Configuration option for custom messages.
CustomMessageConfig config = new CustomMessageConfig();
// The message is not included in unread count.
config.enableUnreadCount = false;
msg.setConfig(config);
// Set the sending status of a message to success.
msg.setStatus(MsgStatusEnum.success);
// Save a message to local database, but not send it to server.
NIMClient.getService(MsgService.class).saveMessageToLocal(msg, true).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Sending a user-defined message
In addition to built-in message types, IM SDK also supports custom message sending and receiving. The SDK will not define and parse content of custom message of which interpretation will be completed by the developer. The SDK will save custom message to message database, which will be shown in message history together with built-in messages.
For convenience of application, a custom message is displayed to the developer in the form of attachment. This is reflected in IMMessage
. The content of custom message will be parsed into MsgAttachment
object. The SDK does not know format of custom message, so that a third-party app needs to register a custom message parser. When the third-party app calls the interface of querying message history, or SDK informs the third-party app of received message, content of custom message can be transformed into a MsgAttachment
object and then custom message can be executed like image message with attachment.
Create custom message prototype
java/**
* Create an app custom message, and provide description field for push and display of message alert in status bar.
*
* @param sessionId - Chat object ID.
* @param sessionType session type.
* @param content - Simple a message. It can be acquired using IMMessage#getContent() and is mainly used for displaying user push.
* @param attachment - Message attachment object.
* @param config - Configuration for custom message.
* @param nosTokenSceneKey - File resource scene.
* @return - Custom message.
*/
public static IMMessage createCustomMessage(String sessionId, SessionTypeEnum sessionType, String content, MsgAttachment attachment, CustomMessageConfig config);
//Or: Create an app custom message and specify nos scene used for uploading files (image, audio, video) (if any).
public static IMMessage createCustomMessage(String sessionId, SessionTypeEnum sessionType, String content, MsgAttachment attachment, CustomMessageConfig config, String nosTokenSceneKey)
Example: Rock-Paper-Scissors
In the demo, a Rock-Paper-Scissors game is provided. Custom messages can be used in the game. The following is taken for an example to describe the steps in detail.
Step 1: Define a base class of custom message attachment to resolve public field of your custom message, for example, type. You can also define some public interfaces for convenient invocation.
Note: All members who have created
MsgAttachment
interface must implement "Serializable".
java// Define a base class of attachment for custom message to decode public field of your custom message, for example, type.
public abstract class CustomAttachment implements MsgAttachment {
// Type of custom message attachment. Different custom messages are distinguished by the field.
protected int type;
CustomAttachment(int type) {
this.type = type;
}
// Decode attachment content.
public void fromJson(JSONObject data) {
if (data != null) {
parseData(data);
}
}
// Interface for realizing MsgAttachment. It encapsulates the public field and then invoke encapsulating feature of sub-class.
@Override
public String toJson(boolean send) {
return CustomAttachParser.packData(type, packData());
}
// Interface for decoding and encapsulating sub-class.
protected abstract void parseData(JSONObject data);
protected abstract JSONObject packData();
}
Step 2: Inherit this base class to implement attachment type of "Rock-Paper-Scissors". Note: The member variables must implement "Serializable".
javapublic class GuessAttachment extends CustomAttachment {
// Finger-guessing type enumeration.
public enum Guess {
Shitou(1),
Jiandao(2),
Bu(3),
;
}
private Guess value;
public GuessAttachment() {
super(CustomAttachmentType.Guess);
random();
}
// Decode detailed data of Finger-guessing type.
@Override
protected void parseData(JSONObject data) {
value = Guess.enumOfValue(data.getIntValue("value"));
}
// Data packing.
@Override
protected JSONObject packData() {
JSONObject data = new JSONObject();
data.put("value", value.getValue());
return data;
}
private void random() {
int value = new Random().nextInt(3) + 1;
this.value = Guess.enumOfValue(value);
}
}
Step 3: Implement attachment parser of custom messages.
javapublic class CustomAttachParser implements MsgAttachmentParser {
// Determine type of attachment object based on decoded message type.
@Override
public MsgAttachment parse(String json) {
CustomAttachment attachment = null;
try {
JSONObject object = JSON.parseObject(json);
int type = object.getInteger("type");
JSONObject data = object.getJSONObject(KEY_DATA);
switch (type) {
case CustomAttachmentType.Guess:
attachment = new GuessAttachment();
break;
default:
attachment = new DefaultCustomAttachment();
break;
}
if (attachment != null) {
attachment.fromJson(data);
}
} catch (Exception e) {
}
return attachment;
}
public static String packData(int type, JSONObject data) {
JSONObject object = new JSONObject();
object.put(KEY_TYPE, type);
if (data != null) {
object.put(KEY_DATA, data);
}
return object.toJSONString();
}
}
Finally, register the attachment parser to SDK. To correctly parse custom attachment when message history is generated, the registration is generally completed in judgment statement of main process in onCreate of Application.
javaif (NIMUtil.isMainProcess(this)) {
// Monitored registration must be in the host process.
NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
}
Example: snaps
If you need to send a file message, for example, image, you can see "Self-destructing messages". Realization steps are as follows:
Step 1: Define a custom attachment type, and inherit FileAttachment
. Note: The member variables must implement "Serializable".
javapublic class SnapChatAttachment extends FileAttachment {
private static final String KEY_PATH = "path";
private static final String KEY_SIZE = "size";
private static final String KEY_MD5 = "md5";
private static final String KEY_URL = "url";
public SnapChatAttachment() {
super();
}
public SnapChatAttachment(JSONObject data) {
load(data);
}
@Override
public String toJson(boolean send) {
JSONObject data = new JSONObject();
try {
// Re-send and use local path
if (!send && !TextUtils.isEmpty(path)) {
data.put(KEY_PATH, path);
}
if (!TextUtils.isEmpty(md5)) {
data.put(KEY_MD5, md5);
}
// Notes: The code is required.
// When SDK invokes toJson, url of the father FileAttachemnt has a value.
// The value is assigned automatically by SDK.
data.put(KEY_URL, url);
data.put(KEY_SIZE, size);
} catch (Exception e) {
e.printStackTrace();
}
return CustomAttachParser.packData(CustomAttachmentType.SnapChat, data);
}
private void load(JSONObject data) {
path = data.getString(KEY_PATH);
md5 = data.getString(KEY_MD5);
url = data.getString(KEY_URL);
size = data.containsKey(KEY_SIZE) ? data.getLong(KEY_SIZE) : 0;
}
}
Step 2: Implement attachment resolver of custom message.
javapublic class CustomAttachParser implements MsgAttachmentParser {
// Determine type of attachment object based on decoded message types.
@Override
public MsgAttachment parse(String json) {
CustomAttachment attachment = null;
try {
JSONObject object = JSON.parseObject(json);
int type = object.getInteger("type");
JSONObject data = object.getJSONObject(KEY_DATA);
switch (type) {
case CustomAttachmentType.SnapChat:
return new SnapChatAttachment(data);
default:
attachment = new DefaultCustomAttachment();
break;
}
if (attachment != null) {
attachment.fromJson(data);
}
} catch (Exception e) {
}
return attachment;
}
...
}
Finally, register the attachment parser to SDK. To correctly parse custom attachment when message history is generated, the registration is generally completed in onCreate of Application.
javaif (NIMUtil.isMainProcess(this)) {
// The registration of the listener must be in the main process.
NIMClient.getService(MsgService.class).registerCustomAttachmentParser(new CustomAttachParser());
}
Message property settings
When sending a message, you can set the message configuration optionsCustomMessageConfig
, mainly determine whether the message is stored in the cloud, or whether it is written to roaming.
- Parameters
Configure CustomMessageConfig attribute for custom messages:
java/**
* It determines to store the message in server.
* The value is "true" by default.
*/
public boolean enableHistory = true;
/**
* It determines that a message must be roamed.
* The value is "true" by default.
*/
public boolean enableRoaming = true;
/**
* It determines that client must throw the message in the callback for receiving messages when the sender logs in multiple clients synchronously and one message is sent from one client.
* The value is "true" by default.
*/
public boolean enableSelfSync = true;
/**
* It determines that push tip is required for the message.
* The value is "true" by default.
*/
public boolean enablePush = true;
/**
* It determines that push display name is required for the message.
* The value is "true" by default.
*/
public boolean enablePushNick = true;
/**
* It determines that the message must be included in unread count.
* The value is "true" by default.
*/
public boolean enableUnreadCount = true;
/**
* It determines that delivery messages are required.
* The value is "true" by default.
*/
public boolean enableRoute = true;
/**
*
* It determines that the message is stored offline. If it is set to "false", the message will not be stored in offline database and message history on cloud database.
* The value is "true" by default.
*/
public boolean enablePersist = true;
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
String text = "this is an example";
// Create a text message.
IMMessage textMessage = MessageBuilder.createTextMessage(account, sessionType, text);
// Configuration options for a message.
CustomMessageConfig config = new CustomMessageConfig();
// The message is not stored in server.
config.enableHistory = false;
// The message is not roamed.
config.enableRoaming = false;
// The message is not synchronized.
config.enableSelfSync = false;
textMessage.setConfig(config);
// Send to the other party.
NIMClient.getService(MsgService.class).sendMessage(textMessage, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
File resource scenario
The SDK can set the corresponding lifetime of images, audio, videos and files.
- Preset file resource scenario
When initializing the SDK, you can configure corresponding file resource scenario, with reference codes:
java
static SDKOptions getSDKOptions(Context context) {
SDKOptions options = new SDKOptions();
//Other configurations.
options.mNosTokenSceneConfig = createNosTokenScene();
return options;
}
public static final String TEST_NOS_SCENE_KEY="test_nos_scene_key";
private static NosTokenSceneConfig createNosTokenScene() {
NosTokenSceneConfig nosTokenSceneConfig = new NosTokenSceneConfig();
//Update expiry (day) of the default scene (NimNosSceneKeyConstant.NIM_DEFAULT_IM).
nosTokenSceneConfig.updateDefaultIMSceneExpireTime(1);
//Update expiry (day) of the default scene (NimNosSceneKeyConstant.NIM_DEFAULT_PROFILE).
nosTokenSceneConfig.updateDefaultProfileSceneExpireTime(2);
// Set custom scene and related expiry (day). 0 indicates no expiry.
//We recommend to set sceneKey to a constant. As a result, it can be used conveniently. Now, at most 10 scenes can be customized.
nosTokenSceneConfig.appendCustomScene(TEST_NOS_SCENE_KEY, 4);
return nosTokenSceneConfig;
}
List of main parameters of NimNosSceneKeyConstant.
NimNosSceneKeyConstant | Meaning |
---|---|
NIM_DEFAULT_IM | Send image, audio, video, file message in private chat, group chat, and chat room. |
NIM_DEFAULT_PROFILE | Upload user and group profile (for example, profile picture) by CommsEase uploading service. |
Considerations:
- If in a nonexistent scenario, the upload will fail (error code: 5).
- If the file is expired and you download file, then download will fail (error code: 4).
Inserting a local message
If a message must be inserted to local database in service scenario, instead of being sent, then it can be implemented through inserting local messages.
java/**
// Insert a message to local database, and notify to update UI interface, but not send it to server. Send a local message that can be set others as senders to yourself.
* If the interface saves a message to the database, it will notify UI, the notification {@link MsgServiceObserve#observeReceiveMessage(Observer, boolean)} will be triggered.
*
* @param msg - Message object to be inserted.
* @param fromAccount - Sender ID.
* @return InvocationFuture - Configurable callback feature. It will be called back when the message is stored in database.
*/
InvocationFuture<Void> insertLocalMessage(IMMessage msg, String fromAccount);
/** Save a message to local database, but not send it to server. It can set the time for saving the message. It can be used for saving local tip message in the third-party APP. When the interface saves a message to the database, if UI must be notified, the parameter notify can be set to true, the notification {@link MsgServiceObserve.observeReceiveMessage(Observer, boolean)} will be triggered.
* @param msg - Message object to be inserted.
* @param notify - It determines to notify.
* @param time - Time for setting the local message.
* @return InvocationFuture - Configurable callback feature. It will be called back when the message is stored in database.
*/
InvocationFuture<java.lang.Void> saveMessageToLocalEx(IMMessage msg,boolean notify,long time);
Updating messages
Updating the extension field
The SDK can update the extension field of messages in client database.
java/**
* Update LocalExtension of a message.
* @param message - Messages to be updated.
*/
void updateIMMessage(IMMessage message);
Updating message status
java/**
* Update message status.
* @param message - Messages to be updated.
*/
void updateIMMessageStatus(IMMessage message);
Example:
javamsg.setStatus(MsgStatusEnum.success);
NIMClient.getService(MsgService.class).updateIMMessageStatus(msg);
Note: Please do not update notification
type message.
Re-sending messages
If the message is not sent successfully., you can send the message again. The message is sent and re-sent using the same interface, and only parameter settings are different. When "resend" is "true", it indicates that a message is resent.
Forwarding messages
Except notification, audio & video call event, the SDK can forward all other types of messages.
You must create a message to be forwarded using MessageBuilder
and then send the message using MsgService#sendMessage
interface.
java/**
* Forward a message.
*
* @param message - Message to be forwarded.
* @param sessionId - Chat object ID.
* @param sessionType session types.
* @return - Messages to be forwarded.
*/
public static IMMessage createForwardMessage(IMMessage message, String sessionId, SessionTypeEnum sessionType);
- Parameters
Parameter | Description |
---|---|
message | Message to be forwarded. |
sessionId | Chat object ID. It is user account for one-to-one chat and group ID for group chat. |
sessionType | Chat type. SessionTypeEnum.peer-to-peer is one-to-one chat type and SessionTypeEnum.Group is group chat type. |
- Example
java// The account is an example. Please register.
String account = "testAccount";
// The one-to-one chat type is taken for an example.
SessionTypeEnum sessionType = SessionTypeEnum.peer-to-peer;
// forwardMessage - It is the message to be forwarded and generally acquired from context.
IMMessage message = MessageBuilder.createForwardMessage(forwardMessage, account, sessionType);
// Send to the other party.
NIMClient.getService(MsgService.class).sendMessage(textMessage, false).setCallback(new RequestCallback<Void>() {
@Override
public void onSuccess(Void param) {
}
@Override
public void onFailed(int code) {
}
@Override
public void onException(Throwable exception) {
}
});
Recalling messages
Recalling a message
It allows you can recall a message that you have sent within a specified duration. The default time is 2 minutes, which can be configured on CommsEase console.
- API prototype
java/**
* Recall a message, and set related third-party push configurations (including push of ISO platform) and change in unread count. If you need to close message return tip in App, see {@link NIMClient#toggleRevokeMessageNotification(boolean on)}.
*
* @param message - Message to be recalled.
* @param customApnsText - Text of the third-party transferred push notification. If it is null, the message will not be pushed.
* @param pushPayload - The third-party custom push attribute, limited to json type, with length 2048.
* @param shouldNotifyBeCount - It determines to update unread count when a notification is recalled.
* @param postscript - Postscript
* @param attach - Extension field
*
* @return InvocationFuture - Configurable callback feature. It can monitor the sending result.
*/
InvocationFuture<Void> recallMessage(IMMessage message, String customApnsText,
Map<String, Object> pushPayload, boolean shouldNotifyBeCount,
String postscript, String attach);
- Parameters
Parameter | Description |
---|---|
message | Message to be recalled. |
customApnsText | Text of the third-party transferred push notification. If null, the message will not be pushed. |
pushPayload | The third-party defined push property is limited to json type, with length 2048. |
shouldNotifyBeCount | Determine that unread count of revocation notification must be updated. |
postscript | P.S. |
attach | Extension field |
- Example
javaNIMClient.getService(MsgService.class).recallMessage(message, null, null, true, postscript, attachJson).setCallback(new RequestCallbackWrapper<Void>() {
@Override
public void onResult(int code, Void result, Throwable exception) {
}
});
After the request of revocation message has been called successfully, the SDK will invoke the message to upper developer successfully and then automatically delete the message in local database. If a tip must be shown after revocation, the developer must create a tip message independently and call the interface of insetting local message.
The message will not be recalled successfully, if:
- The message is null.
- The message is not sent successfully.
- The message cannot be recalled due to timeout.
Content requirement for notification bar in revocation scenario: For example, A sends message to B to generate APNs with text content "Hello". Then A recalls this message and "Hello" shown in notification bar becomes default "recalled a message".
A recommended implementation method:
- When sending message, the user should insert key value with key being apns-collapse-id using NIMMessage - setPushPayload(Map pushPayload). We recommend to fill in character string such as "uuid" in "value" for unique identification.
- When recalling this message, the user should configure text in transfer parameter "customApnsText" on revocation interface and insert same apns-collapse-id key value with recalled message in pushPayload.
Listening for message recalls
The recipient will receive a notification if a message is recalled.
- API prototype
java/**
* Register or unregister the observer for recalling messages.
* @param observer - Observer. The parameter is a recalled message.
* @param register true indicates registered, and true indicates unregistered
*/
public void observeRevokeMessage(Observer<RevokeMsgNotification> observer, boolean register);
- RevokeMsgNotification
Methods | Description |
---|---|
getMessage() | Get recalled messages. |
getAttach() | Get the field of recalled attachment. |
getRevokeAccount() | Get revocation account. |
getCustomInfo() | Get msg field that is configured when the message is recalled (for example, Recall message using server API). |
getNotificationType() | Get notification type: 1 indicates offline notification; 2 indicates roaming notification; 0 is default. |
getRevokeType() | Get revocation type: peer-to-peer dual revocation; group dual revocation; Supergroup dual revocation; peer-to-peer one-way revocation, and undefined. |
getCallbackExt() | Get a third-party extension field. |
- Example
javaObserver<RevokeMsgNotification> recallMessageObserver = new Observer<RevokeMsgNotification>() {
@Override
public void onEvent(RevokeMsgNotification notification) {
// Notification for listening message revocation. Related operation can be made in the interface.
// Get recalled messages.
notification.getMessage();
// Get revocation account.
notification.getRevokeAccount();
}
};
NIMClient.getService(MsgServiceObserve.class).observeRevokeMessage(recallMessageObserver, true);
In addition, if the Message tip feature is enabled, then tip notification bar may also be triggered when revocation message is received. If unnecessary, you can
javaNIMClient.toggleRevokeMessageNotification(false);
disable this feature using XX. See Tip for recalling notification message.
Filter configuration for recall notification
A filter is configured to determine that notification bar must be displayed based on recalled notification object.
If notification bar must be displayed based on other logics, then you can determine that notification bar must be displayed based on the filter. If notification bar must not be displayed based on other logics, then whatever the filter is configured, and the notification bar must not be displayed.
The filter can be used to reduce the number of recalled messages in upper notification bar.
- API prototype
java/**
* It determines to show the filter for notifications when a message is recalled during registration.
*/
void registerShouldShowNotificationWhenRevokeFilter(ShowNotificationWhenRevokeFilter filter);
- ShowNotificationWhenRevokeFilter prototype
javapublic interface ShowNotificationWhenRevokeFilter {
boolean showNotification(RevokeMsgNotification notification);
}
- Example
javaNIMClient.getService(MsgService.class).registerShouldShowNotificationWhenRevokeFilter(notification -> {
return notification == null || TextUtils.isEmpty(notification.getAttach());
});
File transfer management
Listening for file transfer progress
The SDK can manage file transfer. Developers can monitor file transfer by registering observer for message attachment uploading or downloading process.
java/**
* Register/log out the observer for uploading/downloading progress of message attachment.
*
* @param observer - Observer. The parameter is transmission progress of attachment.
* @param register true indicates registered, and true indicates unregistered
*/
void observeAttachmentProgress(Observer<AttachmentProgress> observer,
boolean register);
Cancelling message attachment upload
You can cancel uploading message attachment using MsgService interface.
java/**
* Cancel to upload message attachment (image, video, file type). If the attachment has been uploaded successfully, the operation will be failed. If the attachment uploading is canceled successfully, related message cannot be sent successfully, related message status is MsgStatusEnum.fail, and attachment status is AttachStatusEnum.cancel. Notes: This operation is not available to chat room.
* @param imMessage - Message that is to cancel attachment uploading
*/
InvocationFuture<java.lang.Void> cancelUploadAttachment(IMMessage imMessage);
Audio message processing
CommsEase SDK provides a feature of recording and playing high-definition audio to process audio message.
Playback
CommsEase provides AudioPlayer to support audio playing feature.
AudioPlayer interface:
Return | AudioPlayer interface | Description |
---|---|---|
long | getCurrentPosition() | Get current audio playing position. |
long | getDuration() | Get audio duration. |
OnPlayListener | getOnPlayListener() | Get play listener of AudioPlayer. |
boolean | isPlaying() | Query that audio is playing. |
void | seekTo(int msec) | Skip to specified position to continue playing. |
void | setDataSource(String audioFile) | Set audio source. |
void | setOnPlayListener(OnPlayListener listener) | Set play listening. |
void | start(int audioStreamType) | Start play. |
void | stop() | Stop play. |
Creating a player instance
- API prototype
java/**
* Construct a feature for audio player.
* @param context - Context parameter.
* @param audioFile - Path of an audio file to be played.
* @param listener - Play listener.
*/
public AudioPlayer(Context context, String audioFile, OnPlayListener listener);
- Parameters
Parameter | Description |
---|---|
context | Context parameter. |
audioFile | Path of audio files to be played. |
listener | Play listener. |
OnPlayListener interface:
OnPlayListener interface | Description |
---|---|
onCompletion() | Complete play. |
onError(String error) | Error in play Cause description for parameter error. |
onInterrupt() | Interrupt play. |
onPlaying(long curPosition) | Play report; call back once every 500ms, and notify current position. The parameter is current position (unit: ms) and can be used for updating UI. |
onPrepared() | Complete file decoding, and prepare to play. |
- Example
java// Define a callback for playing progress.
OnPlayListener listener = new OnPlayListener() {
// The audio file has been transcoded and decoded, and will be played soon.
public void onPrepared() {}
// The play is ended.
public void onCompletion() {}
// The play is interrupted.
public void onInterrupt() {}
// An error occurs in playing process. Cause description for parameter error.
public void onError(String error){}
// Play progress report; call back once every 500ms, and notify current position. The parameter is current position (unit: ms) and can be used for updating UI.
public void onPlaying(long curPosition) {}
};
// Construct player object.
AudioPlayer player = new AudioPlayer(context, filePath, listener);
Playback control
- Play audio
java// Start play The parameter audioStreamType must be input to indicate telephone recipient mode or loudspeaker mode.
// Audioadministrator.STREAM_AUDIO_CALL - Telephone recipient mode.
// Audioadministrator.STREAM_MUSIC - Loudspeaker mode.
player.start(audioStreamType);
- Designate play position
java// If the player is switched during the operation, start must be invoked again and specified audioStreamType must be input. The player will stop automatically and then start again by a new streamType.
// If play must be continued from the stopped position, developers must remember the stopped position and then invoke seekTo in the callback onPrepared.
player.seekTo(pausedPosition);
- Stop play
javaplayer.stop();
- Other methods
java// Get current audio playing position.
player.getCurrentPosition();
// Get audio duration.
player.getDuration();
// Query that an audio file is being played.
player.isPlaying();
// Set the audio source.
player.setDataSource(audioFile);
Recording
SDK provides AudioRecorder to support audio recording.
AudioRecorder interface:
Return | AudioRecorder interface | Description |
---|---|---|
void | completeRecord(boolean cancel) | Complete (end) recording, and make different callback as per parameter cancel. If "cancel" is "true", IAudioRecordCallback#onRecordCancel is invoked; if it is "false", IAudioRecordCallback#onRecordSuccess is invoked. |
void | destroyAudioRecorder() | Release resource. |
int | getCurrentRecordMaxAmplitude() | Get max. amplitude at current recording; update data every 40ms; |
void | handleEndRecord(boolean isSuccess, int duration) | After end of recording, IAudioRecordCallback#onRecordSuccess is invoked. |
boolean | isRecording() | Determine that recording is being executed. |
void | startRecord() | Start record. If successful, IAudioRecordCallback#onRecordReady and IAudioRecordCallback#onRecordStart will be invoked in order. |
Create a recorder instance
- API prototype
java/**
* Construct a recorder instance.
*
* @param context - Context
* @param recordType - Type of recorded audio file (aac/amr).
* @param maxDuration - Max. recording duration. The recording will be stopped automatically at the position.
* @param cb - Call back the recording process.
*/
public AudioRecorder(Context context, RecordType recordType,int maxDuration, IAudioRecordCallback cb);
- Parameters
Parameter | Description |
---|---|
context | Context |
recordType | Type of recorded audio (aac/amr). |
maxDuration | Max. recording duration. The recording will be stopped automatically at the position. |
cb | Invoke recording process. |
- IAudioRecordCallback interface:
IAudioRecordCallback interface | Description |
---|---|
onRecordCancel() | The recording is completed. The user cancels recording actively. |
onRecordFail() | The recording is completed. It fails. |
onRecordReachedMaxTime(int maxTime) | Reach specified maximum recording time. |
onRecordReady() | Recorder is ready. The interface is used to close local audio and video play before recording (optional). |
onRecordStart(File audioFile, RecordType recordType) | Start recording invocation. |
onRecordSuccess(File audioFile, long audioLength, RecordType recordType) | The recording is completed. It is successful. |
- Example
java// Define callback object of recording process.
IAudioRecordCallback callback = new IAudioRecordCallback () {
void onRecordReady() {
// Callback returned after initialization. The interface is used for closing local audio and video play before recording (optional).
}
void onRecordStart(File audioFile, RecordType recordType) {
// Callback for starting recording.
}
void onRecordSuccess(File audioFile, long audioLength, RecordType recordType) {
// The recording is completed. It is successful.
}
void onRecordFail() {
// The recording is completed. It fails.
}
void onRecordCancel() {
// The recording is completed. The user cancels recording actively.
}
void onRecordReachedMaxTime(int maxTime) {
// Reach specified maximum recording time.
}
};
// Initialize recorder
AudioRecorder recorder = new AudioRecorder(
context,
RecordType.AAC, // Type of recorded audio file (aac/amr).
maxDuration, // Max. recording duration. The recording will be stopped automatically at the position. The value is 120s by default.
callback // Callback for recording process.
);
Recording control
- Record audio
java// Start recording. If it is successful, onRecordReady and onRecordStart will be called back in order.
recorder.startRecord();
- End or cancel recording
java// End recording, end normally, or cancel recording.
// If cancel is set to true, it indicates to cancel recording; if it is set to false, it indicates to end recording.
recorder.completeRecord(cancel);
- Destruction example
javarecorder.destroyAudioRecorder();
- Other methods
java
// It determines that recording is being executed.
recorder.isRecording();
// Get max. amplitude at current recording; update data every 40ms;
recorder.getCurrentRecordMaxAmplitude();
// When the maximum recording duration is reached, the current recording is confirmed.
recorder.handleEndRecord(true, maxTime)
Audio-to-text
To enable the audio-to-text feature, please contact our business consultant and apply for "audio recognition". If the interface is called without enabling this feature, return 403.
Principle of audio-to-text:
- Record audio files (maximum 60 seconds).
- Upload to the CommsEase storage server and return the file url.
- Input the url and related parameters through the audio-to-text interface, and return the converted text.
The following method under MsgService interface is used for audio-to-text:
java/**
* Transform an audio file into text and specify the scene for uploading file and that the file must be re-uploaded.
* @param audioUrl - Audio url Optional. If there is no such option, SDK will upload nos automatically.
* @param path - Audio path. It is used for getting audio sampling rate. app must ensure that the audio file has been downloaded to local database.
* @param duration - Audio duration.
* @param sceneKey - nos sceneKey used for uploading a file. The value is NimNosSceneKeyConstant#NIM_DEFAULT_IM by default. For configuration parameter nos token scene, see the chapter of file resource scene.
* @param enableForceUploadFile - It determines to upload the file again if there is same file in the server. The value is false by default.
* AbortableFuture - Callback tracking The callback feature can be configured to stop downloading.
*/
AbortableFuture<java.lang.String> transAudioToTextEnableForce(java.lang.String audioUrl,
java.lang.String path,
long duration,
java.lang.String sceneKey,
boolean enableForceUploadFile);
Example:
javapublic void audioToText(IMMessage msg, String sceneKey) {
AudioAttachment attachment = (AudioAttachment) msg.getAttachment();
String audioUrl = attachment.getUrl();
String path = attachment.getPath();
refreshStartUI();
callFuture = NIMClient.getService(MsgService.class).transAudioToTextEnableForce(audioUrl, path, attachment.getDuration(), sceneKey, false);
callFuture.setCallback(new RequestCallback<String>() {
@Override
public void onSuccess(String param) {
audioTransText.setText(param);
updateUI();
}
@Override
public void onFailed(int code) {
LogUtil.e(TAG, "audio to text failed, code=" + code);
audioTransText.setText(R.string.trans_audio_failed);
failIcon.setVisibility(View.VISIBLE);
updateUI();
}
@Override
public void onException(Throwable exception) {
LogUtil.e(TAG, "audio to text throw exception, e=" + exception.getMessage());
audioTransText.setText("Parameter error");
failIcon.setVisibility(View.VISIBLE);
updateUI();
}
});
show();
}