46 2 371KB
M800SDK User Manual for Android M800 SDK Android User Guide v. 141
Contents M800 SDK Android User Guide v. 141 Contents Introduction Glossary How to Import the M800SDK How to Configure the M800SDK Step-by-step guide: Sign-up Module Introduction Pre-requisites How to implement sign-up Sign up as a White Label User Sign up as a SDK user After a successful sign up Connection Module Introduction Pre-requisites How to implement More on Connection Management Contact Sync Module Introduction Pre-requisites How to implement Get M800 contact list Get M800 native contact list Start contact sync manually Sync roster Add M800 contact Remove M800 contact Register roster event listener Find M800 contact by phone number. Find M800 contact by JID Presence (Last Seen) Call Module Introduction How to implement Making an outgoing on-net call (VOIP – VOIP call) To make an outgoing off-net call (VOIP – PSTN call) Receiving an incoming call IM Push Notification Remote Notification To reject a call silently from an incoming call notification bundle To handle a missed call notification How to Configure M800ClientConfiguration Steps to provide a comprehensive call experience Support the mute and speaker feature Play a sound locally to notify user the call is connected Play a sound locally to notify user he/she has sent a DTMF (dual tone multi frequency) tone over the call Dim screen when user’s face is close to the screen. Work closely with network status. Work closely with native phone status. Responsive UI to the in-call events Incoming call notifications. Missed call notifications. Call history management. Use Third Party Push Service IM Module Introduction Pre-requisites How to Implement Single User Chat Room(SUC) Single User Chat Room(SUC) Creation Monitor Single User Chat Room(SUC) Activity Retrieve Single User Chat Room(SUC) Single User Chat Room(SUC) Deletion Retrieve Participants In Single User Chat Room(SUC) Multi User Chat Room(MUC)
Multi User Chat Room(MUC) Creation Monitor Multi User Chat Room(MUC) Activity Retrieve Multi User Chat Room(MUC) Retrieve Participants In Multi User Chat Room(MUC) Multi User Chat Room(MUC) Synchronization Multi User Chat Room(MUC) Participants Management Leave Multi User Chat Room(MUC) Multi User Chat Room(MUC) Property Management System Chat Room Monitor System Chat Room Activity Retrieve System Chat Room SMS Chat Room Create SMS Chat Room Monitor SMS Chat Room Activity Retrieve SMS Chat Room Delete SMS Chat Room Retrieve Chat Participants in SMS Chat Room Messaging Introduction Send text message Send SMS message Send audio message Send image message Send video message Send ephemeral message Register message listener Set media file upload progress listener Get historical chat messages and statistics Retrieve message data Manage ephemeral message Remove chat messages Forward chat message Read chat message Send chat state Monitor chat state changes Credit Module Introduction to Credit Module Pre-requisites How to Implement Contact Management Introduction How to implement Add Contact Remove contact Add or Remove Contact Callback Rate Table Module Introduction Pre-requisites How to implement To retrieve an instance of the RateManager: To listen for change event in the Rate Table: To update the RateManager’s data from server: To check if the RateManager’s data is up-to-date: To retrieves rates: Find User Module Introduction How to Implement Find user by phone number/JID Find User by PIN Find User by Recommendation Find User by Location Report and Block User User Profile Module Introduction How to Implement Retrieve current user profile Retrieve Name Retrieve Status Retrieve Gender Retrieve Birthday Retrieve Email Address Retrieve Profile Image
Retrieve Cover Image Retrieve Caller Video Update current user profile Update Name Update Status Update Gender Update Birthday Update Email Address Update Profile Image Update Cover Image Update Caller Video Delete Profile Image Delete Cover Image Delete Caller Video User Preference Introduction How to Implement Retrieve / Modify User Preference Language Recommendation Find users by Pin/Phone Find users by location My video caller ID visibility Other's video caller ID visibility Presence Displayed Receipt Message notifications Monitor User Preference Update Activity User Preference Synchronization
Introduction The M800 SDK is a Java library for Android which enables developers to leverage M800's global voice and messaging platform. The M800 SDK allows the developer to easily add voice and messaging functionality to an Android app, so that app users can make phone calls, chat, retrieve contact lists, find users, and more. This guide demonstrates the key APIs of the SDK. Previous development experience with Java and the Android platform is assumed.
Glossary JID
A unique identifier for end users. JID stands for Jabber Identifier. For example: [email protected].
On-net call
This is a call using a data connection between two M800 apps. On-net calls are peer-to-peer calls to/from other SDK-based clients.
Off-net call
This is a call from M800 to a number on another network. Off-net calls are calls to landline or mobile numbers.
PSTN
The public switched telephone network, i.e. the regular telephone network.
How to Import the M800SDK Place the M800SDK.aar file and M800PhoneVerification.aar/M800PhoneVerification_testbed.aar files in your project directory. Add following dependencies for M800SDK in your project’s gradle file:
// M800 SDK dependencies compile 'com.google.guava:guava:18.0' compile 'com.google.code.gson:gson:2.3.1' compile 'com.google.code.findbugs:jsr305:2.0.3' compile 'com.google.android.gms:play-services:7.0.0' compile 'com.googlecode.libphonenumber:libphonenumber:7.0.4' compile 'com.infstory:proguard-annotations:1.0.1' compile 'com.fasterxml.jackson.core:jackson-core:2.4.1' compile 'com.fasterxml.jackson.core:jackson-annotations:2.4.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.1' // M800 SDK compile (name: 'M800SDK', ext: 'aar') { transitive = true }
Add following dependencies for Phone Verification in your project’s gradle file:
Production environment:
//M800 Phone Verification SDK compile (name: 'M800PhoneVerification', ext: 'aar')
Testbed environment:
//M800 Phone Verification SDK compile(name: 'M800PhoneVerification_testbed', ext: 'aar')
Note that the size of M800SDK library is large. If the total method count of the application reaches 64k, you will need enable in the your project’s gradle file: Add following dependencies for M800SDK in your project’s gradle file:
// Multidex library compile ‘com.android.support:multidex:1.0.1'
Add the configuration also to enable multiDexEnabled
android { compileSdkVersion 21 buildToolsVersion "22.0.1" defaultConfig { minSdkVersion 16 targetSdkVersion 21 versionCode 1 versionName "1.0" multiDexEnabled true } }
Add the following meta-data in your project’s AndroidManifest.xml file: Production environment:
Include the following files if you have ProGuard enabled in your project:
proguardFile 'M800SDK-proguard-rules.pro' proguardFile 'annotations.pro'
How to Configure the M800SDK To connect your app to M800, you need to generate a capabilities signature or capsig to set your authorization levels on our network. To generate the capsig, use your application secret which was provided when you sign up and specify the capabilities and expiry. To initialize services, you should also add the following keys in your AndroidManifest.xml 1. Developer Key (supplied by M800) 2. Application Key (supplied by M800) 3. Application Identifier (supplied by M800) 4. Application Version: 1.0.0 (default value) 5. Capabilities: incoming, outgoing (default value) 6. Expiry (in seconds) 7. Carrier Name (supplied by M800) 8. Application Secret (supplied by M800) 9. Developer Secret (supplied by M800)
Then implement these with M800SDKConfiguration as follows:
// Configure M800SDK M800SDKConfiguration configuration = M800SDK.newConfiguration(); PreferenceUtil.fillInConfigurationWithPreference(configuration, this); configuration.setCertificateFileForCall(mM800CertificateFile); configuration.setCertificateFileForIM(mM800CertificateFile); M800SDK.setConfiguration(configuration);
Step-by-step guide: When using AndroidManifest.xml, copy the meta-data codes below into your AndroidManifest.xml. Place your code values in the appropriate space; values represented here would of course be supplied by M800:
Prepare the M800Certificate File (mM800CertificateFile). In the demo app project, the source certificate file is named as cacert.crt and placed in the /asset. To see the full implementation, you should go to the ApplicationClass.java and look into the method :
private void copyCertificateFromAsset() { String filename = "cacert.crt"; mM800CertificateFile = copyFileFromAsset(filename); if (mM800CertificateFile != null) { Log.d(TAG, "Certificate for IM:" + mM800CertificateFile.getAbsolutePath()); } }
Get a new M800SDKConfiguration object from M800SDK.newConfiguration().
M800SDKConfiguration configuration = M800SDK.newConfiguration();
Fill the keys, mentioned in Step 1, into the M800SDKConfiguration object. In the demo project, we used a helper class, PreferenceUtil, to fill the keys. You may go to this class to reference the full implementation.
PreferenceUtil.fillInConfigurationWithPreference(configuration, this);
Provide the M800Certificate File from Step 2 to the M800SDKConfiguration object by
configuration.setCertificateFileForCall(mM800CertificateFile); configuration.setCertificateFileForIM(mM800CertificateFile);
Finally, set the M800SDKConfiguration object for M800SDK.
M800SDK.setConfiguration(configuration);
Note. You will need to set all of the following permissions in your manifest.xml file:
You will need additional permissions for M800PhoneVerification SDK. Please refer to the corresponding user manual.
Sign-up Module Introduction The sign-up Module lets a 1st time user sign-up to the M800 server. A successful sign-up allows the end user to log in and out from the app in the future.
Pre-requisites Before sign-up, a user needs to be verified. Please consult the M800 Phone Verification SDK’s user manual, for details on how to implement phone verification. The M800 Phone Verification SDK is a separate product from the M800 SDK in this user guide.
How to implement sign-up After configuring M800SDK, user has to sign up before connecting to M800SDK. To see if user has signed up to M800SDK, you can invoke
M800SDK.getInstance().hasUserSignedUp()
If the method above returns false, user hasn’t signed up, the sign up mechanism is crucial before connecting to M800SDK. Please invoke M800SDK.getInstance().getManagement().signup(...) to start sign up.
Sign up as a White Label User We provide two signup methods for you to use, the first one is signup with verification request ID. You should always use this signup API if possible.
/** * Sign up user with your verified phone number, requestId and display name. * * @param phoneNumber * The phone number that to be registered. Numeric digits only. * @param regionCode * The region code of user's region. 2-letters. For example, “hk” if the user's region is Hong Kong. * @param displayName * The display name of user. * @param language * The {@link com.m800.sdk.IM800Management.M800Language} object. The preferred language of this user. Language will be applied * in the push string. * @param callback * The {@link M800ManagementCallback} interface to handle result of operation. */ public void signup(final String displayName, final String phoneNumber, final String regionCode, final String requestId, final M800Language language, final M800ManagementCallback callback);
We also provide another API that can signup without verification request ID. If the provided phone number is never registered before, the signup will be successful, but the user need to verify his/her phone number later when he/she wants to use any paid functions of M800SDK like offnet call, SMS chat. If the provided phone number is registered before and is signing up with the same device, the signup will be successful and the user will remain her/his previous verification status. If the provided phone number is registered before and user is switching device, the signup will be failed with error, indicating that the user need to verify his/her phone number again. To verify user's phone number, please use M800 Verification SDK and the signup API above.
/** * Sign up user with your phone number. * * * @param phoneNumber * The phone number that to be registered. Numeric digits only. * @param regionCode * The region code of user's region. 2-letters. For example, 'hk' if the user's region is Hong Kong. * @param displayName * The display name of user, optional * @param language * The {@link com.m800.sdk.IM800Management.M800Language} object. The preferred language of this user. Language will be applied * in the push string. * @param callback * The {@link M800ManagementCallback} interface to handle result of operation. */ void signup(final String displayName, final String phoneNumber, final String regionCode, final M800Language language, final M800ManagementCallback callback);
Take the demo project as an example, user verification information is saved as a VerificationInfo object. Please refer to the class Verificat ionManager.java.
private void signUpAfterVerified(VerificationInfo verificationInfo){ M800SDK.getInstance().getManagement().signup( verificationInfo.displayName, verificationInfo.number, verificationInfo.countryCode.getCountyCode(), verificationInfo.record.getRequestId(), IM800Management.M800Language.M800LanguageEnglish, new IM800Management.M800ManagementCallback() { @Override public void complete(boolean isSuccess, M800Error error, Bundle userInfo) { if (isSuccess) { connectAfterSignup(); } else { //Implement your own sign up failure handling mechanism. } } } }); }
Sign up as a SDK user To sign up as a SDK user, you would have no meta-data set as described below
Invoke the following method to sign up:
/** * Sign up user with your network id and display name. * * @param sourceNetworkId * The id of source network to be registered, {0-1, a-z} only. * @param displayName * The display name of source network. * @param language * The preferred language of this user. Language will be applied in the push string * @param callback * The interface to handle result of operation. * @throws IllegalStateException * sourceNetworkId is illegal that should be alphanumeric and the length is not greater than the value defined by * M800SDK_MaxSourceNetworkIdLength */ public void signup(String sourceNetworkId, String displayName, M800Language language, M800ManagementCallback callback);
After a successful sign up After a successful sign up, you can get current user’s phone number by the following API:
M800SDK.getInstance().getUsername();
After a successful sign up, You can get current user’s JID (M800 unique identifier) by the following API:
M800SDK.getInstance().getUserJID();
After a successful sign up, please connect to M800 server in order to use the M800SDK provided features. Connection details are provided in the Connection section.
Connection Module Introduction The Connect Module allows the app to manage the connection to M800 servers. Specfically, the module lets the app perform the following: Connect to M800 server. Disconnect from M800 server. Check connection status. Go online. Go offline. Sign out current user.
Pre-requisites Successful sign-up should have been completed before connecting to M800 servers.
How to implement After signing up to the M800SDK, connection with M800 Server must be established before using the IM and Call features. 1. To check if the user has signed up, please follow Step 1 in the previous session (Sign Up to M800SDK). 2. To check the connection state, please invoke M800SDK.getInstance().getManagement().getConnectionState().
/** * This enumeration contains states that represents connection status of * Management module */ public static enum M800ManagementConnectionState { M800ManagementConnectionDisconnected, /** < Disconnected */ M800ManagementConnectionConnecting, /** < Connecting */ M800ManagementConnectionConnected, /** < Connected */ }
An alternative method is M800SDK.getInstance().getManagement().isConnected(). 3. Invoke M800SDK.getInstance().getManagement().connect() to connect to the M800SDK server.
/** * Connect to management server with current user stored in system. * */ public void connect();
4. Implement the IM800Management.M800ManagementConnectionListener interface to monitor the connectivity with M800SDK server.
/** * This listener can receive events while connection is changed to connected or disconnected * @see com.m800.sdk.IM800Management.M800ManagementConnectionState */ public static interface M800ManagementConnectionListener { /** * Client is connected to M800 servers. */ public void onConnectedToM800(); /** * Client is disconnected from M800 servers with error. * If error is NotAuthorized, then need to kick user from system and signup new user again. * @param error The reason why is disconnected. * */ public void onDisconnectedFromM800(M800Error error); }
5. For the full implementation of connection management, please refer to the ApplicationClass.java in the demo project as an example. Implement IM800Management.M800ManagementConnectionListener interface to monitor the connectivity:
public class ApplicationClass extends MultiDexApplication implements IM800Management.M800ManagementConnectionListener { @Override public void onCreate() { super.onCreate(); … M800SDK.getInstance().getManagement().addConnectionListener (this); } @Override public void onConnectedToM800() {} @Override public void onDisconnectedFromM800(M800Error error) { //Do disconnection handling if (M800SDK.getInstance().getManagement().needKickUserForError(error)){ kickUser(error); } } }
Invoke M800SDK.getInstance().getManagement().connect() to trigger connection.
6. To disconnect from M800 server, please invoke M800SDK.getInstance().getManagement().disconnect().
More on Connection Management This section introduces more features that are supported in the connection module. 1. To update the server user is active with the M800SDK/application, please invoke M800SDK.getInstance().getManagement().goOnline(). Custom status can be added also when going online. M800SDK.getInstance().getManagement().goOnline(String status). 2. To update the server user is inactive with the M800SDK/application, please invoke M800SDK.getInstance().getManagement().goOffline() 3. To clear user data as “logout” from the M800 server, please invoke M800SDK.getInstance().getManagement().clearAllUserData() Below is an example.
private void logoutUser() { final Runnable logoutTask = new Runnable() { @Override public void run() { M800SDK.getInstance().getManagement().clearAllUserData(); } }; new Thread(logoutTask).start(); }
4. User may receive an M800Error object in the following two cases: A disconnection event from the listener IM800Management.M800ManagementConnectionListener. onDisconnectedFromM800( M800Errorerror). See section Connect to M800SDK 5.a. A connection attempt failure from listener IM800Management.M800ManagementConnectionListener.onDisconnectedFromM800( M800Error error) when the application is trying to connect to the M800 server. See section Connect to M800SDK 5.b. The reason of connection failure may due to user invalidation. Please do the checking by invoking M800SDK.getInstance().getManagement ().needKickUserForError(M800Error) with the given M800Error object to see if user should be logout from M800 server.
/** * Checks whether is the error to kick user out from app. * * @param error The given error from M800 callbacks. * @return If true, means the user is invalid, need to kick user out. * Otherwise if false, means the current user is still valid and can be continued to use. */ public boolean needKickUserForError(M800Error error);
If result is positive, please proceed to user data clean up as introduced in point 3. 5. Swap Device. When user has signed up with the same phone number on a new device, M800 server invalidates the user on the older device. On the older device, user will receive the connection error, an M800Error object with M800ErrorCode.Not Authorized as descripted in point 4. Plea se do the checking by invoking M800SDK.getInstance().getManagement().needKickUserForError(M800Error) with the given M800Error object to see if user should be logout from M800 server for confirmation. Finally, follow the step in point 3 to clear the user sign up data. 6. Custom Notifications. The connection module supports custom notifications sent from M800 server. Developer need to implement and manage their own M800No tificationListener object and register to the M800SDK by invoking M800SDK.getInstance().getManagement().addNotificationListener(M800NotificationListener listener).
Contact Sync Module Introduction After user signs up and connects to M800 server for the first time, M800 SDK performs contact sync automatically. 1. SDK gathers and sends a list of all native contacts to the M800 server. By native contact, we mean a contact inside the device’s address book. Upon receipt of the list, M800 server returns a list of M800 users found in the native contacts. The information will saved so that user can know who are using the same application and add them as M800 contacts easily. 2. SDK uses Roster to represent a list of people (M800 contacts) the user is connected to. SDK queries roster from M800 server and saves the query result, which is a list of user's M800 contacts. In short, contact sync contains two parts, one is to sync native contacts, the other is to sync roster. The contact sync is complete after all M800 contacts' information is retrieved from server and added to the SDK’s database.
Every M800 contact has its unique JID (Jabber Identifier). JID is represented in two parts. The text before @ is the phone number with country code prefix. The text after @ is the carrier name. After contact sync is completed, if an M800 contact is a native contact, it can be searched by JID or phone number. If the M800Contact is not in native phone book, it can only be searched by JID.
Pre-requisites Successful sign-up and connection to M800 server.
How to implement Get M800 contact list class GetContactsTask extends AsyncTask { @Override protected List doInBackground(Void... params) { return M800SDK.getInstance().getContactManager().getM800Contacts(); } @Override protected void onPostExecute(List contacts) { // Update UI } }
Get M800 native contact list
class GetContactsTask extends AsyncTask { @Override protected List doInBackground(Void... params) { return M800SDK.getInstance().getContactManager().getM800NativeContacts(); } @Override protected void onPostExecute(List contacts) { // Update UI } }
Start contact sync manually M800 SDK will do contact sync automatically in the following scenarios: After user signup. After app initializes M800SDK, it will start to observe native address book changes. If it detects any phone number or email address ch anges, it will start contact sync. You might want to do contact sync when app launches or at fixed rate of time apart from auto sync.
M800SDK.getInstance().getContactManager().startSyncNativeAddressBook(boolean fullSync);
There is a limitation of how frequent M800 SDK can do contact sync, the default value is 1 minute. You can change this value. Note. Don’t set this value too low, contact sync is very memory and network bandwidth consuming.
M800SDK.getInstance().getContactManager().setMinimumContactSyncTimeInterval(millis);
To find out whether SDK is in synchronizing native contacts:
M800SDK.getInstance().getContactManager().isNativeAddressBookSyncInProgress();
Sync roster You can sync roster without sync native contacts.
M800SDK.getInstance().getContactManager().queryM800ContactRoster();
Add M800 contact To add an M800 contact, user needs to send an add contact request to an M800 user. The M800 user can choose to accept or decline the request. Before the recipient takes any action, user can cancel the request. If the M800 user accepts the add contact request, both sides will receive a new contact roster push and they become friends of each other.
// Sender side: Create a request M800AddContactRequest request = ; // Sender side : Send the request M800SDK.getInstance().getContactManager().requestAddM800Contact(request); // Sender side : Cancel the request String recipientJID = ; M800SDK.getInstance().getContactManager().cancelM800AddContactRequest(recipientJID ); // Recipient side String requesterJID = ; // Recipient side : Accept the request M800SDK.getInstance().getContactManager().acceptM800AddContactRequest(requesterJID); // Recipient side : Decline the request M800SDK.getInstance().getContactManager().declineM800AddContactRequest(requesterJID);
To retrieve add contact requests:
// Get a list of requests M800SDK.getInstance().getContactManager().getM800AddContactRequests(); // Get one request M800SDK.getInstance().getContactManager().getAddContactRequest(, ); // Get requests count M800SDK.getInstance().getContactManager().getAddContactRequestsCount();
Remove M800 contact If user removes an M800 user from his/her contact list, the M800 user will not be notified and still can see current user as his/her contact.
M800SDK.getInstance().getContactManager().removeM800Contact();
Register roster event listener SDK will receive several kinds of roster push events: 1. 2. 3. 4.
New contact added Contact removed Add friend request Contact profile changed
To listener to the roster activities and push events, implement the following listener:
M800SDK.getInstance().getContactManager().addContactChangeListener(this); M800SDK.getInstance().getContactManager().removeContactChangeListener(this);
@Override public void onQueryRosterStart() { // Called when SDK starts to query roster } @Override public void onContactSyncCompleted(boolean hasChange) { // Called when SDK receives roster push or roster query response } @Override public void onContactSyncError(IM800ContactManager.Error error) { // Called when error happens during contact sync } @Override public void onNewAddContactRequest(M800AddContactRequest request) { // Called when SDK receives a new add contact request } @Override public void onAddContactRequestComplete(String jid, M800AddContactRequest.Direction direction, boolean isAccepted) { // Called when an add contact request is being accepted/declined/cancelled }
Find M800 contact by phone number. Note: Result will only contain M800 contacts that are also in user’s native address book.
M800SDK.getInstance().getContactManager().findM800ContactByPhoneNumber(phone#);
Find M800 contact by JID M800SDK.getInstance().getContactManager().findM800ContactByJID(JID);
Presence (Last Seen) User can send online and offline messages to M800 server so that the server can store it as his/her presence information. In user preference module, user can turn off the share presence function so no other user can see his/her presence. To send online message:
// Connect to M800 and send online message M800SDK.getInstance().getLifeCycleManager().applicationWillEnterForeground();
To send offline message:
// Send offline message immediately M800SDK.getInstance().getManagement().goOffline(); // Disconnect from M800 and send offline messages after 10 minutes M800SDK.getInstance().getLifeCycleManager().applicationDidEnterBackground();
User can query his/her contact’s presence information:
M800SDK.getInstance().getContactManager().queryLastSeen(JID, true, new IM800ContactManager.QueryLastSeenCallback() { @Override public void onComplete(String JID, IM800ContactManager.UserPresence presence, Date date) { } @Override public void onError(String JID, M800Error error) { } });
M800 server will also push current user’s contact’ presence information, to listen to the presence changes:
M800SDK.getInstance().getContactManager().addUserPresenceListener(new IM800ContactManager.UserPresenceListener() { @Override public void onPresenceChanged(String JID, IM800ContactManager.UserPresence presence) { } });
Call Module Introduction M800SDK provides functionality to initiate and handle calls. There are three major models which facilities the call feature: M800Client, M800ClientConfiguration and M800Call. M800Client manages the call engine of M800SDK, creates and preserve call objects from the initialization of user action or incoming call bundles. It provides APIs for the application to listen for the call engine status via M800ClientDelegate listener. To get the M800Client singleton from M800SDK, please invoke M800SDK.getInstance().getRealtimeClient(). M800ClientConfiguration configures the call engine setting. For example, it configures the threshold of packet loss, the ring-back tone and the hold tone. M800SDK creates a default M800ClientConfiguration configuration for M800Client during SDK initialization. To get the current M800ClientC onfiguration setting from M800Client, please invoke M800SDK.getInstance().getRealtimeClient().getCurrentConfiguration().
Developer may provide the customized M800ClientConfiguration configuration to M800Client and restart it, see M800Client.start(M800Clien tConfiguration configuration):
/** * Starts client with a new configuration. * @param configuration * A new configuration contains username, password, resources and so on. */ void start(M800ClientConfiguration configuration);
M800Call represents a VOIP call managed by M800Client. It provides information of a call. It manages the in-call activities of a call. For example, it provides APIs to answer if it is an incoming call and to terminate the call. M800Call also updates the application the call status and events. To listen for the status of a M800Call object. See
/** * Adds delegate to handle evens of this call session. * @param delegate To listener to call event. */ void addCallDelegate(M800CallDelegate delegate);
To understand more about the call module, the best way is to look into the class description, Java Documentation, on the package com.m800.msme.api.
How to implement In this section, we are going to descript the step-by-step procedure for how to use the main features provided by M800 call engine.
Making an outgoing on-net call (VOIP – VOIP call) Get the M800Client instance from M800SDK. See com.m800.uimenu.RealtimeMenuActivity from the demo project.
M800Client realtimeClient = M800SDK.getInstance().getRealtimeClient();
Create an outgoing call object by M800Client.
M800OutgoingCall call = realtimeClient.createCall(userName, displayName, carrier, null, "");
Please check the Java Documentation for the full description of input parameters. And refer to com.m800.uimenu.RealtimeMenuActivity from the demo project for solid implementation.
/** * Makes a call to given receiver which maybe phone number or user id. * If receiver is a phone number, it is an offnet call. * If receiver is user id (JID), it is an onnet call. * @param username e.g. "+85288888888", the phone number or the username of JID * @param carrier e.g. "maaii.com", the carrier of JID. i.e. existence of {@code carrier} determines this is a Off-net call. * @param display the encode display name with Base64 of user (the caller). This is sent to the receiver as part of the incoming call notification information. * @param userInfo Put caller extra info. e.g. name, social info, etc. * @param callID A random id used to distinguish the {@link M800Call} object. * @return A {@link M800OutgoingCall} made by the information provided. */ @Nullable M800OutgoingCall createCall(String username, String display, String carrier, Map userInfo, String callID);
Note: The display name should have encoded with Base64. Present your own UI for the call. Invoke dial
call.dial();
Add listener M800CallDelegate to the outgoing call object. See com.m800.phonecall.CallScreenActivity from the demo project.
public class CallScreenActivity extends Activity implements OnClickListener, M800CallDelegate { @Override public void onStart() { super.onStart(); String callID = getIntent().getExtras().getString(EXTRA_KEY_CALL_ID); mCall = M800SDK.getInstance().getRealtimeClient().getCall(callID); mCall.addCallDelegate(this); } //Your own implementations }
Work closely with call events from the implemented M800CallDelegate. See com.m800.phonecall.CallScreenActivity from the demo project. When the callee answers your call, you will receive the callBeginTalking events from M800CallDelegate.
/** * Event: call is talking. * @param call The call. */ void callBeginTalking(M800Call call);
The event indicates the call has started and you are talking with the callee. After a certain period, you will receive a callTerminated event when the call ends. The termination would be triggered by either the callee’s or your action to stop the call, the network failure or some other failure reasons.
/** * Event: call is ended for some reasons. * @param call The call. */ void callTerminated(M800Call call, int status, Map userInfo);
Otherwise, if the callee rejects your call, you will receive the callTerminated event from M800CallDelegate directly. Get the M800Client instance from M800SDK. See com.m800.uimenu.RealtimeMenuActivity from the demo project.
To make an outgoing off-net call (VOIP – PSTN call) Get the M800Client instance from M800SDK. See com.m800.uimenu.RealtimeMenuActivity from the demo project.
M800OutgoingCall call = realtimeClient.createCall(userName, displayName, carrier, null, "");
Create an outgoing call object by M800Client. Please be reminded that no carrier should be provided.
M800OutgoingCall call = realtimeClient.createCall(userName, displayName, null, null, "");
Please check the Java Documentation for the full description of input parameters. And refer to com.m800.uimenu.RealtimeMenuActivity from the demo project for solid implementation.
/** * Makes a call to given receiver which maybe phone number or user id. * If receiver is a phone number, it is an offnet call. * If receiver is user id (JID), it is an onnet call. * @param username e.g. "+85288888888", the phone number or the username of JID * @param carrier e.g. "maaii.com", the carrier of JID. i.e. existence of {@code carrier} determines this is a Off-net call. * @param display the encode display name with Base64 of user (the caller). This is sent to the receiver as part of the incoming call notification information. * @param userInfo Put caller extra info. e.g. name, social info, etc. * @param callID A random id used to distinguish the {@link M800Call} object. * @return A {@link M800OutgoingCall} made by the information provided. */ @Nullable M800OutgoingCall createCall(String username, String display, String carrier, Map userInfo, String callID);
Note: The display name should have encoded with Base64. Present your own UI for the call. Invoke dial.
call.dial();
Add listener M800CallDelegate to the outgoing call object. See com.m800.phonecall.CallScreenActivity from the demo project
public class CallScreenActivity extends Activity implements OnClickListener, M800CallDelegate { @Override public void onStart() { super.onStart(); String callID = getIntent().getExtras().getString(EXTRA_KEY_CALL_ID); mCall = M800SDK.getInstance().getRealtimeClient().getCall(callID); mCall.addCallDelegate(this); } //Your own implementations }
Work closely with call events from the implemented M800CallDelegate. See com.m800.phonecall.CallScreenActivity from the demo project. When the callee answers your call, you will receive the callBeginTalking events from M800CallDelegate.
/** * Event: call is talking. * @param call The call. */ void callBeginTalking(M800Call call);
The event indicates the call has started and you are talking with the callee. After a certain period, you will receive a callTerminated event when the call ends. The termination would be triggered by either the callee’s or your action to stop the call, the network failure or some other failure reasons.
/** * Event: call is ended for some reasons. * @param call The call. */ void callTerminated(M800Call call, int status, Map userInfo);
Otherwise, if the callee rejects your call, you will receive the callTerminated event from M800CallDelegate directly.
/** * Event: call is ended for some reasons. * @param call The call. */ void callTerminated(M800Call call, int status, Map userInfo);
The int status tells the call termination reason.
Receiving an incoming call Incoming call notification bundles arrive the device via two channels, IM Push notifications and Remote Notifications:
IM Push Notification The bundle is received internally via M800SDK connection module. It is broadcasted to the application level once it is received. To listen for the IM Push Notifications for call, please register a BroadcastReceiver for the IntentFilter M800CallNotification.getIntentFilterForM800CallNotifications(Context). Please see com.m800.service.AppM800Service as an example:
@Override public void onCreate() { super.onCreate(); BroadcastReceiver mCallNotificationReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { //Implement your own code } }; LocalBroadcastManager.getInstance(this).registerReceiver(mCallNotificationReceiver, M800CallNotification.getIntentFilterForM800CallNotifications(this)); }
Remote Notification
Received and configured by the application. For example, the incoming call notification will be received as GCM. Developer should configure and implement the GCM service on application level. To handle the incoming call notification bundles: When incoming call notification bundle is received from Step 1, please provide it to the M800Client instance by invoking M800Client.catch RemoteNotification(bundle). You may look into com.m800.service.GcmIntentService for reference.
/** * Handle M800 Call notifications from GCM or M800 Push Service * @param intent */ public static void onHandleCallNotification(Context context, Intent intent){ Bundle bundle = intent.getExtras(); M800Client client = M800SDK.getInstance().getRealtimeClient(); if (client != null) { // Handle incoming push call M800IncomingCall call = client.catchRemoteNotification(bundle); if (null != call) { //Start call UI } } }
With the returned M800IncomingCall object from M800IncomingCall call = client.catchRemoteNotification(bundle);, application may now work with the incoming call. Present your own UI to work with the incoming call. For example, provide a button on screen for call answering and provide a button for call rejecting. Do the same as in the section “To make an outgoing off-net call (VOIP – PSTN call)” step 6, implemented M800CallDelegate to listen for the call To reject the call, invoke M800IncomingCall.reject(Stringreason). To answer the call, invoke M800IncomingCall.answer(). Note. The M800IncomingCall.callId() is different from the call ID from the incoming call notification bundle. If you want to match the call ID from the incoming call notification bundle, follow the below steps: Check if this is a push call by M800Call.isPuchCall(). If it is a push call, you can use M800Call.getPushCallId() to match with the incoming call notification bundle.
To reject a call silently from an incoming call notification bundle It is not the best practice to create an incoming call object and notify the user regardless to the device status. The application should decide when to procced the incoming call or to reject the call silently. Invoke the method below to reject the call when user is busy with another call, either the native PSTN call or M800 call: M800Client.rejectCallSinceBusyWithRemoteNotification(Bundle bundle) You will receive a missed call notification afterwards.
To handle a missed call notification The missed call notification bundle handling is same as incoming call notification bundle handling. The step “To receive an incoming call” step 1 receives missed call notification bundle also. Same as “To receive an incoming call” step 2, pass the bundle to M800Client by invoking client.catchRemoteNotification(bundle);. However, this time you will not get any M800IncomingCall object from the method. If there is already the M800IncomingCall object created from the incoming call bundle, with the implemented M800CallDelegate added to the M800IncomingCall object, you will receive the callTerminated event from M800CallDelegate.
/** * Event: call is ended for some reasons. * @param call The call. */ void callTerminated(M800Call call, int status, Map userInfo);
The int status tells the call termination reason, that the caller has cancelled the call.
How to Configure M800ClientConfiguration The M800ClientConfiguration allows user to customize to customize the call. Here we introduce some of the parameters that are commonly configured. Set packet loss threshold.
/** * Sets the threshold while packet is lost. * After that, the call would be teminated automatically. * * @param threshold The seconds for lossing packet. */ public abstract void setPacketLossThreshold(int threshold);
The communication packets keep transporting along the conversation. If there is no packet arrived to the device for the defined packet loss threshold, the M800 call engine will determine this call as disconnected. The communication packets keep transporting along the conversation. If there is no packet arrived to the device for the defined packet loss threshold, the M800 call engine will determine this call as disconnected. Reconnection configurations. Set support reconnection
/** * * @param support {@value true} means the M800 call engine will attempt to restart a call if it is disconnected. */ public abstract void setSupportCallReconnection(boolean support);
Set this value to be true so that the M800 call engine will attempt to restart a call if it is disconnected. Set reconnection packet loss threshold
/** * To set the delay to start call reconnection after network resume. *
* i.e. The total threshold in {@link M800ClientConfiguration#getPacketLossThreshold()} should be longer than ((1 + {@link M800ClientConfiguration#callReconnectionMaxRetries()})* ({@link M800ClientConfiguration#callReconnectionPacketLossThresholdInMs()} + {@link M800ClientConfiguration#callReconnectionTimeoutInSec()})) * @param milliseconds The delay in milliseconds to start call reconnection after network resume. * */ public abstract void setCallReconnectionPacketLossThresholdInMs(int milliseconds);
To set the time delay starting call reconnection after network resumes. Set reconnection maximum retries
/** * To set the maximum number of reconnection retries. *
* i.e. The total maximum number of reconnection attempts = 1 + {@link M800ClientConfiguration#callReconnectionMaxRetries()} * @param retries */ public abstract void setCallReconnectionMaxRetries(int retries);
To set the timeout in second for each reconnection attempt. Set hold tone
/** * Set the hold tone to be played to the remote party if you hold the call. * @param holdToneFilePath the file path of hold tone. */ public abstract void setHoldTone(String holdToneFilePath);
The hold tone is played to the remote party when you hold the call. Set ring back tone
/** * Set the ring back tone to be played locally when the user is dialing out a call. * @param ringbackTonePath the file path of ring back tone. */ public abstract void setRingbackTone(String ringbackTonePath);
The ring back tone will be played locally when the user is dialing out a call. You have to enable this feature also by
/** * Set the flag to enable playing ring back tone locally. * @param support */ public abstract void setSupportPlayRingbackToneInEngine(boolean support);
Steps to provide a comprehensive call experience Support the mute and speaker feature In addition of the basic features provided by M800Call, you can enhance the call by M800Audio. M800Audio provides the feature such as mute/unmute, switching the audio channel to speaker, etc. The CallScreenActivity.java from demo project shows the example to mute the audio channel during a call:
M800Audio am = M800SDK.getInstance().getRealtimeClient().getAudioManager(); if (am.isMute()){ am.unmute(); this.buttonMute.setText("Mute"); } else { am.mute(); this.buttonMute.setText("Unmute"); }
Play a sound locally to notify user the call is connected Place the connected.mp3 file in the res/raw directory of your project. You may copy this audio file from the demo project at the same directory res/raw. Or, you may also provide your own audio file, but please be reminded that the file should be named as connected.mp3. When the call event M800CallDelegate.callBeginTalking() of the call is trigged, you may play the sound by invoking M800Audio.playDiscon nect(). The CallScreenActivity.java from demo project shows the example:
@Override public void callBeginTalking(M800Call call) { //Your own implemetation M800Audio am = M800SDK.getInstance().getRealtimeClient().getAudioManager(); if (am != null) { am.playDisconnect(); } }
Play a sound locally to notify user he/she has sent a DTMF (dual tone multi frequency) tone over the call Place the dtmf_1024.mp3 file in the res/raw directory of your project. You may copy this audio file from the demo project at the same directory res/raw. Or, you may also provide your own audio file, but please be reminded that the file should be named as dtmf_1024.mp3. The CallScreenActivity.java from demo project demonstrates how to send a DTMF tone over the call.
private void pressDTMF(String key) { mCall.sendDTMF(key); //Your own implemetation }
When the method of call M800Call.sendDTMF(String key) is invoked, with the presence of the dtmf_1024.mp3 file in the res/raw directory, the DTMF tone would be played automatically.
Dim screen when user’s face is close to the screen. It is a common behavior of the mobile devices that the screen dims when user’s face is close to the device during a call conversation. This implementation is to prevent from any unexpected touch events. To apply this logic, Proximity Sensor is used. Check http://developer.android.com/guide/topics/sensors/sensors_position.html#sensors-po s-prox The proximity sensor is usually used to determine how far away a person's head is from the face of a handset device (for example, when a user is making or receiving a call). Most proximity sensors return the absolute distance, in cm, but some return only near and far values. The following code shows you how to use the proximity sensor:
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager mSensorManager; private Sensor mProximity; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // Get an instance of the sensor service, and use that to get an instance of // a particular sensor. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mProximity = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { float distance = event.values[0]; // Do something with this sensor data. } @Override protected void onResume() { // Register a listener for the sensor. super.onResume(); mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { // Be sure to unregister the sensor when the activity pauses. super.onPause(); mSensorManager.unregisterListener(this); } }
When you receive the event, you should apply your own logic to dim the screen. For example, simply display a black screen on top of the current Activity as to hide the buttons in UI. Below is the example how to handle the sensor event:
@Override public final void onSensorChanged(SensorEvent event) { float distance = event.values[0]; // Do something with this sensor data. if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) { // values[0]: Proximity sensor distance measured in centimeters if (distance > 0) { Log.d(DEBUG_TAG, " Restoring screen brightness"); } else { Log.d(DEBUG_TAG, " Dimming screen"); } } }
Work closely with network status. The VOIP call relies on network. You should check the network status before making any outgoing call by the M800 call engine. If no network is subscripted, you should show to the user a correct notification about the reason why call cannot be established. The following snippet shows how to use the ConnectivityManager to query the active network and determine if it has Internet connectivity. (Ref. http://developer.android.com/training/monitoring-device-state/connectivity-monitoring.html )
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
Work closely with native phone status. The VOIP calls should never interrupt PSTN call. The application should always regard to the instant native phone status when making an outgoing VOIP call or receiving an incoming VOIP call. To work with the phone status, add the following permission in AndroidManufest.xml.
The following snippet shows how to get the phone status.
private TelephonyManager telephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); int callState = telephonyManager.getCallState();
If the call state equals to TelephonyManager.CALL_STATE_IDLE, it means that the phone is idle of call. The application can establish a VOIP call at that moment. Otherwise, if the phone is not idle of call while the application receives an incoming call notification bundle, the application should reject the call by providing the bundle to the M800Client instance: M800Client.rejectCallSinceBusyWithRemoteNotification(Bundle bundle). See the class GcmIntentService.java of demo project for full implementation. User attempts to make an outgoing VOIP call, the application should not create any M800Call object; instead, return user the response with
call failure reason. The application should also listen for the native phone status changes when it is undergoing a VOIP call. The following snippet shows how to listen for the phone status changes.
public class NativePhoneManager extends PhoneStateListener{ private TelephonyManager telephonyManager; public NativePhoneManager(Context context) { if(context != null) { telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); telephonyManager.listen(this, PhoneStateListener.LISTEN_CALL_STATE | PhoneStateListener.LISTEN_DATA_ACTIVITY); } }
/** * Hang-up or hold VOIP call when incoming GSM call immediately */ @Override public void onCallStateChanged(int state, String incomingNumber) { //Your implementation when the call state changes. } }
When a PSTN call interrupts the VOIP call, the application may decide to terminate the VOIP call or just hold the call. Consider also when the PSTN call terminates, should the application resume the call screen and un-hold the call for user.
Responsive UI to the in-call events Since there is the API to add the M800CallDelegate listener to a M800Call object, the application is able to display responsive UI during a call conversation. Developer may get the instant call state by either invoking M800Call.callState() or from the events of M800CallDelegate. Such as M800CallDelegate.callReconnecting(M800Call call, int attempts, boolean isPeerReconnecting), M800CallDelegate.callBeginTalking(M800Call call), M800CallDelegate .callTerminated(M800Call call, final int status, Map userInfo), etc. Developers should decide their own action for each events, for example, Show an “Answer Call” button when it is an incoming call waiting the user to answer. Remove the “Answer Call” button when an incoming call has been answered. Display the time elapsed for the call conversation. Display the “Hold” button with correct status. For example, when you receive the M800CallDelegate.callHoldByRemote(M800Call call) event , you should disable the “Hold” button since only one party can hold the call at the same time. Check also the events M800CallDelegate.callHoldByLocal(M800Call call), M800CallDelegate.callUnholdByRemote(M800Call call), M800CallDelegate.callUnholdByLocal(M800Call call), etc. Display the connection health status of call by handling M800CallDelegate.networkQualityReport(M800Call call, long qualityLevel) . Last but not least, remove the call screen when a call is terminated. CallScreenActivity.java demonstrates some of the event handling cases.
Incoming call notifications. Apply your own logic to notify the user there is an incoming call to the device. Possible methodologies: Ringer
Vibration System notification Incoming call screen when device is locked Etc.
Missed call notifications. Apply your own logic to notify the user there was a missed call to the device. Possible methodologies: System notification Call history Etc.
Call history management. There is sufficient information that allows the application to develop its own call history. Developer may make use of the following data to store the call history information. Such as, incoming call notification bundles, the missed call notification bundles, the call started talking events from M800Call objects, Call terminated events from M800Call objects, etc. With the data stored, the application may also apply their own business logic to display the call history. Support audio input/output from blue tooth device. The M800 call engine supports calls over a blue tooth device. To enable this feature, please add the permission in AndroidManufest.xml.
Use Third Party Push Service After your APP established M800 connection using M800SDK, it can receive several kinds of push messages including IM messages, system push messages and call push messages. If the app is killed either by user or system, the M800 connection will also be terminated and the user will not be able to receive any push. There are two ways to prevent this from happening: 1. Keep your app process always alive in background. If your app process is always alive, it can then keep the M800 connection always alive. However, we don’t suggest you to do so because, first, keeping a long live process is very troublesome and will consume extra device battery and memory; second, keeping a long live M800 connection is wasting both server and client resources. 2. Use a third party push service. There are some third party push services available in the market that can help M800 server send messages to your APP without establishing M800 connection. Currently, we support Google Cloud Messaging (GCM) and JPush. It is recommended that you choose one or both of the services to receive push messages when your app goes to background. To integrate a third party push service into your app, please visit Google Cloud Messaging (GCM) https://developers.google.com/cloud-messaging/ JPush https://www.jpush.cn/common After creating an account in the push service website, you need to provide your server API key to M800 server and put the APP API key inside your APP. A unique Registration ID will be created for your APP on each device. You need to upload the Registration ID to M800 server after sign up. GCM example:
String regID = GoogleCloudMessaging.getInstance(context).register(“”); M800SDK.getInstance().getManagement().updatePushToken(regId, IM800Management.PushType.GCM, new M800ManagementCallback() { @Override public void complete(boolean isSuccess, M800Error error, Bundle userInfo) { if (isSuccess) { // Successfully uploaded } else { // Failed } } });
JPush example:
String regID = JPushInterface.getRegistrationID(context); M800SDK.getInstance().getManagement().updatePushToken(regID, IM800Management.PushType.JPUSH, new IM800Management.M800ManagementCallback() { @Override public void complete(boolean isSuccess, M800Error error, Bundle userInfo) { if (isSuccess) { // Successfully uploaded } else { // Failed } } });
After uploading the Registration ID to M800 server, your APP should be able to receive push via GCMBroadcastReceiver or JPushBroadcastReceiver you implemented. When receives any M800 push messages, you need to first start M800 connection. After that, you need to pass the push message to M800 Realtime Client to see if it is an incoming call push or missed call push. Please refer to com.m800.service.GCMIntentService for example.
IM Module Introduction The IM module in the m800SDK provides functionality to run single and multiple-user chat rooms in your app. There are two core features: 1-to-1 Chat. The single user chat (SUC) function allows a single user to send a message to another single user. The sent message can include text, image, audio, location etc. Group Chat. The multi-user chat (MUC) features allows a single user to send a message to a group of users. The sent message can include text, image, audio, location, etc (same as 1-to-1 chat). To enable IM features, you need a list of M800 contact. The contact list provides a set of JID with which you can to create a chat room. After the chat room is created by one JID for SUC or multi JID for MUC, a message can be sent to the chat room. A chat room view controller should be built and listening to the message changes from the SDK. Note: this guide does not describe in detail how to build a chat room UI.
Pre-requisites Successfully completed contact sync
How to Implement Single User Chat Room(SUC) As a start point... Please get an instance of IM800SingleUserChatRoomManager from M800SDK.
IM800SingleUserChatRoomManager sucManager = M800SDK.getInstance().getSingleUserChatRoomManager();
Single User Chat Room(SUC) Creation Please invoke createChatRoom(…) to start SUC Creation.
/** * Create single user chat room. * If the chat room is already existed, it will return this chat room. * * @param jid The jid of member * @param callback The {@link CreateSingleUserChatRoomCallback} whose {@link CreateSingleUserChatRoomCallback#complete(String, String)} method will be called if the request is success, otherwise {@link CreateSingleUserChatRoomCallback#error(String, M800ChatRoomError, String)} method will be called. */ void createChatRoom(String jid, CreateSingleUserChatRoomCallback callback); /** * Callback for use with {@link IM800SingleUserChatRoomManager#createChatRoom(String, CreateSingleUserChatRoomCallback)} to get the create/retrieve chat room result. * * If roomId is null, it will return {@link M800ChatRoomError#INVALID_PARAMETER} from provided callback. * */ interface CreateSingleUserChatRoomCallback { /** * Called on the main thread of the process to report that the chat room is created/retrieved. * * @param roomId multi chat room ID * @param jid The jid of member */ void complete(String roomId, String jid); /** * Called chat room. * * @param * @param * @param */
on the main thread of the process to report that fail to create single
jid The jid of member error simplified error result message detail error result
void error(String jid, M800ChatRoomError error, String message); }
Take the demo project as an example; please refer to the class ChatRoomApiDemoCreateSUCActivity.java.
sucManager.createChatRoom( selectedJid, new IM800SingleUserChatRoomManager.CreateSingleUserChatRoomCallback() { @Override public void complete(String roomId, String jid) { //If success, a related roomId will be return here. } @Override public void error(String jid, M800ChatRoomError error, String message) { //If failure, please read the error message to find the reason. } } );
To create SUC, it just creates a related data in local database; it doesn’t need to send request to server. That mean, SDK will not validate the provided JID (Definition of Jabber Identifier). As long as, the provided JID is not empty, it must be return success result. If it returns failure result, please check if the provided JID is not empty. (Please note that, if the JID is not existed, related chat room impossible to receive any message from server.) If the SUC is already created for given JID, it will return the existing chat room ID.
Monitor Single User Chat Room(SUC) Activity SDK has provided two modes to monitor SUC Activity; one is monitoring all SUC Activity.
/** * Register a listener that listeners events of all single user chat rooms. * * @param listener a listener implements {@link IM800SingleUserChatRoomListener} * @throws NullPointerException if listener is null */ void addChatRoomListener(IM800SingleUserChatRoomListener listener);
Another one is monitoring specified SUC Activity.
/** * Register a listener that listeners events of a single user chat room. * * @param roomID single user chat room ID * @param listener a listener implements {@link IM800SingleUserChatRoomListener} * @throws NullPointerException if listener is null * @throws IllegalStateException if roomID is null or empty */ void addChatRoomListener(String roomID, IM800SingleUserChatRoomListener listener);
Both of them are using the same listener.
/** * Callback for use with {@link IM800SingleUserChatRoomManager#addChatRoomListener(IM800SingleUserChatRoomListener)} to monitor the activity of all single chat room. * Callback for use with {@link IM800SingleUserChatRoomManager#addChatRoomListener(String, IM800SingleUserChatRoomListener)} to monitor the activity of specified single chat room. */ public interface IM800SingleUserChatRoomListener { /** * Called on the main thread of the process to report that a new single chat room has been created. * * @param roomId single user chat room ID */ void onChatRoomCreated(String roomId); /** * Called on the main thread of the process to report that an existing single chat room has been removed from local database. * * @param roomId single user chat room ID */ void onChatRoomRemoved(String roomId); /** * Called on the main thread of the process to report that chat activity occurs. * * @param roomId single user chat room ID * @param lastUpdateTime last chat time */ void onLastUpdateTimeChanged(String roomId, Date lastUpdateTime); }
Take the demo project as an example. Please refer to the class ChatRoomListFragment.java.
IM800SingleUserChatRoomListener mySUCListener = new IM800SingleUserChatRoomListener() { @Override public void onChatRoomCreated(String roomId) { //Invoked when any new SUC created in local database. } @Override public void onChatRoomRemoved(String roomId) { //Invoked when any new SUC removed in local database. } @Override public void onLastUpdateTimeChanged(String roomId, Date lastUpdateTime) { //Invoked when any SUC has chat activity. } }; sucManager.addChatRoomListener(mySUCListener);
We recommend that you keep the reference object of the listener, since developer needs it to stop related monitoring. To stop monitoring SUC Activity, please invoke removeChatRoomListener(…) to stop monitor SUC activity.
/** * Unregister a single user chat room listener. * * @param listener a listener previously registered * @throws NullPointerException if listener is null */ void removeChatRoomListener(IM800SingleUserChatRoomListener listener);
We recommend that, if developers no longer need to monitor SUC Activity, please do not forget to invoke removeChatRoomListener(…) t o stop monitoring:
sucManager.removeChatRoomListener(mySUCListener);
To stop all SUC Activity monitoring, invoke clearChatRoomListeners():
/** * Unregister all single user chat room listeners. */ void clearChatRoomListeners();
Like so:
sucManager.clearChatRoomListeners();
Retrieve Single User Chat Room(SUC) To retrieve all SUC, please invoke getChatRooms(…).
/** * Get all single user chat rooms. * * @return list of single user chat rooms */ @NonNull List getChatRooms();
Take the demo project as an example. Please refer to the class ChatRoomListFragment.java.
List chatRooms = sucManager.getChatRooms();
The above method will query from local database with the sequence descending order of last chat time, and return full list of SUC model objects.
To retrieve specified SUC model objects, SDK has provided two ways for this query. One is to retrieve SUC model object by JID:
/** * Obtain specific single user chat room. * * @param jid The jid of member * @return single user chat room if found, null otherwise. */ IM800SingleUserChatRoom getChatRoomByJID(String jid);
Another way to retrieve SUC model object, by roomID:
/** * Obtain specific single user chat room. * * @param roomId single chat room ID * @return single user chat room if found, null otherwise. */ IM800SingleUserChatRoom getChatRoomById(String roomId);
Since the above retrieval methods are related to database query action, we recommend that, developer should invoke these methods in a background thread, thus avoid blocking the main thread.
Single User Chat Room(SUC) Deletion
To remove the SUC related data from local database, please invoke deleteChatRoom(…) to start SUC Deletion.
/** * Delete the chat room and all related data in local database. * * @param roomId single chat room ID * @return true if this chat room was deleted, false otherwise. */ boolean deleteChatRoom(String roomId);
This method will return true if the related SUC was found and deleted, return false otherwise. Take the demo project as an example; please refer to the class ChatRoomListFragment.java.
sucManager.deleteChatRoom(roomId);
Since the above deletion method related to database delete action, we recommend that, developer should invoke this methods in background thread, thus avoid block the main thread process.
Retrieve Participants In Single User Chat Room(SUC) To retrieve participants in specified SUC, please invoke getParticipants(…).
/** * Get participants in a single user chat room. * * @param roomId single chat room ID * @return participant list including current user and the other participant */ @NonNull List getParticipants(String roomId);
The above method will query from local database, and return full list of SUC Participant model objects. Since the above retrieval methods are related to database query action, we recommend that, developer should invoke this method on a background thread, thus avoid blocking the main thread process.
Multi User Chat Room(MUC) As a starting point... Please get an instance of IM800MultiUserChatRoomManager from M800SDK:
IM800MultiUserChatRoomManager mucManager = M800SDK.getInstance().getMultiUserChatRoomManager();
Multi User Chat Room(MUC) Creation Please invoke createChatRoom(…) to start MUC Creation.
/** * Create multi user chat room * Title cannot be empty * Please at least invite two members * * @param title The title of chat room * @param jids JID the unique identifier of an M800 user, the members will be invite. * @param callback an asynchronous callback of create chat room result, * {@link CreateMultiUserChatRoomCallback#complete(String, String, String[])} method will be called if the request is success, * otherwise {@link CreateMultiUserChatRoomCallback#error(String, String[], M800ChatRoomError, String)} method will be called. */ void createChatRoom(String title, String[] jids, CreateMultiUserChatRoomCallback callback);
interface CreateMultiUserChatRoomCallback { /** * Called when create-chat-room request is accepted by server. * *
Please note when this callback is invoked, the group chat room is not created in client SDK yet. * To monitor chat room creation event, register a listener to listen {@link IM800MultiUserChatRoomListener#onChatRoomCreated(String)}.
*This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param title The title of chat room * @param jids JID the unique identifier of an M800 user, the members will be invite. */ void complete(String roomId, String title, String[] jids); /** * Called when create chat room is finished with error. * *This callback is called on application's main thread.
* * @param title The title of chat room * @param jids JID the unique identifier of an M800 user, the members will be invite. * @param error simplified error result * @param message detail error result */ void error(String title, String[] jids, M800ChatRoomError error, String message) }* If synchronization task is executed once, and force is not set to true, no synchronization task will be executed. * Only one synchronization task will be executed at one time, no duplicate request allowed. *
* * @param force force update */ void syncData(boolean force);This callback is called on application's main thread.
* * @param roomId multi chat room ID */ void complete(String roomId);This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param error simplified error result * @param message detail error result */ void error(String roomId, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jids JID the unique identifier of an M800 user */ void complete(String roomId, String[] jids);This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jids JID the unique identifier of an M800 user * @param error simplified error result * @param message detail error result */ void error(String roomId, String[] jids, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jid JID the unique identifier of an M800 user */ void complete(String roomId, String jid); /** * Called when kick member is finished with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jid JID the unique identifier of an M800 user * @param error simplified error result * @param message detail error result */ void error(String roomId, String jid, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jid JID the unique identifier of an M800 user */ void complete(String roomId, String jid);This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jid JID the unique identifier of an M800 user * @param error simplified error result * @param message detail error result */ void error(String roomId, String jid, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jid JID the unique identifier of an M800 user */ void complete(String roomId, String jid); /** * Called when demote administrator with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param jid JID the unique identifier of an M800 user * @param error simplified error result * @param message detail error result */ void error(String roomId, String jid, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID */ void complete(String roomId); /** * Called when leave room is finished with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param error simplified error result * @param message detail error result */ void error(String roomId, M800ChatRoomError error, String message) }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param isMuted True if mute mode is enabled, false otherwise */ void complete(String roomId, boolean isMuted); /** * Called when enable/disable mute mode with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param error simplified error result * @param message detail error result */ void error(String roomId, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param isEnabled True if smart notification is enabled, false otherwise */ void complete(String roomId, boolean isEnabled); /** * Called when enable/disable smart notification with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param error simplified error result * @param message detail error result */ void error(String roomId, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param title The title of chat room */ void complete(String roomId, String title); /** * Called when update chat room name request is sent with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param title The title of chat room * @param error simplified error result * @param message detail error result */ void error(String roomId, String title, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID */ void complete(String roomId); /** * Called when update chat room icon request is sent with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param error simplified error result * @param message detail error result */ void error(String roomId, M800ChatRoomError error, String message); }This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param themeId The theme Id of chat room, which is defined by client side. Just a string value to let client side setup corresponding theme for chat room. */ void complete(String roomId, String themeId); /** * Called when update the theme id request is sent with error. * *This callback is called on application's main thread.
* * @param roomId multi chat room ID * @param themeId The theme Id of chat room, which is defined by client side. Just a string value to let client side setup corresponding theme for chat room. * @param error simplified error result * @param message detail error result */ void error(String roomId, String themeId, M800ChatRoomError error, String message);This callback is called on application's main thread.
* * @param success list of multi user chat room ID, which is rebuild icon cache file successfully * @param failure list of multi user chat room ID, which is rebuild icon cache file failure, that should be decode image data failure. */ void onResult(String[] success, String[] failure) }When an ephemeral message's TTL is set to 0, * you should also call {@link #removeEphemeralMessageImage(String)} to clear its image data.
* * @param messageID ephemeral chat message ID * @param TTL time to live, should be greater than or equal to 0 * @return true if set TTL successfully, otherwise false * @throws IllegalArgumentException if messageID is null or empty */ boolean setEphemeralMessageTTL(String messageID, @Nonnegative int TTL);Next time when {@link #getEphemeralImageBitmapArray(String)} is called, it will return null.
* * @param messageID ephemeral chat message ID * @return true if remove ephemeral image successfully, otherwise false * @throws IllegalArgumentException if messageID is null or empty */ boolean removeEphemeralMessageImage(String messageID);If chat messages are marked as read correctly * and {@link #sendDisplayedReceipt(String)} is never been called, * will send displayed receipts for all chat rooms if needed.
*/ void resendDisplayedReceipts();Chat state message tells other chat participants whether user is typing or not. * Don't send {@link ChatState#Composing} state too frequently if user keeps typing, * recommended interval is 2 seconds.
* * @param roomID chat room ID, if no room is found with this ID, nothing will be sent * @param state the {@link ChatState} chat state * @return error with code {@link M800ChatRoomError#NO_ERROR} if message is sent, * otherwise see {@link M800ChatRoomError} * @throws IllegalArgumentException */ M800ChatRoomError sendChatState(String roomID, ChatState state);This callback is called on application's main thread.
* * @param phoneNumber phoneNumber the phone number used during search * @param userProfile the search result, if result not found, that should be null * @param isContact indicates whether the related user is friend or not */ void complete(String phoneNumber, IM800UserProfile userProfile, boolean isContact); /** * Called when M800 user search is finished with error. * *This callback is called on application's main thread.
* * @param phoneNumber the phone number used during search * @param error simplified error result * @param message detail error result */ void error(String phoneNumber, M800PacketError error, String message); }This callback is called on application's main thread.
* * @param JID the unique identifier of an M800 user * @param userProfile the search result, if result not found, this should be null * @param isContact indicates whether the related user is friend or not */ void complete(String JID, IM800UserProfile userProfile, boolean isContact); /** * Called when M800 user search is finished with error. * *This callback is called on application's main thread.
* * @param JID the unique identifier of an M800 user * @param error simplified error result * @param message detail error result */ void error(String JID, M800PacketError error, String message); }Note: M800SDK will cache M800 user's profile locally, * but it will not update the profile data unless the M800 user is current user's M800 contact and M800 roster is started * (M800 roster will push contacts' change to user), so the user profile you get from this method is not guaranteed to contain the latest data. * This means, the user name, email...etc may not be the most updated.
*If you want to get the most updated user profile, please use {@link #findM800UserByJIDFromServer(String, FindM800UserByJIDCallback)}
* * @param JID the unique identifier of an M800 user */ IM800UserProfile findM800UserByJIDFromLocal(String JID);Next time when {@link IM800FindUserManager#findM800UsersByRecommendation(FindM800UsersCallback, boolean)} * is called, this user will not appear in the list.
* * @param JID the unique identifier of an M800 user * @param callback an asynchronous callback of remove user from recommendation list result, {@link RemoveRecommendationCallback#success(String)} * method will be called if the request is success, otherwise {@link RemoveRecommendationCallback#error(String, M800PacketError, String)} * method will be called. */ void removeM800UserFromRecommendation(String JID, RemoveRecommendationCallback callback);After update, it will update the related user preference to server automatically. Client side also can use this value to setup corresponding UI.
* * @param language which is supported by M800 SDK */ void setLanguage(IM800Management.M800Language language); * This callback is invoked on {@link android.app.Application}'s main thread. * * @param language The updated language. */ void onLanguageUpdated(IM800Management.M800Language language);
/** * This method is invoked when user preference[Recommendation] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param enabled provides the latest preference setting. */ void onRecommendationEnabled(boolean enabled); /** * This method is invoked when user preference[FindUsersByPinPhone] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param enabled provides the latest preference setting. */ void onFindUsersByPinPhoneEnabled(boolean enabled); /** * This method is invoked when user preference[FindUsersByLocation] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param enabled provides the latest preference setting. */ void onFindUsersByLocationEnabled(boolean enabled); /** * This method is invoked when user preference[ShowMyCallerId] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param isShowing provides the latest preference setting. */ void onShowingMyCallerId(boolean isShowing); /** * This method is invoked when user preference[ShowOthersCallerId] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param isShowing provides the latest preference setting. */ void onShowingOthersCallerId(boolean isShowing);
/** * This method is invoked when user preference[ShareMyPresence] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param isSharing provides the latest preference setting. */ void onSharingMyPresence(boolean isSharing); /** * This method is invoked when user preference[SendDisplayedReceipt] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param enabled provides the latest preference setting. */ void onDisplayedReceiptEnabled(boolean enabled); /** * This method is invoked when user preference[ReceiveMessageNotification] is updated. *
* This callback is invoked on {@link android.app.Application}'s main thread. * * @param enabled provides the latest preference setting. */ void onMessageNotificationEnabled(boolean enabled); /** * Called when sync status changed. * *
This callback is called on application's main thread.
* * @param isSyncing Indicates whether user preference is synced with server. */* If synchronization task is executed once, and force is not set to true, no synchronization task will be executed. * Only one synchronization task will be executed at one time, no duplicate request allowed. *
* * @param force force update */ void syncData(boolean force);