Pre Requisites

  • Freshchat SDK clients require devices running Android 4.1 or higher

  • Freshchat SDK supports apps targeting Android version 7.0 with appcompat-v7 r24.2 or later

Obtaining your AppId and AppKey

Login to your Freshchat account as Account Owner/Admin. Go to Settings > Mobile SDK.



1. Add Freshchat SDK to your project


i) Add the maven URL to the root build.gradle (project/build.gradle)

allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}


ii) Add the following dependency to your app module's build.gradle file (project/app/build.gradle):               

apply plugin: 'com.android.application'

android {
// ...
}

dependencies {
// ...
    implementation 'com.github.freshdesk:freshchat-android:{{latest-version}}'
}

Replace {{latest-version}} with the latest version of the SDK from here. 

For e.g. implementation 'com.github.freshdesk:freshchat-android:2.6.1' 


iii) When app targets Android 7.0+ and Image attachment is enabled, FileProvider needs to be configured.

Include the provider in the AndroidManifest.xml as below.

AndroidManifest.xml

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.demoapp.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/freshchat_file_provider_paths" />
</provider>

Strings.xml

<string name="freshchat_file_provider_authority">com.example.demoapp.provider</string>


2. Initialization of SDK

Invoke Freshchat.init() with your app id and app key before invoking/ attempting to use any other features of Freshchat SDK.  


We highly recommend invoking init() from your app's launcher/support activity's onCreate() function. Freshchat SDK checks for presence of its components during init() and will warn about missing components when it detects the components are missing or their manifest entries are missing. 


Replace the YOUR-APP-ID and YOUR-APP-KEY in the following code snippet with the actual app ID and app key.

FreshchatConfig config = new FreshchatConfig("YOUR-APP-ID","YOUR-APP-KEY");
Freshchat.getInstance(getApplicationContext()).init(config);

2.1 Initialization Config Options

Enable or disable features like camera capture by specifying it in the config before initialization. 

FreshchatConfig config = new FreshchatConfig("YOUR-APP-ID","YOUR-APP-KEY");
config.setCameraCaptureEnabled(true);
config.setGallerySelectionEnabled(true);
config.setResponseExpectationEnabled(true);
Freshchat.getInstance(getApplicationContext()).init(config);

3. User Information


3.1 Updating User Information

You can send basic user information at any point to give you more context on the user when your support agents are messaging back and forth with them. 

// Get the user object for the current installation
FreshchatUser freshchatUser = Freshchat.getInstance(getApplicationContext()).getUser();
freshchatUser.setFirstName("John");
freshchatUser.setLastName("Doe");
freshchatUser.setEmail("john.doe.1982@mail.com");
freshchatUser.setPhone("+91", "9790987495");

// Call setUser so that the user information is synced with Freshchat's servers
Freshchat.getInstance(getApplicationContext()).setUser(freshchatUser);

3.2 Updating User Properties (Meta Data)

You can capture and send additional metadata about the user and the events in the app, all of which also becomes a way to segment your users to later push messages to them.  

/* Set any custom metadata to give agents more context, and for segmentation for marketing or pro-active messaging */
Map<String, String> userMeta = new HashMap<String, String>();
userMeta.put("userLoginType", "Facebook");
userMeta.put("city", "SpringField");
userMeta.put("age", "22");
userMeta.put("userType", "premium");
userMeta.put("numTransactions", "5");
userMeta.put("usedWishlistFeature", "yes");
                                
//Call setUserProperties to sync the user properties with Freshchat's servers
Freshchat.getInstance(getApplicationContext()).setUserProperties(userMeta);


3.3 Reset User Data

Reset user data at logout or when deemed appropriate based on user action in the app by invoking the resetUser API. 

Freshchat.resetUser(getApplicationContext());


3.4 Restore user

