Content Display

This documentation explains how user-generated content (UGC), including reviews and statistics, as well as product information can be displayed using the mobile SDK.

Introduction

Use the Bazaarvoice Mobile SDKs to enable Conversations functionality, such as Ratings and Reviews. The Conversations module provides an easy-to-use wrapper around the Conversations API. Contact Bazaarvoice to set up Conversations.

πŸ“˜

You will need your apiKeyConversations to implement and use Conversations with Mobile SDKs.

Installation instructions

With Gradle

Include the Maven Central repository and add the appropriate Bazaarvoice Mobile SDK modules to your dependencies:

dependencies {  
  implementation 'com.bazaarvoice.bvandroidsdk:conversations:{BV_SDK_VERSION}.+'  
  implementation 'com.google.android.gms:play-services-ads:9.{YOUR_PLAY_SERVICES_VERSION}'  
  implementation 'com.android.support:recyclerview-v7:25.{YOUR_SUPPORT_LIBRARY_VERSION}'  
  implementation 'com.bazaarvoice.bvandroidsdk:conversations-ui: {BV_SDK_VERSION}.+'  
}  
repositories {  
  mavenCentral()  
}

Replace the {tokens}, including brackets, with the appropriate values. Refer to the Installation guide for {BV_SDK_VERSION}.

Extending the application

Create a class that extends android.app.Application, and initialize the Mobile SDK using its builder.

You can find a full list of build options in BVSDK.java.

public class MyApplication extends Application {  
  @Override  
  public void onCreate(){  
    super.onCreate();  
    BVSDK.builder(application, BazaarEnvironment.PRODUCTION)  
      .logLevel(BVLogLevel.VERBOSE) // Optional: Set the log level. Default level is ERROR.  
      .dryRunAnalytics(false)       // Optional: Set analytics to log only, not make a network request. Default is false.  
      .okHttpClient(okHttpClient)   // Optional: Use you own okHttpClient instance  
      .build();  
  }  
}

App manifest file

Add the following to your AndroidManifest.xml file.

<!-- set the name of the class for the application entry -->

<application
    android:name=".MyApplication">  
</application>

Using Conversations Display API

After you install the Mobile SDK, you can refer to the guide below for using the API and Conversations UI containers for displaying Product Review Statistics, Reviews, Question, Answers, and Bulk Ratings of several products at once.

πŸ“˜

If you need to check the list of possible parameters for any of the below APIs, please refer the below links and select the API from section contents:

BVConversationsClient

Use a Bazaarvoice ViewGroup class to make all your Conversations Display API requests.

Loading a product display page

When showing a product display page, use a ProductDisplayPageRequest to fetch useful data like reviewStatistics or to include the first 10 Review reviews.

First, let's look at a simple ProductDisplayPageRequest

  // request product information, including statistics on reviews and questions/answers.
  ProductDisplayPageRequest request = new ProductDisplayPageRequest.Builder("test1")
    .addIncludeStatistics(PDPContentType.Reviews)
    .addIncludeStatistics(PDPContentType.Questions)
    .build();

In the code above, a ProductDisplayPageRequest is created for productId test1. We also include statistics for reviews and questions/answers. You may want to include some actual content with it, as shown below. We also sort the included reviews by their submissionTime.

  // request product information, including statistics on reviews and questions/answers.
  ProductDisplayPageRequest request = new ProductDisplayPageRequest.Builder("test1")
    .addIncludeContent(PDPContentType.Reviews, 10)
    .addIncludeContent(PDPContentType.Questions, 5)
    .addReviewSort(ReviewOptions.Sort.SubmissionTime, SortOrder.DESC)
    .build();

Let's load this request!

To do so, pass the request to your BVConversationsClient instance as shown below.

    BVConversationsClient client = new BVConversationsClient.Builder(BVSDK.getInstance()).build(); // Use one instance
    client.prepareCall(request).loadAsync(new ConversationsCallback<ProductDisplayPageResponse>() {
      @Override
      public void onSuccess(ProductDisplayPageResponse response) {
        //called on Main Thread
        response.getResults(); //contains the product
      }

      @Override
      public void onFailure(BazaarException exception) {
        //called on Main Thread
      }
    });

Loading more reviews

As shown previously, you should use a ReviewsRequest to load the first page of UGC that your users will see (up to 20 items). When loading reviews, you should request and display reviews in a BVUiReviewsRecyclerView or BVUiReviewsContainerView container:

    BVConversationsClient client = new BVConversationsClient.Builder(BVSDK.getInstance()).build(); // Use one instance
    ReviewsRequest reviewsRequest = new ReviewsRequest.Builder("test1", 10, 20).build();
    reviewsRecyclerView = (BVUiReviewsRecyclerView) findViewById(R.id.my_reviews_recycler_view);
    reviewsRecyclerView.loadAsync(client.prepareCall(reviewsRequest), new ConversationsCallback<ReviewResponse>() {
      @Override
      public void onSuccess(ReviewResponse response) {
        //called on Main Thread
        response.getResults(); //contains reviews
      }

      @Override
      public void onFailure(BazaarException exception) {
        //called on Main Thread
      }
    });

