Skip to main content
Version: 4.31.0

Advanced Settings

SDK Initialization

ThreadsLib.init(ConfigBuilder configBuilder)
public static final class ConfigBuilder {
@NonNull
private Context context;
@NonNull
private PendingIntentCreator pendingIntentCreator = (context1, appMarker) -> {

};
@Nullable
private UnreadMessagesCountListener unreadMessagesCountListener = null;

private boolean isDebugLoggingEnabled = false;

private int historyLoadingCount = 50;

public ConfigBuilder(@NonNull Context context) {}
}

historyLoadingCount - Numbers of messages that are loaded when requesting the chat history (default: 50)

isDebugLoggingEnabled - Indicates whether to log the message debug (default: false)

info

The only required parameter is context.

Configuring Client

ThreadsLib.initUser(UserInfoBuilderuserInfo)
public final class UserInfoBuilder {
@NonNull
String clientId;
@Nullable
String authToken;
@Nullable
String authSchema;
@Nullable
String clientIdSignature;
@Nullable
String userName;
@Nullable
String data;
@Nullable
String appMarker;
/**
* true if client id is encrypted
*/
boolean clientIdEncrypted = false;

public UserInfoBuilder(@NonNull String clientId) {}
}
info

The only required parameter is clientId.

  • clientId - Client's unique ID. This parameter is required.
  • authToken - String that will be passed in the Authorization http header.
  • authSchema - String that will be passed in the X-Auth-Schema http header.
  • clientIdSignature - Authorization signature clientId. The signature must be generated on your authorization server based on clientId using the RSA private key, then encrypted in Base64. For more details, refer to the backend documentation.
  • userName - Client's name (can be empty)
  • data - JSON string with custom client data. The following parameters will be displayed in general client info: Example:
{
"name": "Name Surname",
"phone": "+7-999-999-99-99",
"email": "e@mail.com",
"customField":"customValue"
}
  • appMarker - App identifier. edna Android supports connecting several apps to the same server. For more details, refer to Appearance and Behavior Configuration). For that, you need to configure the identifier on the server and in the apps. Any unique string can be used as appMarkerappMarker must be the same for the corresponding Android and iOS apps.
  • clientIdEncrypted - Flag indicating that clientId is passed encrypted.

Client Logout

ThreadsLib.logoutClient(@NonNull final String clientId)

Use it for when the client logs out (i.e., when the backend stops trying to deliver messages for this client to the device).

  • clientId - Unique client ID

Tracking Number of Unread Messages

unreadMessagesCountListener - Listener of the number of unread messages

To subscribe to the changes in the number of unread messages, set a listener as follows:

ConfigBuilder.setUnreadMessagesCountListener(new ThreadsLib.UnreadMessagesCountListener() {
@Override
public void onUnreadMessagesCountChanged(int count) {
// Do the necessary actions
}
});

Setting Priority for Notification Channel

Starting with API 26, you can set a priority for the notification channel. For more details, refer here: https://developer.android.com/develop/ui/views/notifications/channels. In the library, you can configure them using the setNotificationImportance(NotificationManager.IMPORTANCE_...) method when configuring the builder:

ConfigBuilder(this).setNotificationImportance(NotificationManager.IMPORTANCE_HIGH)

Push Notifications Tap-Through and Integration of Several Chats in One App

pendingIntentCreator - creator of the push tap-through handler intent

If the user tapped the push notification of the library in the system notifications area, the main screen of the library - ChatActivity - will be opened. To change this behavior, you can configure the creation of your own PendingIntent.

To do this, use the ConfigBuilder.setPendingIntentCreator(ThreadsLib.PendingIntentCreator pendingIntentCreator) method in application of your application.