For retaining the chat messages across devices/sessions/platforms, the mobile app needs to pass the same external id and restore id combination for the user. This will allow users to seamlessly pick up the conversation from any of the supported platforms - Android, iOS, and Web.


  • External Id - This should (ideally) be a unique identifier for the user from your system like a user id or email id and is set using the Freshchat.identifyUser() API. This cannot be changed once set for the user.

  • Restore Id - This is generated by Freshchat for the current user, given an external id was set and can be retrieved anytime using the Freshchat.getUser().getRestoreId() API. The app is responsible for storing and later present the combination of external id and restore id to the Freshchat SDK to continue the chat conversations across sessions on same device or across devices and platforms.
Note
  • Restore Id for a user is typically generated only when user has sent a message.
  • Notifications are supported in only one mobile device at any point in time and is currently the last restored device or device with the last updated push token.

To set external id

Freshchat.getInstance(getApplicationContext()).identifyUser(externalId, null);


To retrieve the restore id

String restoreId = Freshchat.getInstance(getApplicationContext()).getUser().getRestoreId();
saveRestoreIdForUser(restoreId);


To lookup and restore user by external id and restore id

Freshchat.getInstance(getApplicationContext()).identifyUser(externalId, restoreId);


To listen to restore id generated event

Restore Id generation is an asynchronous process. So you need to register a broadcast receiver to get notified when restore id is generated. This receiver can be registered at onCreate and unregistered at onTerminate of your application class.


Register for broadcast receiver

IntentFilter intentFilter = new IntentFilter(Freshchat.FRESHCHAT_USER_RESTORE_ID_GENERATED);
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(broadcastReceiver, intentFilter);

Listen to broadcast receiver

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
     String restoreId = Freshchat.getInstance(getApplicationContext()).getUser().getRestoreId();
  }
};

Unregister broadcast receiver

LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(broadcastReceiver);


4. Launching the Support Solution

Use the snippets below to launch into the FAQ or Conversation based support experience from a call to action in your app. Your call to action or entry point can be an on-screen button or a menu item.


4.1 Conversations

In response to specific UI events like a menu selection or button on click event, invoke the showConversations() API to launch the Conversation Flow. If the app has multiple channels configured, the user will see the channel list. Channel list is ordered as specified in the Dashboard (link to channel list in dashboard) when there are no messages. When messages are present, the order is based on most recently interacted channel. 

Note

Only Message Channels with visibility set to "Visible to all users" will be displayed when using showConversations() API


Launching conversation list from click of a button in your app's screen

myConversationsButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Freshchat.showConversations(getApplicationContext());
    }
}); 


4.1.1 Filtering Conversation Channels

To filter and display only Message Channels tagged with a specific term, use the filterByTags API in ConversationOptions instance passed to showConversations() API as below.


Eg: To link and display only specific Message Channels from say orders page in your app, those specific Message Channels can be tagged with the term "order_queries".

List<String> tags = new ArrayList<>();
tags.add("order_queries");
ConversationOptions options = new ConversationOptions()
    .filterByTags(tags, "Order Queries");
Freshchat.showConversations(MainActivity.this, options);

Note
  • If no matching channel is found, the user will be redirected to the default channel. 
  • Message Channels which are normally not visible when using showConversations() API, will also be displayed when tagged and the specific tag is passed to filterByTags API of ConversationOptions instance passed to showConversations() API.


4.1.2 Unread Count

If you would like to obtain the number of unread messages for the user at app launch or any other specific event, use the getUnreadCountAsync API and display the count.


Freshchat.getInstance(getApplicationContext()).getUnreadCountAsync(new UnreadCountCallback() {
        @Override
        public void onResult(FreshchatCallbackStatus freshchatCallbackStatus, int unreadCount) {
            //Assuming "badgeTextView" is a text view to show the count on
            badgeTextView.setText(Integer.toString(unreadCount));
        }
    });


The app can also choose to listen to changes to unread count when the app is open. The way to listen to the broadcast is described below.


Register for broadcast receiver