A ReviewsRequest requires three parameters:

  • productId - the productId that you want reviews for
    or
    primaryFilter and ~Id - i.e. to get reviews by author you'd use primaryFilter.AuthorId and the Author's Id. Valid primaryFilters include Id, AuthorId, ProductId, SubmissionId, and CategoryAncestorId.
  • limit - max number of reviews to fetch (maximum of 20)
  • offset - the index to start on

A combination of limit and offset should be used to load more pages of reviews upon the user's request.

You can add filters and sorts to the request, as shown below:

    ReviewsRequest request = new ReviewsRequest.Builder("test1", 10, 0)
     .addFilter(ReviewOptions.Filter.HasPhotos, EqualityOperator.EQ, "")
     .addSort(ReviewOptions.Sort.Rating, SortOrder.DESC)
     .build();

Loading reviews is simply done by calling the loadAsync() method on the chosen Reviews View container as shown above.

Displaying Ratings & Reviews

Multiple reviews should be shown in one of the following container view:

  • BVUiReviewsRecyclerView
  • BVUiReviewsContainerView

Each review should be shown using a ReviewView.

Loading more Questions & Answers

Similarly to reviews, you should use a QuestionAndAnswerRequest to load the first page of Questions & Answers (up to the first 20 questions). When loading questions, you should request and display questions in a BVUiQuestionsRecyclerView or BVUiQuestionsContainerView container:

    BVConversationsClient client = new BVConversationsClient.Builder(BVSDK.getInstance()).build(); // Use one instance
    QuestionAndAnswerRequest questionsRequest = new QuestionAndAnswerRequest.Builder("test1", 10, 20).build();
    questionsRecyclerView = (BVUiQuestionsRecyclerView) findViewById(R.id.my_questions_recycler_view);
    questionsRecyclerView.loadAsync(client.prepareCall(questionsRequest), new ConversationsCallback<QuestionAndAnswerResponse>() {
      @Override
      public void onSuccess(QuestionAndAnswerResponse response) {
        //called on Main Thread
        response.getResults();
      }

      @Override
      public void onFailure(BazaarException exception) {
        //called on Main Thread
      }
    });

A QuestionsAndAnswersRequest requires the same three parameters as a ReviewsRequest:

  • productId - the productId that you want questions for
  • limit - max number of questions to fetch (maximum of 20)
  • offset - the index to start on

A combination of limit and offset should be used to load more pages of questions upon the user's request.

You can add filters and sorts to the request, as shown below:

    QuestionsAndAnswersRequest request = new QuestionsAndAnswersRequest.Builder("test1", 10, 0)
     .addFilter(QuestionOptions.Filter.HasPhotos, EqualityOperator.EQ, "")
     .addQuestionSort(QuestionOptions.Sort.TotalAnswerCount, SortOrder.DESC)
     .addAnswerSort(AnswerOptions.Sort.SubmissionTime, SortOrder.ASC)
     .build();

Displaying Questions & Answers

Questions & Answers should be shown in one of the following container view:

  • BVUiQuestionsRecyclerView
  • BVUiQuestionsContainerView
  • AnswersRecyclerView
  • AnswersContainerView

Each question should be shown using a QuestionView, and each answer should be shown using an AnswerView.

Loading review comments

Comments can be loaded either by a single comment ID, or you can load comments by a review ID with limit and offset parameters. Simply construct a CommentsRequest object and choose one of the default constructors provided. The example provided below demonstrate how to fetch a list of comments from a given review ID.

    BVConversationsClient client = new BVConversationsClient.Builder(BVSDK.getInstance()).build(); // Use one instance

    CommentsRequest request = new CommentsRequest.Builder(reviewId, 20, 0)
      // Add other optional parameters
      .addSort(CommentOptions.Sort.SUBMISSION_TIME, SortOrder.DESC)
      .addIncludeContent(CommentIncludeType.PRODUCTS, 99)
      .addFilter(CommentOptions.Filter.CONTENT_LOCALE, EqualityOperator.EQ, "en_US")
      .build();

    client.prepareCall(request).loadAsync(new ConversationsCallback() {
      @Override
      public void onSuccess(CommentsResponse response) {
        // successful response, get the comments and draw your UI
      }

      @Override
      public void onFailure(BazaarException exception) {
        // add your error handling logic here
      }
    });

Showing bulk ratings

To show product rating statistics on a category page, use a BulkRatingsRequest. For example, on a category page like this one:

Getting each product's rating statistics can be done with the following single request:

    List productIds = Arrays.asList("test1", "test2", "test3", "test4");
    BulkRatingsRequest request = new BulkRatingsRequest
      .Builder(productIds, BulkRatingOptions.StatsType.All).build();
  

