Source: https://rox.chat/kb/pt/mobile/sdk/android-integration.html

> Este artigo fornece instruções detalhadas sobre como integrar o Rox.Chat Mobile SDK em seu aplicativo Android.

# Integração em aplicativos móveis Android

Este artigo fornece instruções detalhadas sobre como integrar o **Rox.Chat Mobile SDK** em seu aplicativo Android.

## Etapa 1: instalar a biblioteca do Rox.Chat Mobile SDK

  1. Abra o arquivo `build.gradle` do aplicativo (módulo).
    Especifique o endereço do repositório e adicione o seguinte código:

    ```
    repositórios {
        mavenCentral()
    }

    dependências {
        ...
        implementação 'com.roxchat.sdk:roxclientsdkandroid:3.+'
    }
    ```

    Para que as alterações sejam aplicadas, você precisa sincronizar o projeto.
    Por exemplo, no **Android Studio**, você pode clicar em **Sync Now** ou selecionar **File → Sync Progect with Gradle Files** no menu. Aguarde a conclusão da sincronização.

    Se a sincronização for bem-sucedida, a biblioteca será adicionada ao projeto automaticamente durante a compilação. Se a compilação falhar, verifique se você especificou o repositório e a dependência corretos e sincronize o projeto novamente.

  1. Edite o arquivo `AndroidManifest.xml`.
    Você precisa adicionar os seguintes itens ao seu manifesto:
    Na raiz do `manifest`, você precisa adicionar a permissão:

    ```
    <uses -permission android:name="android.permission.INTERNET">
    ```

    As seguintes dependências devem ser adicionadas para armazenar o histórico de bate-papo em seu dispositivo:

    ```
    <uses -permission android:name="android.permission.READ_EXTERNAL_STORAGE">
    <uses -permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
    ```

    Se for necessário evitar que o dispositivo entre em modo de suspensão para receber sempre mensagens do bate-papo, a seguinte linha será adicionada:

    ```
    <uses -permission android:name="android.permission.WAKE_LOCK">
    ```

---

## Etapa 2. Trabalhar com o Rox.Chat Mobile SDK

### Trabalhar com a sessão

Depois de implementar a dependência no aplicativo, você precisa criar uma sessão. Uma sessão no **Rox.Chat Mobile SDK** é uma entidade separada da `VisitSession`, que é implementada no **Rox.Chat Server**.

Uma sessão é uma sessão durante a qual um aplicativo interage com um serviço. Na versão atual do SDK, ele recebe qualquer informação do **Rox.Chat Server** somente dentro de uma sessão. Antes de sua criação, o SDK não receberá nenhuma informação do servidor.
A sessão é iniciada com a execução do método `resume()` e encerrada com a execução do método `destroy()` ou com o encerramento do aplicativo.