IntentFilter intentFilter = new IntentFilter(Freshchat.FRESHCHAT_UNREAD_MESSAGE_COUNT_CHANGED);
    getLocalBroadcastManager(getApplicationContext()).registerReceiver(unreadCountChangeReceiver, intentFilter);


Listen for unread count

BroadcastReceiver unreadCountChangeReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Freshchat.getInstance(getApplicationContext()).getUnreadCountAsync(new UnreadCountCallback() {
            @Override
            public void onResult(FreshchatCallbackStatus freshchatCallbackStatus, int unreadCount) {
                //Assuming "badgeTextView" is a text view to show the count on
                badgeTextView.setText(Integer.toString(unreadCount));
            }
        });
    }
}


Unregister for broadcast receiver

getLocalBroadcastManager(getApplicationContext()).unregisterReceiver(unreadCountChangeReceiver);

4.1.3 Unread message count across conversations filtered by tags

If you would like to obtain the number of unread messages for the user across specific conversations filtered by tags, use the getUnreadCountAsync API.



List<String> tags = new ArrayList<>();
    tags.add("premium"); // Tags to filter conversations by
    Freshchat.getInstance(getApplicationContext()).getUnreadCountAsync(new UnreadCountCallback() {
        @Override
        public void onResult(FreshchatCallbackStatus FreshchatCallbackStatus, int unreadCount) {
            badgeTextView.setText(Integer.toString(unreadCount));
        }
    }, tags);


4.2. FAQ

In response to specific UI events like a menu selection or button click event, invoke the showFAQs() API to launch the FAQ screen. By default the FAQ Categories is displayed as a grid with a “Contact Us” button at the bottom. For customising this, check the FAQ Options.

myFAQButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {
        Freshchat.showFAQs(getApplicationContext());
    }
});

4.2.1 FAQs Options

Customizations to the FAQ flow can be achieved by specifying the relevant options in the FaqOptions instance passed to the showFAQs() API.

// Launching FAQ from click of a button in your app's screen
myFAQButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View view) {

        FaqOptions faqOptions = new FaqOptions()
            .showFaqCategoriesAsGrid(true)
            .showContactUsOnAppBar(true)
            .showContactUsOnFaqScreens(false)
            .showContactUsOnFaqNotHelpful(false);

        Freshchat.showFAQs(MainActivity.this, faqOptions);
    }
});


4.2.2 Filtering FAQ categories by tags

To filter and display only FAQ Categories tagged with a specific term, use the filterByTags API with Filter Type as Category in FAQOptions instance passed to showFAQs() API.


Eg: To display FAQ Categories related to specific user type, those specific FAQ Categories can be tagged with the term "premium".

List<String> tags = new ArrayList<>();
tags.add("premium");

FaqOptions faqOptions = new FaqOptions()
    .filterByTags(tags, "FAQs", FaqOptions.FilterType.CATEGORY);//tags, filtered screen title, type

Freshchat.showFAQs(MainActivity.this, faqOptions);


4.2.3 Filtering FAQ articles by tags

To filter and display only FAQs tagged with a specific term, use the filterByTags API with Filter Type as Article in FAQOptions instance passed to showFAQs() API as below. 

NoteFAQs also inherit the tags from the parent FAQ Category.

Eg: To link to FAQs related to payment failure, those specific FAQs can be tagged with the term "payment_failure" and can be linked to from Payments page in the app.

List<String> tags = new ArrayList<>();
tags.add("payment_failure");

FaqOptions faqOptions = new FaqOptions()
    .filterByTags(tags, "payment_failure", FaqOptions.FilterType.ARTICLE);//tags, filtered screen title, type

Freshchat.showFAQs(MainActivity.this, faqOptions);


4.2.4 Filter Message Channels displayed on clicking "Contact Us" in FAQs by tags

To filter and display only Message Channels tagged with a specific term when user clicks "Contact Us"in FAQ screens, use the filterContactUsByTags API in FAQOptions instance passed to showFAQs() API as below.