Which can be loaded with:

    BVConversationsClient client = new BVConversationsClient.Builder(BVSDK.getInstance()).build(); // Use one instance
    client.prepareCall(request).loadAsync(new ConversationsCallback<BulkRatingsResponse>() {
      @Override
      public void onSuccess(BulkRatingsResponse response) {
        //called on Main Thread
        for (Statistics stats : response.getResults()) {
          String productId = "";
          Float avgRating = Float.NaN;
          Integer totalReviewCount = 0;
          ProductStatistics productStats = stats.getProductStatistics();
          if (productStats != null) {
            productId = productStats.getProductId();
            ReviewStatistics reviewStats = productStats.getReviewStatistics();
            if (reviewStats != null) {
              avgRating = reviewStats.getAverageOverallRating();
              totalReviewCount = reviewStats.getTotalReviewCount();
            }
          }
          String msg = String
            .format("productId: %s, avgRating: %f, totalReviewCount: %d",
            productId, avgRating, totalReviewCount);
          Log.d("BulkRatings", msg);
        }
      }

      @Override
      public void onFailure(BazaarException exception) {
        //called on Main Thread
        Log.e("BulkRatings", "Failed to get bulk ratings", exception);
      }
    });

Showing authors profile

Badge display

Please note that image links are not returned from the Conversations API. The display for Conversation API clients is left up to the client's creative interpretation. For more information please see the Conversations Developer documentation on Badges.

To show an Authors profile, use an AuthorsRequest. For example:

    AuthorsRequest request = new AuthorsRequest.Builder("authorId")
      .addIncludeContent(AuthorIncludeType.REVIEWS, 10)
      .addIncludeContent(AuthorIncludeType.QUESTIONS, 11)
      .addIncludeContent(AuthorIncludeType.ANSWERS, 12)
      .addIncludeContent(AuthorIncludeType.COMMENTS, 12)
      .addReviewSort(ReviewOptions.Sort.SubmissionTime, SortOrder.DESC)
      .addQuestionSort(QuestionOptions.Sort.SubmissionTime, SortOrder.DESC)
      .addAnswerSort(AnswerOptions.Sort.AuthorId, SortOrder.DESC)
      .addIncludeStatistics(AuthorIncludeType.REVIEWS)
      .addIncludeStatistics(AuthorIncludeType.QUESTIONS)
      .addIncludeStatistics(AuthorIncludeType.ANSWERS)
      .build();
  

Which can be loaded with:

    BVConversationsClient client = new BVConversationsClient.Builder(BVSDK.getInstance()).build(); // Use one instance
    client.newCall(request).enqueue(new ConversationsCallback() {
      @Override
      public void onSuccess(AuthorsResponse response) {
        if (response.getHasErrors()) {
          // Handle API request errors
          return;
        }

        List authors = response.getResults();
        if (authors.size() > 0) {
          Author author = authors.get(0);
          // Use the author object
        }
      }

      @Override
      public void onFailure(BazaarException exception) {
        exception.printStackTrace();
      }
    );

Loading Review Highlights

Load Review Highlights (PROS and CONS) by specifying a product ID and client ID.

  ReviewHighlightsRequest request = new ReviewHighlightsRequest.Builder("productId").build();
  BVConversationsClient client =β€―new BVConversationsClient.Builder(BVSDK.getInstance()).build();β€―// Use one instance 

  client.prepareCall(request).loadAsync(new ConversationsDisplayCallback<ReviewHighlightsResponse>() {
    @Override
    public void onSuccess(ReviewHighlightsResponse response) {
      List<ReviewHighlight> positives = response.getReviewHighlights().getPositives();
      List<ReviewHighlight> negatives = response.getReviewHighlights().getNegatives();

      for (ReviewHighlight positive : positives) {
        String title = positive.title; // PRO TITLE
      }

      for (ReviewHighlight negative : negatives) {
        String title = negative.title; // CON TITLE
      }
    }

    @Override
    public void onFailure(ConversationsException exception) {
      // HANDLE ERROR
    }
  }); 

Custom key-value pairs

If there is some query parameter that is not supported by the SDK, that your configuration supports, you can add it to a Display Request as follows:

final ReviewsRequest reviewsRequest = new ReviewsRequest.Builder(productId, limit, offset)  
    .addCustomDisplayParameter("customKey", "customValue")  
    .build();

Conversations display: UI containers

In order to provide user interaction analytics that help produce useful ROI (return on investment) reports, and more accurate future recommendations, you should use the SDK-provided views when requesting and displaying Reviews, Questions, or Answers.

The SDK supports the following sub-classed types of view containers, depending on your preference:

  • FrameLayout: BVUiReviewsContainerView, AnswersContainerView, BVUiQuestionsContainerView
  • RecyclerView: BVUiReviewsRecyclerView, AnswersRecyclerView, BVUiQuestionsRecyclerView

For a refrence implementation on utilizing the Reviews, Question, and Answers containers, please refer to the sample application in the SDK.