Android Mobile SDK

The NICE inContact Android Mobile SDK allows you to easily add chat and callback widgets into your Android application. Additionally, it allows you to quickly retrieve key queue statistics and show it within your mobile application. These features can be added without much coding and without needing to be an expert on the NICE inContact APIs. Once added, they can be customized to meet any additional requirements you may have.

This article takes you through the steps of creating a simple Android application and adding the widgets supported by the NICE inContact Mobile SDK. You will need to download the Android SDK and Eclipse IDE and configure it before you start the steps in the sections that follow.

To add the NICE inContact mobile widgets to your Android application, you will need to do the following:

  1. Download the Mobile Android Kit which contains the androidKit.zip file.
  2. Unzip the code in any location. We recommend adding it to the same directory as the project you want to add the widgets to.
  3. Open the Eclipse IDE as administrator.
  4. Import both the inContactMobileSDK and inContactMobileUISDK projects from the location you just unzipped into by right-clicking on the project explorer and clicking on the Import option.

  5. Select the "Existing Android Code into Workspace" option.

  6. Click on the "Next" button.
  7. Click the "Browse" button, and browse to the location where you unzipped the SDK.
  8. Select the "SDK" folder, and Eclipse will find the two SDK projects (inContactMobileSDK and inContactMobileUISDK) and list them for you:

  9. Ensure both SDK projects are selected, and click the "Finish" button. With this, the SDK will be imported and you will be ready to add the widgets to your Android application.

The Chat Widget can be used to allow your patrons to chat with your agents using your mobile application. The widget will take user input and send it to the NICE inContact system. It automatically handles the events that the NICE inContact platform sends back, and displays the data returned in the chat window.

The inContactMobileSdkUI project you just imported has all the resources needed to quickly add the chat widget to your application. To add the chat widget, you will need to do the following:

  1. Create an empty Android project in the same workspace you imported the inContactMobileSdkUI and name the project "TestProject".

  2. Copy and paste the contents of the assets folder from the inContactMobileUISDK project into the assets folder of the TestProject project. This includes the "fonts" folder and the "timezones.csv" file. You can copy and paste the files from within Eclipse:

  3. You will now need to import the inContactMobileSdkUI project to your TestProject as a library. To do that right-click on the project and click on "Properties".
  4. Open the "Android" tab and locate the "Library" section.

  5. Click on the "Add" button.
  6. Select inContactMobileSdkUI and press the "OK" button. You only need to add the inContactMobileUISDK project, not the inContactMobileSDK project.

  7. You will see the project added to the library list.

  8. Now go to the Java Build Path option and locate it in the "Libraries" tab.

  9. Click the "Add JARs…" button and select the "incontactmobilesdkui.jar" file and press the "OK" button.

  10. Now select the "Order and Export" tab, and select the "Android Dependencies" and the "incontactmobileuisdk.jar" items (along with any other dependencies your project has).

  11. Press the "OK" button to save all changes.
  12. Now create a button and assign it an onClick event.
  13. Open the AndroidManifest.xml, and as with all Android applications, copy these permissions in the corresponding section.

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
  14. Copy this code to the section where you define all the activities in the AndroidManifest.xml file:

    <activity android:name="com.incontact.sdk.ui.screen.ChatActivity"
        android:theme="@style/Theme.Transparent"
        android:launchMode="singleTop"
        android:screenOrientation="portrait">
    </activity>
    <service android:name="com.incontact.sdk.chat.ChatService"></service>
    
  15. Open the Activity that inflates the layout and contains the button, add the following code in the "onCreate" method to set the require configurations. You will need to provide the Application ID of the API Application that you have registered with NICE inContact. For information on how to register your application in the NICE inContact Central website, please refer to the API Developers Guide. If you are using the OAuth 2.0 Client flow, your code should like something like this:

    ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
    JHttpUtil.initialize(connectivityManager);
    HttpConnectionConfiguration httpConnectionConfiguration = new HttpConnectionConfiguration();
    httpConnectionConfiguration.setServerUrl("https://api.incontact.com");
    httpConnectionConfiguration.setClientId("AppName@VendorName");
    httpConnectionConfiguration.setClientSecretKey("your_app_id");
    httpConnectionConfiguration.setPointOfContact("chat-point-of-contact-guid");
    HttpConnectionManager.getInstance().setConfiguration(httpConnectionConfiguration);
    
  16. Finally, in the action method of the created button, call the ChatActivity.class Activity and start it.

    Intent intent = new Intent(this, ChatActivity.class);
    startActivity(intent);
    
  17. Launch the application and press the "Chat with Agent" button, and the chat widget will be shown.