NoteThe default behaviour for "Contact Us" from within FAQ flow is same as invoking showConversations() i.e it will display all channels that are marked "Visible to all users", except when filtering of channels is enabled by passing tags to filterContactUsByTags API.


Eg: To display Message Channels related to specific section of FAQ show, those specific Message Channels can be tagged with the term "payment_failure" 

List<String> tags = new ArrayList<>();
tags.add("payment_failure");

FaqOptions faqOptions = new FaqOptions()
    .filterContactUsByTags(tags, "Payments"); //tags, filtered screen title

Freshchat.showFAQs(MainActivity.this, faqOptions);


5. Send message API

The app can send a message on behalf of the user using the sendMessage() API. 


NoteThis API would silently send a message and not launch the Freshchat SDK UI

Eg: To send a message on a channel tagged "premium", the API can be invoked as below.

String tag = "premium";
String msgText = "User has trouble with order #1234";
FreshchatMessage FreshchatMessage = new FreshchatMessage().setTag(tag).setMessage(msgText);
Freshchat.sendMessage(getContext(), FreshchatMessage);


6. Push Notifications

Integrating Freshchat push notification in your application will help users receive your support messages quicker.

6.1 Connecting Freshchat with FCM 


Prerequisites

  1. FCM Implemented in you app
  2. Device running Play Services
  3. FCM Server Key saved in Freshchat web portal

Steps

  1. Saving FCM server key in Freshchat web portal
  2. Sending the device registration token to Freshchat

  3. Handling messages


6.1.1 Saving FCM server key in Freshchat web portal

Get your Application’s Firebase FCM server key and save it in Freshchat web app under Settings > Mobile SDK > FCM Server key section.


6.1.2 Sending the device registration token to Freshchat

Send user push registration token to Freshchat SDK. 

String token = FirebaseInstanceId.getInstance().getToken();
Freshchat.getInstance(this).setPushRegistrationToken(token);


6.1.3 Handling messages

In the app’s implementation of  FirebaseMessagingService, pass the RemoteMessage object to Freshchat if it is a Freshchat notification.

public void onMessageReceived(RemoteMessage remoteMessage) {
    if (Freshchat.isFreshchatNotification(remoteMessage)) {
        Freshchat.handleFcmMessage(context, remoteMessage);
    } else {
        // Handle notifications with data payload for your app
    }
}


6.2 Customising Notifications

Freshchat SDK supports customizing the following for notifications.


1. Notification Icon (Small Icon and Large Icon) - App icon is used as the default for small icon if not set explicitly.

2. Notification Sound - Enable or disable notification tone. By default it is disabled.

3. Notification Priority - Priority for notifications in below Android 8.0 devices. Default is NotificationCompat.PRIORITY_DEFAULT.

4. Notification Importance - Importance for notifications in Android 8.0+ devices. Default is NotificationManagerCompat.IMPORTANCE_DEFAULT. This can be modified to show Heads up Notifications.

5. Activity to launch on up navigation from the messages screen launched from notification. The messages screen will have no activity to navigate up to in the backstack when it is launched from notification. Specify the activity class name to be launched.   

6. For specifying the accent color of the circle behind the small icon in notification,

<color name="freshchat_notification_accent_color">@color/red</color>


7. On Oreo and later versions of Android, the notification channel name used to deliver notifications can be customized by overriding the string as below.

<string name="freshchat_campaign_notification_channel_name">Campaign messages</string>

    8. Specifying the notification config,

FreshchatNotificationConfig notificationConfig = new FreshchatNotificationConfig()
    .setNotificationSoundEnabled(true)
    .setSmallIcon(R.drawable.ic_notif_small_icon)
    .setLargeIcon(R.drawable.ic_notif_large_icon)
    .launchActivityOnFinish(MainActivity.class.getName())
    .setPriority(NotificationCompat.PRIORITY_HIGH);

Freshchat.getInstance(getApplicationContext()).setNotificationConfig(notificationConfig);