ConfigBuilder.setPendingIntentCreator(new ThreadsLib.PendingIntentCreator() {
@Override
public PendingIntent createPendingIntent(Context context, String appMarker) {
if (!TextUtils.isEmpty(appMarker)) {
//Start the appropriate chat according to appMarker
}
});

To integrate several chats in the same app, see the appMarker in the createPendingIntent app. Use it to specify which chat needs to be opened.

To implement a multi-chat, set clientId and appMarker before you launch the current chat. For example, for chat 1 to launch:

ThreadsLib.initUser(
new UserInfoBuilder(clientId1)
.setAppMarker(appMarker1)
)
//Configure design & behavior for chat 1

For chat 2 to launch:

ThreadsLib.initUser(
new UserInfoBuilder(clientId2)
.setAppMarker(appMarker2)
)
//Configure design & behavior for chat 2
caution

Important: clientId1 and clientid2 must be different. Currently, multi-chat with the same clientId is not supported out-of-the-box. However, implementing a multi-chat with one client is possible. To do this, contact your implementation manager.

Using Styles

ThreadsLib.applyChatStyle(ChatStyle chatStyle)

Use styles to customize the chat appearance. For more details, refer to Appearance and Behavior Configuration

Sending Messages

ThreadsLib.sendMessage(@Nullable String message, @Nullable File file)

Use it to send any message from on behalf of the client. At least one of the parameters - message или file - must not be null.

  • message - Message text
  • file - File

The default server settings allow you to send files up to 30 MB.

SSL Pinning

It allows you to use a specified list of certificates to check whether they match the certificates on the server.

danger

When utilizing this functionality, we do not recommend using only one certificate. If it is revoked or expired, SDK will stop connecting to the server. Use backup certificates and update them timely.

To enable SSL pinning, you need to:

  1. Place the public certificates in the res/raw folder.
  2. In the Application class in the ConfigBuilder initialization directory, add the list of certificates. For example:
.certificateRawResIds(Collections.singletonList(R.raw.crt));
  1. In the manifest, register the network config. For example:

android:networkSecurityConfig="@xml/network_security_config"

In the contents of the configuration file, you need to specify or add a network profile. For example:

<network-security-config> 
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">your_domain/</domain>
<trust-anchors>
<certificates src="@raw/crt"/>
</trust-anchors>
</domain-config>
</network-security-config>

Timeout Customization

For timeout customization of threads, to ConfigBuilder, the requestConfig(final RequestConfig requestConfig) method has been added.

RequestConfig contains the following fields with default settings:

  • socketClientSettings (type SocketClientSettings) - Socket connection settings 
  • picassoHttpClientSettings (type HttpClientSettings) - HTTP connection settings for the Picasso image download library 
  • authHttpClientSettings (type HttpClientSettings) - HTTP connection settings for authorization 
  • threadsApiHttpClientSettings (type HttpClientSettings) - HTTP connection settings for the Chat Center server API

SocketClientSettings contains the following:

  • resendIntervalMillis - Interval of the repeated attempt to send the message
  • resendPingIntervalMillis - Interval of requests to maintain an active connection (OkHttpClient.Builder().pingInterval())
  • connectTimeoutMillis - Timeout for establishing a new connection (OkHttpClient.Builder().connectTimeout())
  • readTimeoutMillis - Read operation timeout for a new connection (OkHttpClient.Builder().readTimeout())
  • writeTimeoutMillis - Timeout of write operations for a new connection (OkHttpClient.Builder().writeTimeout())

HttpClientSettings contains the following:

  • connectTimeoutMillis - Timeout for establishing a new connection (OkHttpClient.Builder().connectTimeout())
  • readTimeoutMillis - Read operation timeout for a new connection (OkHttpClient.Builder().readTimeout())
  • writeTimeoutMillis - Timeout of write operations for a new connection (OkHttpClient.Builder().writeTimeout())

The library allows you to use internal deeplinks. For example, if there is text in the following format is in the message:

earth://some.params?code={code}

And if you create Activity that will be launched by Аction.VIEW, then the specified activity will launch when the link is tapped. For that, specify filters for your activity:

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="earth"
android:host="*" />
</intent-filter>

Configuring Backup for App

The library uses the following setting:

<application  
android:fullBackupContent="@xml/backup_rules">
...
</application>

The contents of this file is as follows:

<full-backup-content>  
<exclude domain="sharedpref" path="im.threads.internal.utils.EncryptedPrefStore.xml"/>
</full-backup-content>

This entry is required so that encrypted SharedPreferences do not remain in the device's memory after the app is reinstalled. If you use your own fullBackupContent file, you need to add exclude that is defined on our side to your file and override the file with yours:

<application  
android:fullBackupContent="@xml/your_backup_rules"
tools:replace="android:fullBackupContent">
...
</application>

Other SDKs might use the android:fullBackupContent setting as well. In this case, you need to review which exceptions are registered in these SDKs and make a shared file. For example, Vungle and AppsFlyer have their own fullBackupContent settings. Their exceptions are documented as follows:

To merge their settings with the ones we have, the file should look as follows:

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
<exclude domain="sharedpref" path="appsflyer-data"/>
<exclude domain="file" path="vungle" />
<exclude domain="file" path="vungle_cache" />
<exclude domain="external" path="vungle_cache" />
<exclude domain="database" path="vungle_db" />
<exclude domain="sharedpref" path="com.vungle.sdk.xml" />
<exclude domain="sharedpref" path="im.threads.internal.utils.EncryptedPrefStore.xml"/>
</full-backup-content>

Logger

The library uses its own logger that supports recording to a file. It is disabled by default, meaning the logs will not be recorded to a file or to the console. To enable the logs in the library, you need to enable enableLogging in ConfigBuilder and pass the logger builder as follows:

val configBuilder = ConfigBuilder(this) // this - app context
.enableLogging(loggerConfig)
ConfigBuilder configBuilder = new ConfigBuilder(this) // this - app context
.enableLogging(loggerConfig)

To create a logger builder, you need to complete the following command:

LoggerConfig.Builder(this) // this - app context

To enable recording logs to a file, you need to enable this as a feature:

logToFile()

Then, you need to specify the log directory:

dir(File(this.filesDir, "logs"))

The logger supports two types of logging. It can be logging into either a single file or to several files, the name of which will be equal to the start time of the app session. For that, LoggerRetentionPolicy is used with the FILE_COUNT value used for sessions and TOTAL_SIZE used for recording into a single file. The logging method is specified as:

retentionPolicy(LoggerRetentionPolicy.TOTAL_SIZE)

If you used LoggerRetentionPolicy.TOTAL_SIZE, then, to limit the max size, specify the following:

maxTotalSize(N) // N - size in bytes

Also, in case with LoggerRetentionPolicy.TOTAL_SIZE, you can enter your own name for the file (by default, it will be the start time of the first session). For that, specify the following:

fileName("your_file_name")

If you used LoggerRetentionPolicy.FILE_COUNT, then, to limit the number of files, specify the following:

maxFileCount(N) // N - number of files

To define the minimum level for logs (default - LoggerLevel.VERBOSE), specify the following:

minLogLevel(logLevel) // logLevel - your minimum level for logs

At the end, you need to call build(). Configuration example:

val loggerConfig = LoggerConfig.Builder(this)
.logToFile()
.dir(File(this.filesDir, "logs"))
.retentionPolicy(LoggerRetentionPolicy.TOTAL_SIZE)
.maxTotalSize(5242880)
.build()
LoggerConfig loggerConfig = new LoggerConfig.Builder(this)
.logToFile()
.dir(File(this.filesDir, "logs"))
.retentionPolicy(LoggerRetentionPolicy.TOTAL_SIZE)
.maxTotalSize(5242880)
.build()