The Callback Widget can be used to allow your users to queue a callback request with the NICE inContact platform. The widget allows the user to register an immediate callback or a callback in the future (Promise Keeper).

To add the Callback widget into your Android app, you will need to do the following:

  1. You will first need to do steps 1-12 and 14-16 of the steps listed in the section above, if you haven’t done so already.
  2. Open the AndroidManifest.xml file, and add the following lines of code in the application section.

    <activity 
        android:name="com.incontact.sdk.ui.screen.ScheduleActivity"
        android:screenorientation="portrait">
    </activity>           
    
  3. Create another button to launch the widget in the onClick action.
  4. Finally in the action method of the created button call the ScheduleActivity.class Activity and start it with the following code.

    Intent intent = new Intent( this, ScheduleActivity.class);
    startActivity(intent);
    
  5. Launch the activity and try the application. On clicking the "Request Callback" button, the NICE inContact Callback widget will be shown. Your patrons can now enter phone number they would like to be reached at, as well as a preferred time (optional) and then click on the "Submit" button to send the callback request to the NICE inContact platform as shown below:

If you would like to use the NICE inContact services in your application, but would prefer to use your own user interface, this section will guide you on how to do that.

NOTE: If you don’t want to use the NICE inContact UI, you will not need to import the inContactMobileSdkUI project as described in the sections previous. You will only one library that is located in the "libs" directory called "incontactmobilesdk.jar". This library contains all the classes used by the NICE inContact widget and can be integrated with your user interface.

Customizing the Chat Widget Interface

After you have the incontactmobilesdk.jar file in the libs directory of your project you just need an appropriate interface to show the messages of the chat.

For purposes of this example, we will just create one activity that has a TextView to show the messages, an EditText box to write the messages, and a "Send" button.

Since the chat is a group of procedures that must be running all the time, it has been created as an Android service, which must be started and stopped when it is necessary.

