Перейти к содержанию

Интеграция в мобильные приложения Android (v2)

Библиотека Webim Mobile SDK 2.0 предоставляет разработчикам мобильных приложений на платформе Google Android средства для встраивания в эти приложения чата между их пользователями и операторами компании-разработчика на основе технологий, применяющихся в сервисе Webim.

N.B.

Поддерживается с версии Android 4.+ (Android API 15+)

Внимание!

Данная версия SDK устарела. Техническая поддержка клиентов, использующих эту версию SDK, более не осуществляется!

Пример приложения: WebimClient

Нами предлагается пример приложения, написанный на Java с использованием библиотеки Webim Mobile SDK для Android. Это приложение позволяет открыть чат между пользователем телефона и оператором.

Тестовое приложение (код на GitHub)

Скачать тестовое приложение c Google Play

Адрес административного раздела — https://demo.webim.ru. Приложение работает под учётной записью demo.


Инструкция по добавлению Webim Mobile SDK в проект Android

Чтобы подключить библиотеку Webim Mobile SDK в проект на платформе Google Android, выполните следующие шаги:

  1. Подключите проект библиотеки в файле build.gradle в разделе dependencies:

    compile 'com.webim.sdk:webimclientsdkandroid:2.+'
    
    2. Добавить необходимые для работы SDK permissions:

    uses-permission android:name="android.permission.INTERNET"
    uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
    
  2. На экране чата внизу разместите надпись "Предоставлено: webim.ru", где webim.ru подчёркнуто и является кликабельной ссылкой на сайт Webim.

    Пример подобного использования см. в тестовом приложении WebimClient.


Структура

Webim Mobile SDK предоставляют простой и удобный интерфейс для работы с сервисом Webim. Она осуществляется через класс WMSession, который через механизм делегирования оповещает об изменении состояния чата. Для того чтобы начать работать с чатом, необходимо инициализировать объект WMSession и выставить ему делегата. Делегат будет управлять отображаемыми видами и следить за изменением состояния сессии. Делегат должен следовать интерфейсу WMSessionDelegate. Кроме выбора делегата необходимо определиться с размещением и учётной записью в сервисе Webim. Объект WMSession работает только с одним выбранным размещением.

Конструкторы WMSession выглядят следующим образом:

WMSession(Context context, String serverName, String location, WMSessionDelegate delegate);


WMSession(Context context, String serverName, String location, WMSessionDelegate delegate, WMVisitorExt visitorFields);

