-
Notifications
You must be signed in to change notification settings - Fork 1
Tutorials
This guide provides tutorials for working with the Community Android SDK API providers and utility methods.
- Intro to the Client classes
- Handling a 401 authentication error
- Working with messages
- Working with subscriptions
When you work with our API providers and utility methods to interact with Khoros Community entities like users, messages, kudos, and images, you’ll generally be working with these classes:
- LiClient
- LiClientManager
- LiClientRequestParams
- LiPostClientResponse
- LIGetClientResponse
We’ll give you a quick introduction to them here, as you’ll be seeing these throughout our tutorials.
LiClient
is an interface that includes methods to make callbacks, get the HTTP request type, define the ordering of LiQL query responses, get the Gson library, and client type.
LiClientManager
is the class that includes all of the API providers to interact with Community.You’ll be using this class to make POST, PUT, and GET actions for things like posting a message, giving a kudo, adding an image, creating a user, and so on. This class also includes methods for you to make custom POST, PUT, and GET actions. For custom POST and PUT actions, you will provide a Community API v2 endpoint path and a request body. For custom GET actions, you will provide a LiQL query.
LiClientRequestParams
is a class that includes all of the request parameter builders used with our API providers. Each provider has a unique set of parameters, but all of them require the Android context. See API reference and Javadoc for details.
LiPostClientResponse
represents the response to a POST action. The class includes methods to get the response, and to get specific details about the response like the HTTP code and status, and the JSON object if one is included.
LiGetClientResponse
represents the response to a GET action. The class includes methods to get the response (transformed to the corresponding data model), and to get details like the HTTP code and status of the response.
If an anonymous user does not have permission to perform a certain action, such as replying to a message or giving kudos, the SDK returns a 401 (Unauthorized) error. The following example shows how to check for the 401 error and display the error in the UI.
try {
LiClientRequestParams liClientRequestParams = new LiClientRequestParams.LiMessagesByBoardIdClientRequestParams(getContext(), selectedBoardId);
LiClient client = LiClientManager.getMessagesByBoardIdClient(liClientRequestParams);
client.processAsync(new LiAsyncRequestCallback < LiGetClientResponse > () {
@Override
public void onSuccess(LiBaseRestRequest liBaseRestRequest, final LiGetClientResponse liClientResponse) {
if (!isAdded() || getActivity() == null) {
return;
}
// check for a 401 Unauthorized error
if (null != liClientResponse) {
if (liClientResponse.getHttpCode() == HTTP_CODE_UNAUTHORIZED) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
showUserNotLoggedIn();
}
});
return;
} else if (liClientResponse.getHttpCode() == HTTP_CODE_SERVER_ERROR) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
//Show server error
}
});
return;
}
response = liClientResponse.getResponse();
// show the UI based upon response in case of successful execution
}
}
@Override
public void onError(Exception e) {
if (!isAdded() || getActivity() == null) {
return;
}
}
});
} catch (LiRestResponseException exception) {
if (!isAdded() || getActivity() == null) {
return;
}
//Show server error
}
Then you can use the following to begin the login flow for the anonymous user:
try {
LiSDKManager.getInstance().initLoginFlow(getActivity(), ssoToken);
} catch (URISyntaxException e) {
Log.d(LiSDKConstants.GENERIC_LOG_TAG, "Could not initiate login flow");
LiUIUtils.showInAppNotification(getActivity(), R.string.li_login_failure);
}
This section provides a walkthrough of actions used when working with messages.
Let’s look at an example class that posts a new topic message to the community. We’ll build a client using the API provider LiClientManager.getCreateMessageClient(LiClientRequestParams liClientRequestParams)
. Note that this example is for a new topic. Creating a reply takes other considerations. We show an example of creating a reply later on.
We need to:
- Build the request parameters for the client
- Create the client
- Call the client
All of our clients take a set of request parameters, so the first thing we do is build those parameters to pass to the client. Client request parameters are built using LiClientRequestParams
. There is a specific builder for each client. To post a new message, we need the Android context, the subject and body text, the board where the message will be posted, and (optionally) an image ID and title if the user has uploaded an image.
We build the request parameters like this:
// Build the parameters
LiClientRequestParams liClientRequestParams = new LiClientRequestParams.LiCreateMessageClientRequestParams(getContext(), askQuestionSubjectText,askQuestionBodyText, selectedBoardId, selectedImageId, selectedImageName);
Next, we create the client, passing our request parameters:
// Create the client
LiClient postQuestionClient = LiClientManager.getCreateMessageClient(liClientRequestParams);
In this example, we’re going to make an asynchronous call to run the client. The client will return a response, and we’ll use LiPostClientResponse
to handle the response depending on the HTTP code returned.
// Call the client
postQuestionClient.processAsync(new LiAsyncRequestCallback<LiPostClientResponse>() {
// If successful, use HTTP response code from LiPostClientResponse
@Override
public void onSuccess(LiBaseRestRequest liBaseRestRequest,
LiPostClientResponse liClientResponse) throws LiRestResponseException {
switch (liClientResponse.getResponse().getHttpCode()) {
// Depending on the HTTP code returned in the response,
// display the appropriate message post confirmation
// and perform the next action
case LiSDKConstants.HTTP_CODE_SUCCESSFUL:
// Handle successful post
case HTTP_CODE_FORBIDDEN:
// Handle permission issue
default:
// Handle other error codes
}
}
@Override
public void onError(Exception e) {
// Handle call failure
}
});
Posting a topic with an image adds another layer to our topic post example. The flow requires that we upload the image to the community first. This returns an image ID. The provider uses the ID to create a macro string and appends that string to the end of the message body entered by the user.
You’ll upload the image to the community using LiClient getUploadImageClient
, and you’ll build the request parameters with LiUploadImageClientRequestParams
.
// Build the request parameters
LiClientRequestParams liClientRequestParams = new
LiClientRequestParams.LiUploadImageClientRequestParams(getContext(),
selectedImageName, imageDescription,imageAbsolutePath,selectedImageName);
// Create the client
LiClient uploadImage = LiClientManager.getUploadImageClient(liClientRequestParams);
uploadImage.processAsync(new LiAsyncRequestCallback<LiPostClientResponse>() {
Next, we make a callback.
// Call the client
uploadImage.processAsync(new LiAsyncRequestCallback<LiPostClientResponse>() {
// Get the image ID from the response
@Override
public void onSuccess(LiBaseRestRequest liBaseRestRequest,
LiPostClientResponse liPostClientResponse)
throws LiRestResponseException {
// If successful, upload the image the message
// We can get the image ID from the JSON object returned with the response
// using calls on LiPostClientResponse.
// We get the ID as a string so that we can append it to the message body
// in the next step
if (liPostClientResponse.getHttpCode() == 200) {
Log.i(LiSDKConstants.GENERIC_LOG_TAG,
liPostClientResponse.getResponse().getData().toString());
selectedImageId = liPostClientResponse.getResponse().getData()
.get("data").getAsJsonObject().get("id").getAsString();
post();
// If unsuccessful, do something else,
// like notify the user that the upload was unsuccessful
} else {
...
}
}
}, imageAbsolutePath, selectedImageName);
To retrieve a specific message, you’ll use the LiClientManager.getMessageClient(LiClientRequestParams liClientRequestParams)
provider. Here’s an example.
We’re going to create and make a callback to run a client to get a message by ID. The provider returns the LiMessage
object.
// Build the request parameters
LiClientRequestParams liClientRequestParams = new
LiClientRequestParams.LiMessageClientRequestParams(getContext(),
selectedMessageId);
// Create the client
LiClient messageClient = LiClientManager.getMessageClient(liClientRequestParams);
// Call the client
messageClient.processAsync(new LiAsyncRequestCallback<LiGetClientResponse>() {
@Override
public void onSuccess(LiBaseRestRequest request,
LiGetClientResponse originalArticleResponse)
throws LiRestResponseException {
selectedMessage = (LiMessage) originalArticleResponse.getResponse().get(0);
// do something with the message
});
}
// If unsuccessful, handle the error
...
Before we can post a reply, we want to get and display the parent message. We showed an example of how to get the message earlier. While replies and topic messages are both stored as messages in the database, we create a reply using a different provider than when creating a topic.
To create a reply, we use LiClientManager.getCreateReplyClient
. We’re passing the body text of the reply and the parent message ID to getCreateReplyClient
, as well as in image ID and name if the user uploads an image.
// Build the request parameters
LiClientRequestParams liClientRequestParams = new
LiClientRequestParams.LiCreateReplyClientRequestParams(getContext(),
askQuestionBodyText, selectedMessageSubject, selectedMessageId, selectedImageId,
selectedImageName);
// Create the client
LiClient replyMessageClient = LiClientManager.getCreateReplyClient(liClientRequestParams);
// Call the client
replyMessageClient.processAsync(new LiAsyncRequestCallback<LiPostClientResponse>() {
...
}
Just like when creating a topic message, we will use LiPostClientResponse.getResponse().getHttpCode()
to get the HTTP response code to display the appropriate message post confirmation message and take the next actions.
Subscriptions are a powerful way for users to stay engaged with a community. A subscription to a conversation, a board, a category, or even a label, alerts users to activity important to them.
This section will teach you how to integrate subscription operations into an Android application through Community SDK APIs.
A subscription operates on a target -- the community, a category, a board, a topic message, or a label -- and each target is represented by a unique identifier. Users subscribe or unsubscribe to a single target for each subscription they create in the community.
In the following sections, you'll learn how to:
- Verify that a user is logged in
- Subscribe to a topic message
- Retrieve subscriptions
- Unsubscribe from a target
Subscription API calls work similar to any other calls made through the Community Android SDK APIs. Each of the examples in this section includes the following tasks:
- Creating a respective API-method client parameter
- Creating a respective API-method client
- Processing the client request, synchronously or asynchronously as needed
- Processing the response
All calls to our subscriptions API require authentication. Anonymous users cannot create or delete subscriptions.
Before you make any calls to the Subscription API, ensure that the current user is logged using this call on LiSDKManager
:
LiSDKManager.getInstance().isUserLoggedIn() == true
Let's walk through creating a subscription to a message. Note that users subscribe to topic messages, not to replies or comments.
The first thing we're going to do is create a subscription target using LiSubscriptionPostModel.MessageTarget(messageId)
, passing the message ID of the topic we're subscribing to.
LiSubscriptionPostModel
also supports LiSubscriptionPostModel.BoardTarget
.
String messageId = "message:test";
LiSubscriptionPostModel.Target target = new LiSubscriptionPostModel.MessageTarget(messageId);
Next, we're going to create a subscription POST model. This step puts the details for the subscription into the proper model for ingestion by the API when we make our POST call. We pass the target we created in the previous step.
LiSubscriptionPostModel postModel = new LiSubscriptionPostModel(target);
Now, we create the parameters for the subscription that we will pass with our client request:
LiClientRequestParams.LiPostSubscriptionParams params = new LiClientRequestParams.LiPostSubscriptionParams(mContext, target);
Finally, we're ready to create the POST client and make our request using LiClientManager.getSubscriptionPostClient(LiClientRequestParams)
. You can read more about getSubscriptionPostClient(LiClientRequestParams)
in our API reference guide and Javadoc.
Then, we make an asynchronous request.
liClient = LiClientManager.getSubscriptionPostClient(params);
liClient.processAsync(callback);
A successful response contains an instance of LiPostClientResponse
, which contains a JSON body. It will look something like this:
{
"status": "success",
"message": "",
"http_code": 200,
"data": {
"type": "subscription",
"id": "0",
"href": "/subscriptions/0",
"target": {
"type": "message",
"id": "571",
"href": "/messages/571",
"view_href": "https://triumph.qa.lithium.com/t5/Cross-Device-Demo/A-new-question/m-p/571#M44"
},
"subscriber": {
"type": "user",
"id": "583464189",
"href": "/users/583464189",
"view_href": "https://triumph.qa.lithium.com/t5/user/viewprofilepage/user-id/583464189",
"login": "Naren"
}
},
"metadata": {}
}
The response returns a target (in this case, a message) and a subscriber (a user), and most important, the unique id of the subscription. You'll see how to use the value of id later when we look at how to unsubscribe from a target.
To retrieve all of a user's subscriptions, we're going to follow some familiar steps.
// We create the subscription parameters to use with the request
LiClientRequestParams liClientRequestParams = new LiClientRequestParams.LiUserSubscriptionsClientRequestParams(mContext);
// We create a GET client and make the request
LiClient subscriptionsClient = LiClientManager.getUserSubscriptionsClient(liClientRequestParams);
subscriptionsClient.processAsync(callback...);
On success, the response JSON will look something like the following. You'll see items similar to the ones returned from our earlier POST example.
{
"status" : "success",
"message" : "",
"http_code" : 200,
"data" : {
"type" : "subscriptions",
"list_item_type" : "subscription",
"size" : 2,
"items" : [ {
"type" : "subscription",
"id" : "32",
"href" : "/subscriptions/32",
"target" : {
"type" : "message",
"id" : "568",
"href" : "/messages/568",
"view_href" : "/t5/abc/A-new-question/m-p/568#M271"
},
"subscriber" : {
"type" : "user",
"id" : "583464189",
"href" : "/users/583464189",
"view_href" : "/t5/user/viewprofilepage/user-id/583464189",
"login" : "Naren"
}
}, {
"type" : "subscription",
"id" : "30",
"href" : "/subscriptions/30",
"target" : {
"type" : "message",
"id" : "571",
"href" : "/messages/571",
"view_href" : "/t5/Cross-Device-Demo/A-new-question/m-p/571#M44"
},
"subscriber" : {
"type" : "user",
"id" : "583464189",
"href" : "/users/583464189",
"view_href" : "/t5/user/viewprofilepage/user-id/583464189",
"login" : "Naren"
}
} ]
},
"metadata" : { }
}
In this example, we're going to unsubscribe from the post we subscribed to earlier. To unsubscribe from a post necessarily needs a subscription ID which is obtained from the subscription. Subscriptions can be synced through Getting all subscriptions or a single subscription obtained as a response to subscribe call.
-
Create a subscription delete client parameter
String subscriptionId = ""; LiClientRequestParams params = new LiClientRequestParams.LiDeleteSubscriptionParams(getContext(), subscriptionId);
-
Create a delete subscription client and process
LiClient client = new LiClientManager.getSubscriptionDeleteClient(params); client.processAsync(callback);
-
Process the response
On success, the response would look like this:
{"status":"success","message":"","http_code":200,"data":{},"metadata":{}}