Android Oreo Support

Freshchat supports Notification channels out of the box in Oreo or later. It automatically creates a notification channel for conversation messages.

Note:

If you haven’t already integrated FCM, do so by following the instructions here and then follow the above 3 steps.


7. Language localization


7.1 Changing Default SDK texts

All strings in SDK can be modified by overriding them in strings.xml.


All Freshchat texts can be found here.


7.2 Localization


7.2.1 Language localization of default Freshchat texts

All strings in SDK can be modified by overriding them in respective locale strings.xml file.


All Freshchat texts can be found here.


For more details, refer Android developers documentation here.


7.2.2 Language localization of FAQs and Channels

Once FAQs and Channels are localized in Freshchat web app, SDK will automatically update content based on user’s app/device locale.


7.3 Right-to-Left Language Support

Freshchat SDK supports RTL languages. 


7.4 Runtime app locale change


If your app can support different locale (languages) apart from the default locale of the device, follow the steps below to update the locale in your Freshchat SDK.


1. Once app changes locale, notify the sdk about the app locale change using below method,


Freshchat.notifyAppLocaleChange(activityContext);


2. Freshchat internally uses webview as part of SDK, from Android OS version 7.0, webview changes locale during the webview load.


To fix this, we have provided a callback method onLocaleChangedByWebView(), where you need to reset the locale again inside this function.


Implement FreshchatWebViewListener


private FreshchatWebViewListener webviewListener = new FreshchatWebViewListener() {
    @Override
    public void onLocaleChangedByWebView(@NonNull WeakReference<Context> activityContext) {
      if (activityContext.get() == null) {
        return;
      }
      
      // Reset the run time locale here
      changeLocale(activityContext, appLocale);
    }
  };

Set webview listener to Freshchat Instance .We recommend you to do this in onCreate() of Application class.


Freshchat.getInstance(this).setWebviewListener(webviewListener);



8. Customizations


8.1 UI Customization options

Refer theme documentation here.


8.2 Custom Image Loader

SDK defaults to including Picasso 2.5.2 library to download images. If you want to use any other version of Picasso or any other image download library, you can set your custom image downloader with Freshchat SDK using setImageLoader() API.


Examples

Implement your custom image loader

public class CustomImageLoader implements FreshchatImageLoader {
  
  @Override
 public void load(@NonNull FreshchatImageLoaderRequest request, @NonNull ImageView imageView) {
    // your code to download image and set to imageView
  }

  @Nullable
  @Override
  public Bitmap get(@NonNull FreshchatImageLoaderRequest request) {
    // code to download and return bitmap image
  }

  @Override
  public void fetch(@NonNull FreshchatImageLoaderRequest request) {
    // code to download image
  }
}


Call Freshchat.setImageLoader() in onCreate() of your Application class

public class MyApp extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    Freshchat.setImageLoader(new CustomImageLoader());
  }
}


9. Other Notes


9.1 Checklist for Launch

  1. Ensure you are initializing the SDK in the onCreate of the application or support activity.

  2. Ensure you are on the latest version of SDK.

  3. Check that you have push notifications working right from your first launch and have the right notification icons configured.

  4. Ensure the App name is set right for your notifications.

  5. Configure your default channel name and welcome message right even if you aren't using other channels.

  6. Capture the unique user identifier, email, phone number, or any other unique customer identifiers with the SDK to ensure smooth use of APIs, as well as for the best use of our "Smart Plugs" feature on the dashboard.

  7. Ensure the push notifications are working for new installs as well as upgrades from your previous versions.


9.2 Permissions

Freshchat SDK is built with support for the Run Time/Dynamic Permissions Model introduced in Marshmallow as long as the app is built with targetSdk as Marshmallow or later.


9.3 Proguard Configuration (If Proguard is enabled in your app)
Freshchat Android SDK is configured out of the box to support proguard. Proguard will automatically pickup the config for the SDK, no manual configuration is necessary.