serverName может быть задано в виде имени аккаунта или же полноценной ссылкой на сервер (demo или https://demo.webim.ru или кастомный домен https://test.mywebimserver.com) Расширенная версия конструктора принимает в себя объект WMVisitorExp, который описывает характеристики текущего пользователя приложения.

Подробнее о идентификации посетителей можно прочитать по данной ссылке.


Начало работы

Для начала работы чата с сервером необходимо запустить сессию методом:

session.startSession(); *
1 При успешном старте сессии на WMSessionDelegate вызовется метод, в котором будет содержаться объект, характеризующий сессию (sessionItem):

void sessionDidReceiveFullUpdate(WMSession session);
Объект сессии содержит в себе все внутренние данные, такие как: состояние, чат, оператор. После первого вызова этого метода можно анализировать состояние сессии и работать с чатом.

При изменении состояния сессии на делегате WMSessionDelegate вызовется метод

void sessionDidChangeSessionStatus(WMSession session);
Состояний сессии может быть несколько:

enum WMSessionState{WMSessionStateUnknown,WMSessionStateIdle,WMSessionStateIdleAfterChat, WMSessionStateChat, WMSessionStateOfflineMessage; }

Для использования интересно только одно состояние сессии: WMSessionStateOfflineMessage - выставление состояния сессии в этот флаг означает, что не осталось онлайн операторов и чат будет завершен.


Вызов чата

При первом запуске приложения чат скорее всего не будет инициализирован, то есть session.getChat() == null или session.hasChat() == false. В случае его появления (начала диалога со стороны оператора или посетителя) он автоматически добавится в объект сессии (или же удалится после закрытия пользователем и оператором). При повторной инициализации чат уже (ещё) может существовать, если это так, то необходимо отобразить этот чат. Он уже будет содержать сообщения. Объект чата имеет несколько состояний, которые важны для определения необходимости отображать этот чат пользователю.

enum WMChatState {
WMChatStateUnknown,
WMChatStateQueue,
WMChatStateChatting,
WMChatStateClosed,
WMChatStateClosedByVisitor,
WMChatStateClosedByOperator,
WMChatStateInvitation; }

Если чат существует и находится в одном из состояний WMChatStateInvitation, WMChatStateQueue, WMChatStateChatting или WMChatStateClosedByOperator, то его необходимо отобразить пользователю.

Если на делегате вызывается один из методов об изменении чата, то при изменении состояния на любое другое - чат должен закрыться. Обращения к такому чату (посылка сообщений, закрытие) будут возвращать ошибку. Перед началом чата необходимо убедиться в наличии операторов онлайн. Это можно узнать, вызвав метод WMSessionOnlineStatus session.getOnlineStatus().

enum WMSessionOnlineStatus {
WMSessionOnlineStatusUnknown("unknown"),
WMSessionOnlineStatusOnline("online"),
WMSessionOnlineStatusBusyOnline("busy_online"),
WMSessionOnlineStatusOffline("offline"),
WMSessionOnlineStatusBusyOffline("busy_offline"); }

Если чат не существует, то его можно инициировать методом сессии:

session.startChat();

Если вызов этого метода будет удачным, то на делегате вызовется метод:

void sessionDidStartChat(WMSession session, WMChat chat);

или

sessionDidChangeChatStatus(WMSession session)
если чат уже был, и у него сменилось состояние.


Использование чата

Для закрытия чата вызывается метод:

session.closeChat();

Инициированный чат содержит в себе массив сообщений, принадлежащих этому чату. Каждое из сообщений имеет тип, описанный в классе WMMessage. Для отправки сообщения от пользователя необходимо вызвать метод у сессии:

public String sendMessage(String message, final OnMessageSendListener listener)

где message - переменная типа String с сообщением. OnMessageSendListener вызывается сразу после ответа сервера и содержит два метода обратного вызова (callback):

  1. оnSuccess(String clientSideId) — означает успешную отправку

  2. onFailure(String clientSideId, WMSessionError error) — сигнализирующий об ошибке во время отправки сообщения.

Также можно отправить в чат файл, вызвав метод:

public String sendFile(InputStream fileData, String name, String mimeType, final OnFileUploadListener listener)

OnFileUploadListener вызывается сразу после ответа сервера и содержит два метода обратного вызова (callback):

  1. оnSuccess(String clientSideId) — означает успешную отправку

  2. onFailure(String clientSideId, WMSessionError error) — сигнализирующий об ошибке во время отправки сообщения.

Опционально оба метода принимают и возвращают clientSideId по которому можно отслеживать статус доставки сообщения. Реакцией на успешную доставку сообщения, так же как и на появления системного или операторского сообщения будет вызов на делегате метода:

void sessionDidReceiveMessage(WMSession session, WMMessage message);

Для сообщений типа WMMessageKindFileFromOperator можно загрузить (открыть в браузере) соответствующий файл по ссылке, хранящейся в поле param. Для получения ссылки, у объекта WMMessage есть специальное поле, а также ссылка на параметры фаила (WMFileParams). Для других типов сообщений эти поля — null. Кроме того в объекте WMMessage содержатся данные об отправителе (пока что актуально только для сообщений оператора). Для получения имени отправителя у обьекта WMMessage присутствует метод

public String getSenderName() Для получения ID отправителя можно вызвать метод у объекта сообщения:

public String getSenderId()

Для того, что бы получить ссылку на фото профиля отправителя необходимо вызвать статический метод у классса WMSession, передав туда объект сообщения и строки ServerUrl из объекта WMSession:

public static String getSenderAvatarUrl(WMMessage messageItem, String serverUrl)

Также существует способ оценить оператора, вызвав у сессии метод

session.rateOperator(String senderId, WMOperatorRate rate, OnRateOperationListener listener)

где senderId — значение ID оператора, которое можно получить из отправленного им сообщения (см. выше), rate - enum с возможными значениями оценки:

WMOperatorRateOneStar(-2),
WMOperatorRateTwoStars(-1),
WMOperatorRateThreeStars(0),
WMOperatorRateFourStars(1),
WMOperatorRateFiveStars(2);

Пример подобного использования см. в тестовом приложении WebimClient. Для отправки файла оператору можно вызвать метод у сессии:

session.sendFile(InputStream imageData, String name, String mimeType, final OnFileUploadListener listener);

Если объект чата инициализирован, то он может содержать ссылку на объект оператора. В случае, если оператор меняется или берёт посетителя в обработку, на делегате WMSessionDelegate вызывается метод

void sessionDidUpdateOperator(WMSession session, WMOperator chatOperator);

По объекту WMOperator можно определить имя оператора и путь для загрузки его аватара. Для отправки статуса набора текста (а также текста для функции "шпион") у объекта сессии необходимо вызвать метод:

session.setComposingMessage(boolean isComposing, String draftMessage)

Метод содержит защиту от частых вызовов и срабатывает с задержкой в 2 секунды при последующем вызове, если ещё не был осуществлён текущий. Не забудьте сбросить флаг после того, как пользователь перестанет вводить текст.

Пример подобного использования см. в тестовом приложении WebimClient.

В случае, если оператор начинает или перестает набирать текст, на делегате WMSessionDelegate вызывается метод:

void sessionDidChangeOperatorTyping(WMSession session, boolean isTyping);

При необходимости обновить чат, у сессии можно вызвать метод:

session.refreshSessionWithCompletionBlock(WMRefreshFinishDelegate delegate);

Который принимает параметром делегат WMRefreshFinishDelegate, который исполнится после выполнения запроса обновления. Для отслеживания ошибок при работе с чатом на делегате WMSessionDelegate вызывается метод:

void sessionDidReceiveError(WMSession session, WMSessionError errorID);

который возвращает номер ошибки из перечисления WMSessionError.

Если на устройстве нет сети, то при вызове методов API на делегат будет возвращаться константа WMSessionErrorNetworkError. При смене режимов работы сети библиотека сама возобновляет соединение с сервером. При этом на делегате будет вызываться метод:

void sessionDidChangeConnectionStatus(WMSession session, WMSessionConnectionStatus status);

Ожидаемая реакция приложения на переключение статуса сети - оповещение пользователя и, по необходимости, либо ограничение доступа к чату (вид, блокирующий деятельность), либо перехват соответствующих методов для дальнейшего восстановления данных. Для остановки общения с сервером и сервисом Webim необходимо вызвать метод

session.stopSession();

Другой способ — при выходе вызывать метод

session.fullUpdate();

который загрузит с сервера самые актуальные данные. 1

Кроме того, вызов метода session.stopSession() позволит сэкономить время жизни батареи, так как в этом случае SDK прекращает общение с сервисом Webim.


Работа с push-уведомлениями

Для получения push-уведомлений от сервиса Webim пользователю Webim Mobile SDK необходимо реализовать в своем приложении базовую поимку push-уведомлений (не забудьте про uses-permission). Далее, при получении push-уведомления рекомендуется проверить, совпадает ли оправитель с вашим SENDER_ID. Если нет, то скорее всего это push-уведомление принадлежит сервису Webim, и его необходимо передать для обработки в статичный метод класса WMSession:

public static void onPushMessage(Context context, Bundle pushData, Class<? extends Activity> clazz)

где Class<? extends Activity> clazz - класс, который должен быть открыт при открытии push-уведомления. Также есть возможность самостоятельно обработать push-уведомления:

public static PushNotificationModel getPushNotificationModel(Bundle pushData) throws JsonSyntaxException

где PushNotificationModel содержит в себе данные о типе push-уведомления (сообщение/файл/системное уведомление) и о необходимом действии (спрятать/показать).

Пример обработки из тестового приложения представлен ниже.

Bundle extras = intent.getExtras();
String senderId = intent.getStringExtra("from");
if (!senderId.equals("YOUR_SENDER_ID")) {
if(WebimSDKApplication.isInBackground()) {
//Webim push logic
WMSession.onPushMessage(this.getApplicationContext(), extras, MainActivity.class);
}
} else {
// Your app push logic
}

Пример подобного использования см. в тестовом приложении WebimClient.

Также, начиная с версии 2.2.7 у онлайн сесcии появилась возможность запрашивать историю сообщений для текущего пользователя (без локального сохранения).

Подробнее про метод запроса истории можно узнать в разделе Оффлайн-обращения.


Оффлайн-обращения

Обращения к оператору могут происходить в режиме "оффлайн". В этом режиме задержка ответа не критична, но важно время хранения и способ обращения с чатами на стороне сервера. За работу с таким типом чатов отвечает класс SDK WMOfflineSession. Как и для обычных чатов, необходимо инициализировать его перед вызовом любых других методов работы с классом. Важно отметить, что в случае использования обеих сессий сразу пользователь должен инициализировать их последовательно, например, дожидаясь успешного старта онлайн сессии, или использовав специальный конструктор онлайн-сессии, который содержит слушателя на получение push-token (после его успешного вызова можно однозначно сказать, что онлайн-сессия готова к использованию, и можно инициализировать оффлайн).

WMOfflineSession(Context context, String accountName, String location, String token, String platform, boolean enableLogging) При использовании стандартного механизма push-уведомлений. Параметр token может быть null (или же вовсе не использоваться). Свяжитесь со службой поддержки для получения более подробной информации об специальном механизме отправки push-уведомлений. Параметр platform, если установлен, используется для определения сервером механизма отсылки уведомлений - использование пользовательского сервера или стандартного механизма push-уведомлений. Для использования этого параметра необходимо связаться со службой поддержки Webim. Флаг enableLogging используется для отладки приложения и позволяет скрыть все записи о работе SDK в журнале LogCat при завершении разработки. Данные о чатах хранятся в памяти и доступны через метод класса:

public List getOfflineChats()

Возвращаемый список хранит объекты типа WMChat. Каждый чат имеет ссылку на относящиеся к нему сообщения. В общем случае чаты и сообщения отсортированы по дате создания. Также, для уменьшения трафика, SDK сохраняют свое состояние в файле на диске. Предполагается, что клиентское приложение будет периодически опрашивать сервер на предмет появления новых сообщений в чатах. Это осуществляется методом класса WMOfflineMessage:

public void getHistoryForced(boolean forced, OnHistoryResponceListener listener)

Флаг forced заставляет SDK заново запросить всю историю. Не рекомендуется злоупотреблять этим флагом из-за увеличения трафика. OnHistoryResponceListener вызывается при завершении запроса. Здесь и далее используется Listener, вызываемый при завершении запроса. Он имеет следующую структуру:

  • флаг, сигнализирующий успех запроса;

  • один или несколько объектов, значения которых имеют значение при успешном завершении метода;

  • объект ошибки, являющийся действительным (valid) только при неуспешном завершении метода. Ошибка может быть нескольких типов - ошибки домена Webim определяются константой WMWebimErrorDomain. В случае такой ошибки имеет место её код — он будет одним из перечисления WMSessionError из класса WMBaseSession.

Возвращаясь к методу запроса истории: объект WMHistoryChanges в OnHistoryResponceListener содержит в себе информацию о модификациях с предыдущего запроса. Извлечь эти данные можно при помощи публичных методов объекта:

public List getNewChats()
public List getModifiedChats()
public List getMessages()

С помощью возвращаемых списков можно определить, какие чаты были добавлены, изменены и какие сообщения были добавлены в эти чаты. Для связи объектов WMMessage и WMChat можно использовать метод класса WMOfflineSession

public WMChat chatForMessage(WMMessage message)

Для создания нового чата и отправки сообщений в существующем со стороны клиента используется следующий метод:

public void sendMessage(String message, WMChat chat, String subject, String department, OnMessageSendListener listener)
  • Параметр message является обязательным.

  • Если параметр chat является пустым (передается null), то метод создаёт новый чат с одним новым сообщением. Если параметр chat передан, то создастся новое сообщение в этом чате.

  • Параметр subject задаёт тему обращения для нового чата, может быть пустым.

  • Параметр department назначает отдел новому чату, может быть пустым.

OnMessageSendListener вызывается сразу после ответа сервера и содержит объекты WMChat и WMMessage — новые объекты сообщения и чата, если было запрошено создание нового чата. Аналогично работает метод отправки изображения:

public void sendFile(InputStream imageData, String nameWithExtension, String mimeType, final WMChat chat, String subject, String department, final OnMessageSendListener listener)

Сообщения WMMessage, созданные данным методом будут иметь тип WMMessageKindFileFromVisitor. Такие сообщения в поле text содержат имя файла. Также в объекте присутствуют специальные поля содержащие в себе ссылку на файл, ссылку на предпросмотр, а также параметры файла (WMFileParams). SDK хранит прикреплённые к чату изображения до успешной отправки данных на сервер. Управление загрузкой и отображением файла целиком ложится на пользовательское приложение. При появлении в истории ответа от оператора, соответствующий чат помечается как непрочитанный. Поэтому, после отображения чата пользователю необходимо пометить его прочитанным методом класса сессии:

public void markChatAsRead(WMChat chat, OnChangeReadedByVisitorListener listener)
Удаление чата осуществляется с помощью методов:

public void deleteChat(WMChat chat, OnChatDeletedListener listener)

и

public void deleteChats(Collection chats, final OnChatDeletedListener listener)
SDK способно работать без подключения к сети (сообщения и изображения будут храниться локально, до момента отправки их на сервер Webim). Для отправки неотправленных данных существует метод:

public void sendUnsentRequests(OnSyncListener listener)

Метод сначала отправляет запросы на удаление удалённых оффлайн-чатов с сервера, затем отправляет сообщения и картинки, попутно создавая для них чаты, если необходимо.

Интерфейс OnSyncListener содержит 2 метода (см ниже). Первый срабатывает при отправке неотправленного сообщения на сервер. Второй информирует пользователя SDK о смене ID локального(созданного в оффлайн) чата, на тот, что был присвоен чату на сервере Webim.

public void onMessageSend(boolean successful, WMChat chat, WMMessage message, WMSessionError error)
public void onChatIdChanged(String oldChatId, String newChatId);

Для достижения большей гибкости в архитектуре приложения использующего Webim SDK, были добавлены синхронные аналоги основных методов-действий:

public WMHistoryChanges getHistoryForcedSync(boolean forced) throws WMExeption
public WMMessage sendMessageSync(String message, WMChat chat, String subject, String department) throws WMExeption
public WMMessage sendFileSync(InputStream imageData, String nameWithExtension, String mimeType, final WMChat chat, String subject, String department) throws WMException

Методы могут работать в любом потоке, кроме главного. Исключение WMExeption содержит публичный метод

public WMBaseSession.WMSessionError getError()

возвращающий перечисление WMSessionError из класса WMBaseSession, и выбрасывается в случае возникновения одной из ошибок аналогичной асинхронным методам.

Для принудительного удаления всех данных, относящихся к работе SDK с устройства, существует метод в WMOfflineSession:

public void clearCachedUserData()

С его помощью можно сменить "текущего пользователя чата". В текущей реализации активной может быть только одна сессия, поэтому для того чтобы получить данные другого пользователя необходимо:

  1. Перестать запрашивать историю для сессии А

  2. Cделать очистку данных (метод clearCachedUserData у объекта WMSession сессии А)

  3. Создать сессию В с другими желаемыми параметрами.


  1. Для успешной и эффективной работы с сервисом Webim рекомендуется начинать и прекращать работу с сервером в методах onStart() и onStop() класса Activity соответственно (или при подключении и отключении к Service, как в тестовом приложении). Этим вы обеспечите себя самой актуальной информацией при обращении к сервису Webim