Mas, para começar a executar ações em uma sessão, você deve primeiro criar um objeto de sessão.

  1. **Criação de uma sessão**. O objeto de sessão é criado pelo método `newSessionBuilder` da classe **Rox**, que retorna um objeto da classe construtora `SessionBuilder` (ambas as classes e seus métodos estão descritos no arquivo `Rox.java`). Depois de definir todos os parâmetros necessários no objeto `SessionBuilder` criado, o método `build()` é chamado, o que retorna um objeto `RoxSession`. Exemplo de uso (para Android):

    ```
    RoxSession roxChatSession = Rox.newSessionBuilder()
        .setAccountName(ACCOUNT_NAME)
        .setLocation(LOCATION_NAME)
        .build()
    ```

    O campo `ACCOUNT_NAME` deve corresponder ao nome da conta se o chat estiver hospedado em uma configuração de nuvem (em servidores **Rox.Chat** - consulte Configurações de rede do serviço Rox). Se o chat estiver hospedado nos servidores do cliente, a URL completa deverá ser especificada em vez disso (exemplo: `https://chat.company.ru`).

    O campo `LOCATION_NAME` contém o nome do posicionamento. Se você especificar um valor inexistente nesse campo, a invocação será feita no posicionamento `default`.

    A chamada do método `build()` conclui a configuração dos parâmetros iniciais e cria a sessão em formato suspenso.

    Uma descrição de todos os parâmetros que podem ser definidos ao criar uma sessão, bem como os erros que podem ocorrer durante o processo, podem ser encontrados em [reference](https://rox.chat/kb/pt/mobile/sdk/android-sdk-handbook.html#session-builder). Apenas dois deles são obrigatórios: nome da conta e posicionamento.

    Se apenas o nome da conta e o local forem definidos, a sessão será criada em uma área não autorizada, mas será um bate-papo pessoal.

  1. **Métodos de sessão**. Abaixo estão os métodos básicos que precisam ser salvos ao trabalhar com um objeto de sessão.

  | Método                                                                                                                                                                                                                                                                                                                                                                                                             | Descrição                                                                                                                                                                                                                             | Próximo método                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| Depois que o objeto de sessão é criado, o método `resume()` deve ser chamado para iniciar a sessão. Como resultado da resposta do servidor, a atividade de rede da sessão é iniciada, o que pode acionar os métodos `MessageListener`, `ChatStateListener`, `CurrentOperatorChangeListener` e `LocationSettingsChangeListener`. Este método também é usado para retomar uma sessão após chamar o método `pause()`. | `pause()`<br>`destroy()`<br>`destroyWithClearVisitorData()`                                                                                                                                                                           |
| `pause()`                                                                                                                                                                                                                                                                                                                                                                                                          | Um método que é usado para suspender a atividade de rede de uma sessão (por exemplo, quando o usuário não está em uma janela de aplicativo ativa). Se a sessão já estiver em um estado suspenso, o método não executará nenhuma ação. | `resume()`<br>`destroy()`<br>`destroyWithClearVisitorData()`                   |
| `destroy()`                                                                                                                                                                                                                                                                                                                                                                                                        | Um método que é usado para desativar a sessão e a instância da classe.                                                                                                                                                                | Nenhum método relacionado à sessão pode ser usado após a chamada desse método. |
| `destroyWithClearVisitorData()`                                                                                                                                                                                                                                                                                                                                                                                    | Um método que é usado para desativar a sessão e a instância da classe com as informações do usuário removidas.                                                                                                                        | Nenhum método relacionado à sessão pode ser usado após a chamada desse método. |

    Exemplos de uso:

    ```
    public class MainActivity extends AppCompatActivity {
      private RoxSession session;
      private static final String ACCOUNT_NAME = "conta";
      private static final String LOCATION_NAME = "mobile";
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          roxChatSession = Rox.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();
      }
    }
    ```

---

### Instalação de interfaces e protocolos

Todas as interfaces e protocolos a seguir devem ser instalados para que um aplicativo baseado em SDK funcione. Para usar os métodos de interface, é necessário que a sessão não esteja em estado suspenso ou desativado.

  1. O `MessageStream` é necessário para a interação direta com o serviço **Rox.Chat** (por exemplo, para enviar ou receber mensagens). Ele é definido chamando o método `getStream()` da instância `RoxSession`. Exemplos de uso:

    * Enviar uma mensagem

        ```  
        session.getStream().sendMessage(message);
        ```

    * Excluir mensagem

        ```
        session.getStream().deleteMessage(message, callback);
        ```

    * Rastrear alterações no operador de chat atual

        ```
        session.getStream().setCurrentOperatorChangeListener(
                novo MessageStream.CurrentOperatorChangeListener() {
                @Override
                public void onOperatorChanged(@Nullable Operator oldOperator,
                                        @Nullable Operator newOperator) {
        //seu código
               }
           });
        ```

    * Rastrear alterações no status da sessão

        ```
        session.getStream().setVisitSessionStateListener(
                novo MessageStream.VisitSessionStateListener() {
                @Override
                public void onStateChange(@NonNull MessageStream.VisitSessionState previousState,
                                        @NonNull MessageStream.VisitSessionState newState) {
        //seu código
                }
            });
        ```

    * Rastreie as alterações no estado atual do chat

        ```
        session.getStream().setChatStateListener(
                novo MessageStream.ChatStateListener() {
                @Override
                public void onStateChange(@NonNull MessageStream.ChatState oldState,
                                        @NonNull MessageStream.ChatState newState) {
        //seu código
                }
            });
        ```

    A lista de todos os métodos, bem como informações mais detalhadas sobre eles, pode ser encontrada na descrição do método [`MessageStream`](https://rox.chat/kb/pt/mobile/sdk/android-sdk-handbook.html#message-stream).

  1. O `MessageListener` é necessário para receber alterações no fluxo de mensagens. Seus métodos são chamados automaticamente ao executar ações em mensagens na sala de bate-papo: ao adicionar uma mensagem, excluir uma mensagem, excluir todas as mensagens e modificar uma mensagem, respectivamente. Em um aplicativo de usuário, você precisa de uma classe que implemente os métodos dessa interface: `messageAdded(Message, Message)`, `messageRemoved(Message)`, `allMessagesRemoved()`, `messageChanged(Message, Message)`.

    Exemplo de uso:

    ```
    public class MainActivity extends AppCompatActivity {
        private RoxSession session;
        ListController listController privado;
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            roxChatSession = Rox.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;
            adaptador final privado MessagesAdapter;
            static ListController install(RoxChatFragment roxChatChatFragment,
                                          RecyclerView recyclerView) {
                return new ListController(roxChatChatFragment, recyclerView);
            }
            private ListController(final RoxChatFragment roxChatChatFragment,
                                   final RecyclerView recyclerView) {
                this.recyclerView = recyclerView;
                this.adapter = new MessagesAdapter(roxChatChatFragment);
                this.recyclerView.setAdapter(this.adapter);
            }
            @Override
            public void messageAdded(@Nullable Message before, @NonNull Message message) {
                int index = (before == null) ? 0 : adapter.indexOf(before);
                Se (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);
                se (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);
                se (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);
            }
        }
    }
    ```

    Uma lista de todos os métodos, bem como informações completas sobre eles, pode ser encontrada na descrição de [`MessageListener`](https://rox.chat/kb/pt/mobile/sdk/android-sdk-handbook.html#message-listener).

      1. O `MessageTracker` é necessário para recuperar o histórico de mensagens, que é armazenado no dispositivo local. No servidor, o histórico de mensagens é armazenado sem limitação de tempo. O objeto da classe `MessageTracker` pode ser recuperado por meio do método `newMessageTracker(MessageListener)` do objeto `MessageStream`:

        ```
        MessageTracker tracker = session.getStream.newMessageTracker(this);
        ```

        O método `newMessageTracker(MessageListener)` do objeto `MessageStream` cria um objeto da classe `MessageTracker`, que pode ser usado para controlar o fluxo de mensagens no contexto de um aplicativo cliente. Você pode usar o método `getLastMessages(int limit, GetMessagesCallback callback)` para recuperar as mensagens mais recentes do histórico, mas não mais do que o limite especificado.

        Exemplo de uso do método:

        ```
        int MESSAGES_PER_REQUEST = 25;
        tracker.getLastMessages(MESSAGES_PER_REQUEST, new MessageTracker.GetMessagesCallback() {
                        @Override
                        public void receive(@NonNull final List< ? extends Message> received) {
                            //seu código
                        }
                    });
        ```

        Para iterar ainda mais o histórico de mensagens, o método `getNextMessages(int limit, GetMessagesCallback)` é chamado - ele solicita um determinado número de mensagens do histórico.

        Exemplo de uso do método:

        ```
        int MESSAGES_PER_REQUEST = 25;
        tracker.getNextMessages(MESSAGES_PER_REQUEST, new MessageTracker.GetMessagesCallback() {
                        @Override
                        public void receive(@NonNull final List< ? extends Message> received) {
                            //seu código
                        }
                    });
        ```

        A classe `Message` é necessária para armazenar informações sobre mensagens. Usando os métodos das instâncias da classe `Message` é possível obter todos os dados necessários sobre uma determinada mensagem: número único da mensagem (método `getId()`), texto da mensagem (método `getText()`), informações sobre o arquivo anexado (método `getAttachment()`) etc. Os métodos da interface `MessageListener` operam em objetos da classe `Message`. Todas as ferramentas relacionadas a essa classe (métodos para trabalhar com anexos, tipos de mensagens etc.) estão descritas [aqui](https://rox.chat/kb/pt/mobile/sdk/android-sdk-handbook.html#message).

        A descrição detalhada desses e de outros métodos pode ser encontrada nos guias de métodos para [iOS](https://rox.chat/kb/pt/mobile/sdk/ios-sdk-handbook.html) e [Android](https://rox.chat/kb/pt/mobile/sdk/android-sdk-handbook.html).

    ## Etapa 3: Outras configurações

    Além de instalar as interfaces listadas acima, para a operação correta do aplicativo com base no **Rox.Chat Mobile SDK**, você precisa fazer várias configurações no código do aplicativo.

      1. É necessário configurar corretamente os `campos de visitantes` e o procedimento de contagem de `hash`.
      A chave privada da conta não deve ser armazenada no dispositivo ou em qualquer outro lugar que não seja o servidor do cliente. Caso contrário, haverá uma séria ameaça à segurança e o risco de vazamento da correspondência do cliente para terceiros.

        Exemplo de transmissão do objeto `json-encoded` de um visitante do SDK:

        ```
        .setVisitorFieldsJson("{
            "id":"1234567890987654321",
            "display_name": "Nikita",
            "hash":"ffadeb6aa3c788200824e311b9aa44cb"
        }")
        ```

        1. Um ofuscador pode ser usado para um aplicativo baseado em SDK. Nesse caso, é necessário definir exceções nas regras do ofuscador para que determinadas classes não sejam ofuscadas - isso é necessário para o funcionamento correto do aplicativo baseado no **Rox.Chat** Mobile SDK. Em particular, ao usar o ofuscador **Proguard**, você deve definir o seguinte em suas regras:

  ```
  -keep public class com.roxchat.android.sdk.* { *; }
  ```

  Isso significa que o pacote/classe especificado não será "criptografado" pelo ofuscador.

1. Forneça os acessos de rede necessários.

  Para um dispositivo móvel que executa um aplicativo móvel integrado com o **Rox.Chat Mobile SDK**, as portas de saída devem estar abertas para os seguintes URLs:

    * `https://*.rox.chat/l/v/m/action 443 (POST)` - usado para transmitir ações de clientes.

    * `https://*.rox.chat/l/v/m/delta 443 (GET)` - usado para receber atualizações incrementais.

    * `https://*.rox.chat/l/v/m/download 443 (GET)` (não usado no SDK, mas necessário para baixar arquivos no aplicativo móvel)

    * `https://*.rox.chat/l/v/m/upload 443 (POST)` - usado para enviar arquivos do cliente para o servidor.

    * `https://*.rox.chat/l/v/m/history 443 (GET)` - usado para obter o histórico de bate-papo do banco de dados.

  As seguintes portas devem estar abertas para enviar notificações push:

    * FCM: `5228-5230 TCP`, consulte <https://firebase.google.com/docs/cloud-messaging/concept-options>.

    * APNs: `443, 2197, 5223 TCP`, consulte <https://support.apple.com/en-us/HT203609>.

  Se o bate-papo estiver hospedado nos servidores do cliente, o domínio deverá ser alterado para o seu próprio.

1. Para permitir que o usuário avalie o desempenho do operador após o término do chat, é necessário descrever o mecanismo correspondente no aplicativo. O SDK não implementa o mecanismo de avaliação, mas o obtém do aplicativo cliente.

1. As notificações por push estão ativadas e configuradas (opcional).

1. O método `startChat()` pode ser chamado para iniciar um chat. Se o método não for chamado, o chat será iniciado após a primeira mensagem do visitante.