To establish a connection with the chat service we must follow the normal steps to start a service from an activity.

  1. Create an instance of the ServiceConnection class which will help us listen to the connection and disconnection events of the service.

    private ServiceConnection connection = new ServiceConnection(){
        @Override
        public void onServiceDisconnected(ComponentName name){
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service){
        }
    }
    
  2. We need to add a ConnectivityManager to the HttpConnectionManager to test if there is internet connection before trying to connect to the server. Also, we need to add the HttpConnectionConfiguration to the HttpConnectionManager if we haven’t done it yet in another Activity.

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_chat_screen);
        ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        JHttpUtil.initialize(connectivityManager);
        HttpConnectionConfiguration httpConnectionConfiguration = new HttpConnectionConfiguration();
        httpConnectionConfiguration.setUser("YOUR USER");
        httpConnectionConfiguration.setPassword("YOUR PASSWORD");
        httpConnectionConfiguration.setClientId("YOUR Application ID");
        httpConnectionConfiguration.setClientSecretKey("YOUR AppName@VendorName");
        httpConnectionConfiguration.setServerUrl("https://login.incontact.com");
        HttpConnectionManager.getInstance().
        setConfiguration(httpConnectionConfiguration);
        chatEditor = (EditText)findViewById(R.id.custom_chat_editor);
        chatPanel = (TextView)findViewById(R.id.custom_chat_panel);
        startChatService();
    }
    
  3. Then add a private method that will do all the needed steps to call the chat service.

    private void startChatService() {
        Intent intent = new Intent(this, ChatService.class);
        startService(intent);
        bindService(intent, connection, BIND_AUTO_CREATE);
    }
    

    This will start the chat service which will be running in background. As you can see, we are starting the chat twice using two different strategies to start the service. The first strategy will just start the service and run it in background, and the second will guarantee that the service will be alive until no Activity is bounded to the service. This is because it is important to keep the service alive even though the chat Activity is in background or destroyed.

  4. We must create a listener that will hear all events in the chat service.

    private ChatSessionListener listener = new ChatSessionListener() {
        @Override
        public void agentAssigned(ChatSession chatSession) {
        }
        @Override
        public void authenticatedWithCredentials(Authorization authorization) {
        }
        @Override
        public void authenticatedWithoutCredentials(Authorization authorization) {
        }
        @Override
        public void chatEnded() {
        }
        @Override
        public void chatStarted(ChatSession chatSession) {
        }
        @Override
        public void connectionTimedOut() {
        }
        @Override
        public void internetConnectionNotFound() {
        }
        @Override
        public void messageReceived(String sender, String message) {
        }
        @Override
        public void messageSent() {
        }
        @Override
        public void receiveError(Exception exception, int code) {
        }
    };
    

    All of the listener methods available are listed below:

    • agentAssigned: This method gets called when the platform raises an event indicating an agent has been assigned to the chat session.
    • authenticatedWithCredentials: This event gets fired when you authenticate with username and password in the HttpConnectionManager (used in the OAuth 2.0 Password flow).
    • authenticatedWithoutCredentials: This event gets fired when you authenticate without username and password in the HttpConnectionManager (used in the OAuth 2.0 Client flow).
    • chatEnded: This method gets called when the platform raises an event indicating that the chat session has ended.
    • chatStarted: This method gets called when the platform raises an event indicating that the chat session has started.
    • connectionTimedOut: This method gets called when the response takes more than 60 seconds.
    • internetConnectionNotFound: This method gets called when no internet connection is found.
    • messageReceived: This method gets called every time the chat service receives a message. Information on the sender and the message is passed into this method.
    • messageSent: This method gets called every time a message is sent to the server.
    • receiveError: If an error occurred in the chat service or in the server, this method is called with the corresponding exception or the error code from the server.
  5. In the onServiceConnected and onServiceDisconnected methods you will need to add this code to get the server instance, and also to set and remove the created listener.

    @Override
    public void onServiceDisconnected(ComponentName name) {
        chatService.removeChatListener(listener);
    }
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        chatService = ((ChatServiceBinder)service).getServerInstance();
        chatService.addChatListener(listener);
        chatService.startChat();
    }
    
  6. Add the click event handler to the button to send messages when the "Send" button is pressed.

    public void onSendClick(View view) {
        String message = chatEditor.getText().toString();
        chatService.sendMessage("Patron", message);
        showMessage("Patron", message);
        chatEditor.setText("");
    }
    private void showMessage(String sender, String message) {
        String conversation = chatEditor.getText().toString();
        conversation+=sender + ": " + message;
        chatPanel.setText(conversation);
    }
    
  7. Finally, in the messageReceived method of the created ChatSessionListener we call the just created showMessage method to show the received message.

    @Override
    public void messageReceived(String sender, String message) {
        showMessage(sender, message);
    }
    

With this, you will be able to launch the application and test it with an agent. In the agent screen, the agent can accept the incoming chat request and send a message to the android application.

The patron can send the messages back to the agent by typing in text and tapping on the "Send" button. To end the chat, the patron can just click on the close button or you can implement a button that calls the closeChat method in the chat service.

To use the callback service in your own user interface you first need to create the layout and the activity that will handle the events and the fields needed to be filled to send the required information. A sample layout is shown below:

