Интеграция в мобильные приложения Android (v3)
В данной статье представлена подробная инструкция по интеграции Webim Mobile SDK версии 3 в ваше Android-приложение.
Шаг 1. Установка библиотеки Webim Mobile SDK
-
Откройте файл
build.gradle
приложения (модуля). Укажите адрес репозитория и добавьте следующий код:repositories { mavenCentral() } dependencies { ... implementation 'ru.webim.sdk:webimclientsdkandroid:3.+' }
Для того, чтобы изменения применились, необходимо синхронизировать проект. Например, в Android Studio можно нажать Sync Now или выбрать в меню File → Sync Progect with Gradle Files. Дождитесь окончания синхронизации.
Если синхронизация завершилась успешно, при компиляции библиотека будет добавлена в проект автоматически. При ошибке компиляции, убедитесь что вы правильно указали репозиторий и зависимость и синхронизируйте проект снова.
-
Редактируйте файл
AndroidManifest.xml
. Необходимо добавить в Ваш манифест следующие элементы: в кореньmanifest
необходимо добавить разрешение:<uses -permission android:name="android.permission.INTERNET">
для хранения истории чата на устройстве следует добавить следующие зависимости:
<uses -permission android:name="android.permission.READ_EXTERNAL_STORAGE"> <uses -permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
при необходимости предотвращения перехода устройства в спящий режим для того, чтобы всегда получать сообщения из чата, добавляется следующая строка:
<uses -permission android:name="android.permission.WAKE_LOCK">
Шаг 2. Работа с Webim Mobile SDK
Работа с сессией
После внедрения зависимости в приложение необходимо создать сессию. Сессия в Webim Mobile SDK является отдельной сущностью от VisitSession
, которая реализуется на Webim Server.
Сессией называют сеанс, в течение которого приложение взаимодействует с сервисом. В текущей версии SDK он получает любую информацию от Webim Server только в рамках сессии. До её создания SDK не получит с сервера никакой информации.
Началом сессии считается выполнение метода resume()
, а завершением — выполнение метода destroy()
, либо аварийная остановка приложения.
Но для того, чтобы начать выполнять действия с сессией, необходимо сначала создать объект сессии.
-
Создание сессии. Объект сессии создаётся методом
newSessionBuilder
класса Webim, который возвращает объект класса-строителяSessionBuilder
(оба класса и их методы описаны в файлеWebim.java
). После задания всех необходимых параметров на созданном объектеSessionBuilder
вызывается методbuild()
, который возвращает объектWebimSession
. Пример использования (для Android):WebimSession webimSession = Webim.newSessionBuilder() .setAccountName(ACCOUNT_NAME) .setLocation(LOCATION_NAME) .build()
Поле
ACCOUNT_NAME
должно соответствовать имени аккаунта, если чат размещён в облачной конфигурации (на серверах Webim — см. Сетевые конфигурации сервиса Webim). Если же чат размещён на серверах заказчика, то вместо него должен быть указан полный URL (пример:https://chat.company.ru
).Поле
LOCATION_NAME
содержит наименование размещения. Если в нём указать несуществующее значение, то обращение будет в размещенииdefault
.Вызов метода
build()
завершает установку начальных параметров и создаёт сессию в приостановленном виде.Описание всех параметров, которые можно задать при создании сессии, а также ошибок, которые могут возникать в процессе, можно найти в справочнике. Обязательными из них являются только два – имя аккаунта и размещение.
Если заданы только имя аккаунта и размещение, сессия будет создана в неавторизованной зоне, тем не менее, это будет персональный чат.
-
Методы сессии. Ниже описаны базовые методы, которые необходимо вызывать при работе с объектом сессии.
Метод Описание Следующий метод resume
После создания объекта сессии необходимо вызвать метод resume()
, который запустит сессию. В результате ответа сервера стартует сетевая активность сессии в результате чего могут быть вызванные методыMessageListener
,ChatStateListener
,CurrentOperatorChangeListener
иLocationSettingsChangeListener
. Этот метод также используется для возобновления сессии после вызова методаpause()
.pause()
destroy()
destroyWithClearVisitorData()
pause()
Метод, который используется для приостановки сетевой активности сессии (например, когда пользователь не находится в активном окне приложения). Если сессия уже находится в приостановленном состоянии, метод не произведёт никаких действий. resume()
destroy()
destroyWithClearVisitorData()
destroy()
Метод, который используется для деактивации сессии и экземпляра класса. После вызова данного метода никакие методы, относящиеся к сессии, использованы быть не могут. destroyWithClearVisitorData()
Метод, который используется для деактивации сессии и экземпляра класса с удалением информации о пользователе. После вызова данного метода никакие методы, относящиеся к сессии, использованы быть не могут. Примеры использования:
public class MainActivity extends AppCompatActivity { private WebimSession session; private static final String ACCOUNT_NAME = "account"; private static final String LOCATION_NAME = "mobile"; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webimSession = Webim.newSessionBuilder() .setAccountName(ACCOUNT_NAME) .setLocation(LOCATION_NAME) .build() } protected void onStart() { super.onStart(); session.resume(); } protected void onResume() { super.onResume(); session.resume(); } protected void onPause() { super.onPause(); session.pause(); } protected void onDestroy() { session.destroy(); super.onDestroy(); } }
Установка интерфейсов и протоколов
Для функционирования приложения на базе SDK обязательна установка всех перечисленных ниже интерфейсов и протоколов. Для использования методов интерфейса необходимо, чтобы сессия не находилась в приостановленном или деактивированном виде.
-
MessageStream
необходим для непосредственного взаимодействия с сервисом Webim (например, для отправки или получения сообщений). Устанавливается путём вызова методаgetStream()
экземпляраWebimSession
. Примеры использования:-
Отправить сообщение
session.getStream().sendMessage(message);
-
Удалить сообщение
session.getStream().deleteMessage(message, callback);
-
Отследить изменения оператора текущего чата
session.getStream().setCurrentOperatorChangeListener( new MessageStream.CurrentOperatorChangeListener() { @Override public void onOperatorChanged(@Nullable Operator oldOperator, @Nullable Operator newOperator) { //your code } });
-
Отследить изменения статуса сессии
session.getStream().setVisitSessionStateListener( new MessageStream.VisitSessionStateListener() { @Override public void onStateChange(@NonNull MessageStream.VisitSessionState previousState, @NonNull MessageStream.VisitSessionState newState) { //your code } });
-
Отследить изменения состояния текущего чата
session.getStream().setChatStateListener( new MessageStream.ChatStateListener() { @Override public void onStateChange(@NonNull MessageStream.ChatState oldState, @NonNull MessageStream.ChatState newState) { //your code } });
Список всех методов, а так же более подробную информацию о них можно найти в описании метода
MessageStream
. -
-
MessageListener
необходим для получения изменений в потоке сообщений. Его методы вызываются автоматически при осуществлении действий с сообщениями в чате: при добавлении сообщения, удаления сообщения, удаления всех сообщений и изменении сообщения, соответственно. В пользовательском приложении необходим класс, который реализует методы данного интерфейса:messageAdded(Message, Message)
,messageRemoved(Message)
,allMessagesRemoved()
,messageChanged(Message, Message)
.Пример использования:
public class MainActivity extends AppCompatActivity { private WebimSession session; private ListController listController; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); webimSession = Webim.newSessionBuilder() .setAccountName(ACCOUNT_NAME) .setLocation(LOCATION_NAME) .build() initChatView(rootView); } private void initChatView(View rootView) { RecyclerView recyclerView = rootView.findViewById(R.id.chat_recycler_view); listController = ListController.install(this, recyclerView); } private static class ListController implements MessageListener { private static final int MESSAGES_PER_REQUEST = 25; private final RecyclerView recyclerView; private final MessagesAdapter adapter; static ListController install(WebimChatFragment webimChatFragment, RecyclerView recyclerView) { return new ListController(webimChatFragment, recyclerView); } private ListController(final WebimChatFragment webimChatFragment, final RecyclerView recyclerView) { this.recyclerView = recyclerView; this.adapter = new MessagesAdapter(webimChatFragment); this.recyclerView.setAdapter(this.adapter); } @Override public void messageAdded(@Nullable Message before, @NonNull Message message) { int index = (before == null) ? 0 : adapter.indexOf(before); if (index < = 0) { adapter.add(message); adapter.notifyItemInserted(0); } else { adapter.add(index, message); adapter.notifyItemInserted(adapter.getItemCount() - index - 1); } } @Override public void messageRemoved(@NonNull Message message) { int index = adapter.indexOf(message); if (index != -1) { adapter.remove(index); adapter.notifyItemRemoved(adapter.getItemCount() - index); } } @Override public void messageChanged(@NonNull Message from, @NonNull Message to) { int index = adapter.lastIndexOf(from); if (index != -1) { adapter.set(index, to); adapter.notifyItemChanged(adapter.getItemCount() - index - 1, 42); } } @Override public void allMessagesRemoved() { int size = adapter.getItemCount(); adapter.clear(); adapter.notifyItemRangeRemoved(0, size); } } }
Список всех методов, а также полную информацию о них можно найти в описании
MessageListener
. -
MessageTracker
необходим для получения истории сообщений, которая хранится на локальном устройстве. На сервере же история сообщений хранится без ограничений по времени. Объект классаMessageTracker
можно получить через методnewMessageTracker(MessageListener)
объектаMessageStream
:MessageTracker tracker = session.getStream.newMessageTracker(this);
Метод
newMessageTracker(MessageListener)
объектаMessageStream
создает объект классаMessageTracker
, с помощью которого можно управлять потоком сообщений в контексте приложения клиента. Для получения последних сообщений из истории можно использовать методgetLastMessages(int limit, GetMessagesCallback callback)
, но не больше указанного лимита.Пример использования метода:
int MESSAGES_PER_REQUEST = 25; tracker.getLastMessages(MESSAGES_PER_REQUEST, new MessageTracker.GetMessagesCallback() { @Override public void receive(@NonNull final List< ? extends Message> received) { //your code } });
Для дальнейшей итерации по истории сообщений вызывается метод
getNextMessages(int limit, GetMessagesCallback)
— он запрашивает определенное количество сообщений из истории.Пример использования метода:
int MESSAGES_PER_REQUEST = 25; tracker.getNextMessages(MESSAGES_PER_REQUEST, new MessageTracker.GetMessagesCallback() { @Override public void receive(@NonNull final List< ? extends Message> received) { //your code } });
Message
необходим для хранения информации о сообщениях. С помощью методов экземпляров классаMessage
можно получить все необходимые данные о конкретном сообщении: уникальный номер сообщение (методgetId()
), текст сообщения (методgetText()
), информацию о вложенном файле (методgetAttachment()
) и т.д. Методы интерфейсаMessageListener
оперируют объектами классаMessage
. Все связанные с этим классом инструменты (методы для работы с вложениями, типы сообщений и пр.) описаны здесь.Подробное описание этих и других методов можно найти в справочниках методов для iOS и для Android.
Шаг 3. Прочие Настройки
Кроме установки перечисленных ранее интерфейсов для корректной работы приложения на базе Webim Mobile SDK необходимо произвести ряд настроек в коде приложения.
-
Необходимо правильно настроить процедуру подсчёта
visitor fields
иhash
. Приватный ключ аккаунта не должен храниться на устройстве или где бы то ни было, кроме сервера заказчика. В противном случае появляется серьёзная угроза безопасности и риск утечки переписок клиента третьим лицам.Пример передачи
json-encoded
объекта посетителя SDK:.setVisitorFieldsJson("{ "id":"1234567890987654321", "display_name":"Никита", "hash":"ffadeb6aa3c788200824e311b9aa44cb" }")
Подробно об идентификации авторизованных клиентов можно почитать в этой статье.
-
Для приложения на базе SDK может быть использован обфускатор. В этом случае необходимо задавать исключения в правилах обфускатора, чтобы определённые классы не обфусцировались — это необходимо для корректной работы приложения на базе Webim Mobile SDK. В частности, при использовании обфускатора Proguard следует задать в его правилах следующее:
-keep public class ru.webim.android.sdk.* { *; }
Это будет означать, что указанный пакет/класс не будет "шифроваться" обфускатором.
-
Обеспечить необходимые сетевые доступы.
Для мобильного устройства, на котором установлено мобильное приложение, интегрированное с Webim Mobile SDK, должны быть открыты исходящие порты для следующих URL-адресов:
-
https://*.webim.ru/l/v/m/action 443 (POST)
- используется для передачи действий от клиентов. -
https://*.webim.ru/l/v/m/delta 443 (GET)
- используется для получения инкрементальных обновлений. -
https://*.webim.ru/l/v/m/download 443 (GET)
(не используется в SDK, но нужно для скачивания файлов в мобильном приложении) -
https://*.webim.ru/l/v/m/upload 443 (POST)
- используется для отправки файлов с клиента на сервер. -
https://*.webim.ru/l/v/m/history 443 (GET)
- используется для получения истории чата из базы данных.
Для отправки push-уведомлений должны быть открыты следующие порты:
-
FCM:
5228-5230 TCP
, см. https://firebase.google.com/docs/cloud-messaging/concept-options -
APNs:
443, 2197, 5223 TCP
, см. https://support.apple.com/en-us/HT203609
Если чат размещён на серверах заказчика, то домен должен быть изменен на их собственный.
-
-
Для того, чтобы после завершения чата пользователь мог поставить оценку работы оператора, необходимо описать соответствующий механизм в приложении. SDK не реализует механизм оценки, а получает её от приложения клиента.
-
Включены и настроены push-уведомления (опционально). Подробнее параметры push-уведомлений и примеры можно посмотреть в статье Push-уведомления.
-
Для начала чата может вызываться метод
startChat()
. Если метод не будет вызван, чат будет начат после первого сообщения посетителя.