After having created the activity and the layout, you will need to do the following:

  1. First in the onCreate method we must add the HttpConnectionConfiguration to the HttpConnectionManager the same way we did in the previous examples. This step can be skipped if you have already set your configuration in one of the previous examples.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom_callback_screen);
        HttpConnectionConfiguration httpConnectionConfiguration = new HttpConnectionConfiguration();
        httpConnectionConfiguration.setUser("YOUR USER");
        httpConnectionConfiguration.setPassword("YOUR PASSWORD");
        httpConnectionConfiguration.setClientId("YOUR ApplicationID");
        httpConnectionConfiguration.setClientSecretKey("YOUR AppName@VendorName");
        httpConnectionConfiguration.setServerUrl("http://login.incontact.com");
        HttpConnectionManager.getInstance().setConfiguration(httpConnectionConfiguration);
        phoneField = (EditText) findViewById(R.id.callback_screen_phone);
        dateField = (EditText) findViewById(R.id.callback_screen_phone);
        timeField = (EditText) findViewById(R.id.callback_screen_phone);
        callbackManager = CallbackManager.getInstance(this);
        callbackManager.setCallBackListener(callbackListener);
    }
    
  2. Now add the CallbackListener to hear all events fired from the CallbackManager.

    private CallbackListener callbackListener = new CallbackListener() {
        @Override
        public void receiveNoInternetConnection() {
        }
        @Override
        public void receiveFailed(int code) {
        }
        @Override
        public void receiveError(Exception exception) {
        }
        @Override
        public void connectionTimeOut() {
        }
        @Override
        public void callbackSent(String contactId) {
        }
        @Override
        public void authenticated(Authorization authorization) {
        }
    };
    

    NOTE: This listener is very similar with the ChatSessionListener, the description of the methods and its usage is the same, except of the callbackSent method which is called when the callback has been successfully submitted to the server returning a contactId.

  3. Now we must create the onClick handlers of the "Call Now" and "Request Callback" buttons and call the manager.

    public void onCallNowClick(View view) {
        String phone = phoneField.getText().toString();
        callbackManager.callNow(phone);
    }
    public void onRequestCallbackClick(View view) {
        String phone = phoneField.getText().toString();
        String date = dateField.getText().toString();
        String time = timeField.getText().toString();
        callbackManager.sendCallback(phone, date, time, "");
    }
    
  4. With this, you can launch the application and try the service:

    The patron can enter their phone number and optionally the date and time of the Callback request, and click on the "Request Callback" or "Call Now" buttons.

    The agent should see the Callback request and can accept it.

Changing the Callback Manager Configuration.

The CallbackManager methods callNow and sendCallback have their own configuration options. Those can be accessed by calling the following methods:

  • getPromiseConfiguration(): It retrieves the configuration to request scheduled callbacks. The most important configuration options are the skill and time zone:
  • setSkill: This method can be used to set the skill that is going to be used in the callback request.
  • setTimeZone: This method allows you to change the time zone that the server is going to use the send a callback. We recommend that this be set to the current device time zone, which is the already done in the inContactMobileSdk PromiseActivity class. The default value is "Mountain Standard Time".
  • getImmediateCallbackConfiguration: Use this method to set any needed configuration for immediate callback requests. You can set the skill information as in the case of the PromiseConfiguration.

The inContactMobileSdk contains a class called QueueStatsManager which gives access to some key statistics about your correct queue.

To use the QueueStatsManager, as in the other examples, it is important that you update the configuration in the HttpConnectionManager to connect to the server.

NOTE: If you have already configured this in the application before, you don’t have to repeat this step.

HttpConnectionConfiguration httpConnectionConfiguration = new HttpConnectionConfiguration();
httpConnectionConfiguration.setUser("YOUR USER");
httpConnectionConfiguration.setPassword("YOUR PASSWORD");
httpConnectionConfiguration.setClientId("YOUR ApplicationID");
httpConnectionConfiguration.setClientSecretKey("YOUR AppName@VendorName");
httpConnectionConfiguration.setServerUrl("THE SERVER URL");
HttpConnectionManager.getInstance().setConfiguration(httpConnectionConfiguration);

You can save the instance of the QueueStatsManager in a local variable.

QueueStatsManager manager = new QueueStatsManager(this);    

The QueueStatsManager gets all the information from the server, which is why you will need to create the callback object from the QueueDelegate interface.

How to get the number of connected agents?

To get the number of connected agents, you can use the getAgentStateList in the QueueManager class with the start date as parameter. You will receive the response in the methods of the QueueDelegate. The requestSucceeded method sends the response of the server with the constructed object.

QueueDelegate<list<agentstate>> dalegate = new QueueDelegate<list <agentstate>>() {
    @Override
    public void requestSucceeded(List< agentstate > agentStateList) 
    {
        //This will count how many agents are not in the LOGGED_OUT state
        int availableAgents = 0;
        for (AgentState agentState : agentStateList)
        {
            if (AgentState.AVAILABLE.equals(agentState.getAgentStateName()))
            {
                availableAgents++;
            }
        }
    }
    @Override
    public void requestFailed(int method, int type, int code, String response) 
    {
    }
    @Override
    public void requestError(Exception arg0) 
    {
    }
};
String startDate ="2013-01-01";
manager.getAgentStateList(dalegate, startDate);

As you can see in the requestSucceded method, we are getting the parameter List "agentstate"" which has the same type of the created delegate. This will be similar in all of the cases; the given response will be the same type of the constructed generic delegate.

Having the response in the requestSucceeded method, we must count how many agents aren’t in the LOGGED_OUT state. This is how we establish how many agents are connected.

How to get the number of available agents?

As in the previous example, you can use the AgentState class to get this information as shown below:

QueueDelegate<list <agentstate>> dalegate = new QueueDelegate<list <agentstate>>() {
    @Override
    public void requestSucceeded(List<agentstate>agentStateList)
    {
        //This will count how many agents are not in the LOGGED_OUT state
        int availableAgents = 0;
        for(AgentState agentState : agentStateList) 
        {
            if(AgentState.AVAILABLE.equals(agentState.getAgentStateName())) 
            {
                availableAgents ++;
            }
        }
    }
    @Override
    public void requestFailed(int method, int type, int code, String response) 
    {
    }
    @Override
    public void requestError(Exception arg0) 
    {
    }
};
String startDate ="2013-01-01";
manager.getAgentStateList(dalegate, startDate);

Then, instead of counting the agents that are not LOGGED_OUT, you can count the agents that are in the AVAILABLE state to get the desired information.

How to get the number of available agents in a specific skill?

You can do something similar to what we have shown in the previous example, and add in an additional check on the skillID when doing the count. Another way of doing this is to use the SkillSummary class. This class has many other statistics that that the AgentState class doesn’t have. In order to get the desired information you will need to create the delegate, but this time the generic type will be a SkillSummary class. The method that we are going to use is the getSkillSummary method.

QueueDelegate<skillsummary> dalegate = new QueueDelegate<skillsummary> () {
    @Override
    public void requestSucceded(SkillSummary summary) {
        int availableAgents = summary.getAgentsLoggedIn() - summary.getAgentsUnavailable();
    }
    @Override
    public void requestFailed(int method, int type, int code, String response) {
    }
    @Override
    public void requestError(Exception arg0) {
    }
};
String skillId = "DESIRED_SKILL";
String startDate = "START_DATE";//yyyy-MM-dd
String endDate = "END_DATE";//yyyy-MM-dd
manager.getSkillSummary(dalegate, skillId, startDate, endDate);

Subtracting the unavailable from the logged in agents we can have the available agents without using a "for" cycle. Just as in the above examples, you can add similar functions per your requirements and create a QueueDelegate that matches the parameter that the function needs.

AgentState Class

An instance of this class has information about the current state, when the state changed and of a single agent. Here is the information that can be extracted from this class.

For a full list of the class attributes see GET /agents/states API documentation.

SkillSummary Class

An instance of this class has the most relevant information about a specific skill; of you are trying to get some information regarding a specific skill and its configuration parameters this must be the first class you have to see.

For a full list of the class attributes see GET /skills/summary API documentation.