PROTÓTIPO DE SISTEMA MÓVEL NA PLATAFORMA ANDROID...
Transcript of PROTÓTIPO DE SISTEMA MÓVEL NA PLATAFORMA ANDROID...
UNIVERSIDADE REGIONAL DE BLUMENAU
CENTRO DE CIÊNCIAS EXATAS E NATURAIS
CURSO DE CIÊNCIA DA COMPUTAÇÃO – BACHARELADO
PROTÓTIPO DE SISTEMA MÓVEL NA PLATAFORMA
ANDROID PARA COMPARTILHAMENTO DE ARQUIVOS E
MENSAGENS ENTRE DISPOSITIVOS BASEADO EM
PROXIMIDADE GEOGRÁFICA
CESAR AUGUSTO KUEHL
BLUMENAU
2012
2012/1-09
CESAR AUGUSTO KUEHL
PROTÓTIPO DE SISTEMA MÓVEL NA PLATAFORMA
ANDROID PARA COMPARTILHAMENTO DE ARQUIVOS E
MENSAGENS ENTRE DISPOSITIVOS BASEADO EM
PROXIMIDADE GEOGRÁFICA
Trabalho de Conclusão de Curso submetido à
Universidade Regional de Blumenau para a
obtenção dos créditos na disciplina Trabalho
de Conclusão de Curso II do curso de Ciência
da Computação — Bacharelado.
Prof. Dalton Solano dos Reis, M. Sc. - Orientador
BLUMENAU
2012
2012/1-09
PROTÓTIPO DE SISTEMA MÓVEL NA PLATAFORMA
ANDROID PARA COMPARTILHAMENTO DE ARQUIVOS E
MENSAGENS ENTRE DISPOSITIVOS BASEADO EM
PROXIMIDADE GEOGRÁFICA
Por
CESAR AUGUSTO KUEHL
Trabalho aprovado para obtenção dos créditos
na disciplina de Trabalho de Conclusão de
Curso II, pela banca examinadora formada
por:
______________________________________________________
Presidente: Prof. Dalton Solano dos Reis, M. Sc. – Orientador, FURB
______________________________________________________
Membro: Prof. Aurélio Faustino Hoppe, M. Sc. – FURB
______________________________________________________
Membro: Prof. Sérgio Stringari, M. Sc. – FURB
Blumenau, dia 10 de Julho de 2012
Dedico este trabalho aos meus pais, à minha
noiva e aos meus amigos, por todo apoio
concedido nesta etapa da minha vida.
AGRADECIMENTOS
A todos que me ajudaram de forma direta ou indireta na realização deste trabalho.
Aos meus pais, por terem me dado todo o apoio necessário para que eu pudesse chegar
nesta etapa da minha vida.
Ao professor Paulo César Rodacki Gomes, por todo seu auxilio na elaboração da
proposta deste trabalho.
Ao meu orientador, que mesmo diante das dificuldades, aceitou orientar este trabalho e
sempre o fez de forma exemplar.
A minha noiva, por sua enorme paciência com minha ausência durante o período de
realização deste trabalho.
Embora ninguém possa voltar atrás e fazer um
novo começo, qualquer um pode começar
agora e fazer um novo fim.
Francisco de Paula Cândido Xavier
RESUMO
Este trabalho apresenta o desenvolvimento de um protótipo de sistema que permite a troca de
mensagens de texto e arquivos entre usuários que estejam geograficamente próximos. A
obtenção das coordenadas de posicionamento global dos usuários é feita através de bibliotecas da
própria plataforma Android. Para calcular a distância entre os usuários foi utilizado a formula
matemática de Haversine. A troca de mensagens entre os usuários e o compartilhamento dos
arquivos é realizado através de um web service. O acesso a este web service é feito através de
uma biblioteca externa disponibilizada para a plataforma. O download dos arquivos
compartilhados é realizado através de uma requisição do HyperText Transfer Protocol (HTTP).
Durante a evolução desse trabalho, a plataforma Android é apresentada, através de conceitos e
utilização de funcionalidades da mesma.
Palavras-chave: Computação móvel. Web-services. Android. Geolocalização.
ABSTRACT
This paper presents the development of a prototype system that allows the exchanging of text
messages and files between users who are geographically close. The achievement of global
positioning coordinates of the users is done through libraries of the Android platform. To
calculate the distance between users the mathematical formula of Haversine was used. The
exchange of messages between users and the sharing of files is done through a web service.
Access to this web service is done through an external library available for the platform. The
download of the shared files is accomplished through a request of the HyperText Transfer
Protocol (HTTP). During the evolution of this work, the Android platform is presented, using
concepts and use of the same features.
Key-words: Mobile computing. Web-services. Android. Geolocation.
LISTA DE ILUSTRAÇÕES
Figura 1 – Ciclo de vida de uma activity .................................................................................. 20
Figura 2 – Ciclo de vida de um service .................................................................................... 22
Figura 3 – Formula de Haversine ............................................................................................. 25
Quadro 1 – Definição de um LocationListener ............................................................. 26
Figura 4 – Interface do trabalho correlato Framework para gerenciamento e disponibilização
de informações multimídia geolocalizadas na plataforma Android ...................... 28
Figura 5 – Interface do trabalho correlato Foursquare ............................................................. 29
Figura 6 – Interface do trabalho correlato SCVNGR ............................................................... 30
Figura 7 – Diagrama de casos de uso do protótipo desenvolvido ............................................ 34
Quadro 2 – Caso de uso Efetuar login ............................................................................ 36
Quadro 3 – Caso de uso Registrar usuário .................................................................. 37
Quadro 4 – Caso de uso Alterar configurações ........................................................ 38
Quadro 5 – Caso de uso Alterar senha ............................................................................ 39
Quadro 6 – Caso de uso Visualizar usuários próximos de sua
localização ..................................................................................................... 40
Quadro 7 – Caso de uso Alterar distância para visualização de
usuários ............................................................................................................ 41
Quadro 8 – Caso de uso Visualizar arquivos compartilhados ......................... 42
Quadro 9 – Caso de uso Compartilhar um arquivo .................................................... 43
Quadro 10 – Caso de uso Remover compartilhamento de arquivo ..................... 44
Quadro 11 – Caso de uso Listar arquivos compartilhados de um usuário 45
Quadro 12 – Caso de uso Realizar download de um arquivo .............................. 46
Quadro 13 – Caso de uso Efetuar logoff ....................................................................... 47
Quadro 14 – Caso de uso Recuperar coordenadas geográficas do usuário 47
Quadro 15 – Caso de uso Envia coordenadas geográficas do usuário para
o servidor ....................................................................................................... 48
Quadro 16 – Caso de uso Atualiza lista de usuários próximos ..................... 49
Quadro 17 – Caso de uso Gerar notificação para mensagem recebida ......... 50
Quadro 18 – Caso de uso Cria sessão para usuário autenticado .................. 51
Quadro 19 – Caso de uso Remove sessão de usuário inativo ............................ 51
Figura 8 – Componentes do aplicativo cliente ......................................................................... 53
Figura 9 – Pacote br.com.cesar.tcc2 do aplicativo cliente ......................................... 56
Figura 10 – Pacote br.com.cesar.tcc2.task .............................................................. 58
Figura 11 – Pacote br.com.cesar.tcc2.adapter ....................................................... 59
Figura 12 – Pacote br.com.cesar.tcc2.ws ................................................................... 60
Figura 13 – Pacote br.com.cesar.tcc2.service ....................................................... 61
Figura 14 – Pacote br.com.cesar.tcc2.listener ..................................................... 61
Figura 15 – Pacote br.com.cesar.tcc2.modelo ......................................................... 63
Figura 16 – Pacote br.com.cesar.tcc2.util .............................................................. 64
Figura 17 – Pacote br.com.cesar.tcc2 do aplicativo webservice ................................ 65
Figura 18 – Pacote br.com.cesar.tcc2.dao ................................................................. 66
Figura 19 – Pacote br.com.cesar.tcc2.server ......................................................... 67
Figura 20 – Pacote br.com.cesar.tcc2.server.util ............................................. 67
Figura 21 – Pacote br.com.cesar.tcc2.server.rmi ................................................ 68
Figura 22 – Pacote br.com.cesar.tcc2.modelo ......................................................... 69
Figura 23 – Pacote br.com.cesar.tcc2.server.lock ............................................. 69
Figura 24 – Pacote br.com.cesar.tcc2.server.controle .................................... 70
Figura 25 – Diagrama de sequencia Visualizar usuários próximos da sua
localização ..................................................................................................... 72
Figura 26 – Diagrama de sequencia Compartilhar um arquivo ................................. 74
Figura 27 – MER das tabelas do banco de dados do sistema ................................................... 75
Quadro 20 – Cabeçalho do arquivo AndroidManifest.xml ........................................... 77
Quadro 21 – Declaração de activities e services no arquivo
AndroidManifest.xml .................................................................................. 78
Quadro 22 – Arquivo layout/tela_config.xml .......................................................... 79
Quadro 23 – Arquivo values/strings.xml .................................................................... 80
Quadro 24 – Trecho da activity Configuracoes ................................................................ 81
Quadro 25 – Arquivo services.xml .................................................................................. 82
Quadro 26 – Trecho da classe LocalSocial ....................................................................... 83
Quadro 27 – Método para gravação dos dados de acesso ao webservice ................................. 84
Quadro 28 – Método para gravação da lista de arquivos compartilhados ................................ 85
Quadro 29 – Classe br.com.cesar.tcc2.dao.DAOFactory ..................................... 86
Quadro 30 – Trecho da classe br.com.cesar.tcc2.dao.UsuarioDAO ..................... 87
Quadro 31 – Trecho de conexão da classe br.com.cesar.tcc2.ws.LocalSocialWS
............................................................................................................................... 88
Quadro 32 – Classe MarshalDouble................................................................................... 89
Quadro 33 – Interface br.com.cesar.tcc2.server.rmi.LocalSocialRMI ....... 90
Quadro 34 – Trecho da classe
br.com.cesar.tcc2.server.rmi.LocalSocialImpl ...................... 91
Quadro 35 – Abertura de conexão com o aplicativo servidor .................................................. 92
Quadro 36 – Primeiro trecho da classe
br.com.cesar.tcc2.service.Georastreamento ............................. 92
Quadro 37 – Segundo trecho da classe
br.com.cesar.tcc2.service.Georastreamento ............................. 93
Quadro 38 – Classe
br.com.cesar.tcc2.listener.LocationListenerSatelite ..... 94
Quadro 39 – Classe
br.com.cesar.tcc2.listener.LocationListenerNetwork ....... 94
Quadro 40 – Método setPosicaoUsuario da classe
br.com.cesar.tcc2.util.Parametros ................................................ 95
Quadro 41 – Classe br.com.cesar.tcc2.util.Util ................................................. 96
Quadro 42 – Método downloadArquivo() da task
br.com.cesar.tcc2.task.DownloadArquivo .................................... 97
Quadro 43 – Método gravarArquivoSD(ByteArrayBuffer bab) da task
br.com.cesar.tcc2.task.DownloadArquivo .................................... 97
Figura 28 – Passos para criação de um usuário ........................................................................ 99
Figura 29 – Tela principal do sistema ...................................................................................... 99
Figura 30 – Context menu da tela principal do sistema .......................................................... 100
Figura 31 – Tela de conversas e escrita de mensagem ........................................................... 101
Figura 32 – Notificação de nova mensagem .......................................................................... 102
Figura 33 – Passos para compartilhar arquivo........................................................................ 102
Figura 34 – Passos para interromper compartilhamento de arquivo ...................................... 103
Figura 35 – Passos para download de arquivo compartilhado ............................................... 104
Figura 36 – Cenário do sistema .............................................................................................. 105
Quadro 44 – Tempo de transferência de arquivos .................................................................. 107
Figura 37 – Tempo para donwload de arquivo ....................................................................... 108
Quadro 45 – Comparativo de funcionalidades entre os trabalhos correlatos ......................... 109
LISTA DE TABELAS
Tabela 1 – Tempo para recuperação da lista de usuários ....................................................... 106
Tabela 2 – Tempo para recuperação da lista de mensagens enviadas .................................... 106
Tabela 3 – Tempo para recuperação de mensagem ................................................................ 107
Tabela 4 – Espaço utilizado pela tabela LS_USUARIO......................................................... 108
Tabela 5 – Espaço utilizado pela tabela LS_ARQUIVOS ...................................................... 109
LISTA DE SIGLAS
API – Application Programming Interface
EDGE – Enhanced Data for GSM Evolution
GPS – Global Positioning System
HPSPA – High-Speed Downlink Packet Access
HTTP – HyperText Transport Protocol
JDBC – Java DataBase Connectivity
JDK – Java Development Kit
MER – Modelo de Entidades e Relacionamentos
MIT – Massachusetts Institute of Technology
RMI – Remote Method Invocation
SGBD – Sistema Gerenciador de Banco de Dados
SMTP – Simple Mail Transfer Protocol
SOAP – Simple Object Access Protocol
SQL – Sequel Query Language
URL – Uniform Resource Locator
VOIP – VOice over IP
WSDL – Web Services Definition Language
XML – eXtensible Markup Language
SUMÁRIO
1 INTRODUÇÃO .................................................................................................................. 16
1.1 OBJETIVOS DO TRABALHO ........................................................................................ 17
1.2 ESTRUTURA DO TRABALHO ...................................................................................... 17
2 FUNDAMENTAÇÃO TEÓRICA .................................................................................... 18
2.1 PLATAFORMA ANDROID............................................................................................. 18
2.1.1 Componentes da plataforma Android ............................................................................. 19
2.1.1.1 Activity ......................................................................................................................... 19
2.1.1.2 Service .......................................................................................................................... 21
2.1.1.3 AsyncTask .................................................................................................................... 22
2.2 WEB SERVICES .............................................................................................................. 23
2.3 GEOLOCALIZAÇÃO ...................................................................................................... 24
2.3.1 Geolocalização na plataforma Android ........................................................................... 25
2.4 TRABALHOS CORRELATOS ........................................................................................ 27
2.4.1 Framework para gerenciamento e disponibilização de informações multimídia
geolocalizadas na plataforma Android ............................................................................ 27
2.4.2 Foursquare ....................................................................................................................... 28
2.4.3 SCVNGR ........................................................................................................................ 29
3 DESENVOLVIMENTO DO PROTÓTIPO .................................................................... 31
3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO ....................... 31
3.2 IMPLEMENTAÇÃO ........................................................................................................ 33
3.2.1 Casos de uso .................................................................................................................... 33
3.2.1.1 Efetuar login ................................................................................................................. 35
3.2.1.2 Registrar usuário ........................................................................................................... 36
3.2.1.3 Alterar configurações .................................................................................................... 37
3.2.1.4 Alterar senha ................................................................................................................. 38
3.2.1.5 Visualizar usuários próximos de sua localização ......................................................... 39
3.2.1.6 Alterar distância para visualização de usuários ............................................................ 40
3.2.1.7 Visualizar arquivos compartilhados ............................................................................. 41
3.2.1.8 Compartilhar um arquivo .............................................................................................. 42
3.2.1.9 Remover compartilhamento de arquivo ........................................................................ 43
3.2.1.10 Listar arquivos compartilhados de um usuário ...................................................... 44
3.2.1.11 Realizar download de um arquivo ......................................................................... 45
3.2.1.12 Efetuar logoff ......................................................................................................... 46
3.2.1.13 Recuperar coordenadas geográficas do usuário ..................................................... 47
3.2.1.14 Envia coordenadas geográficas do usuário para o servidor ................................... 48
3.2.1.15 Atualiza lista de usuários próximos ....................................................................... 48
3.2.1.16 Gerar notificação para mensagem recebida ........................................................... 49
3.2.1.17 Cria sessão para usuário autenticado ..................................................................... 50
3.2.1.18 Remove sessão de usuário inativo ......................................................................... 51
3.2.2 Componentes do aplicativo cliente ................................................................................. 52
3.2.3 Classes do aplicativo cliente ........................................................................................... 55
3.2.3.1 Pacote br.com.cesar.tcc2.task ...................................................................... 57
3.2.3.2 Pacote br.com.cesar.tcc2.adapter ............................................................... 59
3.2.3.3 Pacote br.com.cesar.tcc2.ws ........................................................................... 59
3.2.3.4 Pacotes br.com.cesar.tcc2.service e
br.com.cesar.tcc2.listener ........................................................................ 60
3.2.3.5 Pacote br.com.cesar.tcc2.modelo ................................................................. 61
3.2.3.6 Pacote br.com.cesar.tcc2.util ...................................................................... 63
3.2.4 Classes do aplicativo webservice .................................................................................... 64
3.2.4.1 Pacote br.com.cesar.tcc2.dao ........................................................................ 65
3.2.5 Classes do aplicativo servidor ......................................................................................... 66
3.2.5.1 Pacote br.com.cesar.tcc2.server.controle e
br.com.cesar.tcc2.server.lock ................................................................. 68
3.2.6 Diagramas de sequencia .................................................................................................. 70
3.2.6.1 Diagrama de sequencia Visualizar usuários próximos da sua
localização ............................................................................................................ 70
3.2.6.2 Diagrama de sequencia Compartilhar um arquivo ......................................... 73
3.2.7 Banco de dados ............................................................................................................... 75
3.3 IMPLEMENTAÇÃO ........................................................................................................ 75
3.3.1 Técnicas e ferramentas utilizadas.................................................................................... 76
3.3.2 Arquivo AndroidManifest.xml ........................................................................................ 77
3.3.3 Arquivos de leiaute e constantes de texto ....................................................................... 79
3.3.4 Arquivo services.xml ...................................................................................................... 81
3.3.5 Persistência dos dados no aplicativo cliente ................................................................... 84
3.3.6 Persistência dos dados no aplicativo webservice ............................................................ 85
3.3.7 Conexão do aplicativo cliente com o aplicativo webservice ........................................... 87
3.3.8 Conexão do aplicativo webservice com o aplicativo servidor ........................................ 89
3.3.9 Recuperação das coordenadas geográficas do usuário.................................................... 92
3.3.10 Cálculo da distancia entre dois usuários .................................................................. 96
3.3.11 Download de um arquivo compartilhado ................................................................. 96
3.3.12 Operacionalidade da implementação ....................................................................... 98
3.3.12.1 Cadastro de usuário................................................................................................ 98
3.3.12.2 Visualização dos usuários próximos ...................................................................... 99
3.3.12.3 Troca de mensagens com um usuário .................................................................. 101
3.3.12.4 Compartilhamento de arquivos ............................................................................ 102
3.3.12.5 Download de um arquivo compartilhado por outro usuário ................................ 103
3.4 RESULTADOS E DISCUSSÃO .................................................................................... 104
3.4.1 Testes de performance................................................................................................... 105
3.4.2 Testes de memória......................................................................................................... 108
3.4.3 Comparativo dos trabalhos correlatos ........................................................................... 109
4 CONCLUSÕES ................................................................................................................ 111
4.1 EXTENSÕES .................................................................................................................. 112
REFERÊNCIAS BIBLIOGRÁFICAS ............................................................................... 113
16
1 INTRODUÇÃO
Os smartphones tornaram-se uma parte integral da vida de muitos usuários. Eles o
utilizam como uma extensão de seus computadores pessoais, no desempenho de tarefas e
consumo de outras mídias digitais (GOOGLE MOBILE ADS, 2011).
O crescente poder dos dispositivos de comunicação móvel chegou a um ponto em que
agora eles agem como computadores de bolso. Com este poder computacional, uma vasta
gama de aplicações disponíveis e acesso a Internet, estes dispositivos representam hoje em dia
um grande potencial produtivo, educacional e de entretenimento (WILKINSON, 2011, p. 2).
Conforme Lecheta (2010, p. 19), estudos mostravam que mais de três bilhões de
pessoas possuíam um aparelho celular em 2010, e isso correspondia a aproximadamente
metade da população mundial.
Em 2005 quando o Google adquiriu a plataforma Android, pagou um preço tão baixo
que escapou da exigência de tornar esta aquisição pública. Seis anos depois, a tecnologia até
então incipiente que motivou a compra está no centro da unidade de negócios de plataformas
para celulares e tablets, que vale dois bilhões de dólares (COHEN, VITURINO, 2011, p. 96).
Dados recentes mostram que 107,7 milhões de smartphones foram vendidos no
período de julho de 2010 até julho de 2011, fazendo com que atualmente a plataforma
Android esteja presente em cerca de 48% dos aparelhos ativos no mercado, sendo que 32,9
milhões de unidades foram vendidas somente nas Américas (CANALYS, 2011).
Quanto as principais atividades realizadas nos smartphones, uma pesquisa online
realizada pela IDG Global Solutions (IGS) revelou que no Brasil 84,5% dos entrevistados
usam seus smartphones para acesso à Internet, 74,6% deles diariamente e 71,6% baixam e
utilizam aplicações móveis. Quando questionados sobre os conteúdos acessados nestas
navegações, o acesso às redes sociais destacou-se com 78,3% das repostas, seguido de perto
por leitura de notícias gerais com 76,7% (CIDADE BIZ, 2011).
Com base nestes cenários, desenvolveu-se um protótipo de sistema, para a plataforma
Android, cujo propósito principal é permitir que usuários que estejam próximos
geograficamente possam trocar arquivos e mensagens.
17
1.1 OBJETIVOS DO TRABALHO
O objetivo deste trabalho é disponibilizar um protótipo de sistema capaz de listar
vários usuários que estejam próximos geograficamente, permitindo a troca de mensagens e
arquivos entre os mesmos.
Os objetivos específicos do trabalho são:
a) disponibilizar uma base de dados para armazenar os dados de conexão dos
usuários e uma lista de nomes de arquivos que estes usuários estão
compartilhando;
b) disponibilizar um web service que permitirá a leitura e gravação na base de dados;
c) disponibilizar uma interface gráfica para Android, que permita que um usuário
visualize os dados dos usuários que estejam próximos a ele e dos arquivos que
estes usuários estão compartilhando, a troca de mensagens com estes usuários e a
realização de download dos arquivos que estes usuário estejam compartilhando;
d) disponibilizar um serviço, que executará em segundo plano no dispositivo móvel,
com a finalidade de comunicar-se com o web service e receber a situação mais
atual dos usuários que estão nas proximidades.
1.2 ESTRUTURA DO TRABALHO
Este trabalho está estruturado em quatro capítulos.
O capitulo dois contém a fundamentação teórica necessária para permitir um melhor
entendimento sobre este trabalho.
O capítulo três apresenta o desenvolvimento do protótipo, contemplando os principais
requisitos do problema e a especificação contendo os casos de uso, diagramas de
componentes, de classes e de sequência. Neste capitulo são apresentadas também as
ferramentas utilizadas na implementação. Por fim são apresentados os resultados e discussão.
O quarto capítulo refere-se às conclusões do presente trabalho e sugestões para
trabalhos futuros.
18
2 FUNDAMENTAÇÃO TEÓRICA
Na seção 2.1 contém uma introdução à plataforma Android, incluindo os componentes
do sistema operacional e os componentes de desenvolvimento da plataforma. A seção 2.2
contém uma introdução ao conceito de web services. Na seção 2.3 é apresentado o conceito de
geolocalização e como ela figura na plataforma Android. Ao final, a seção 2.4 apresenta três
trabalhos correlatos ao trabalho proposto.
2.1 PLATAFORMA ANDROID
Segundo Open Handset Alliance (2012), a plataforma Android é um pacote completo
para plataformas móveis, incluindo um sistema operacional, um middleware e aplicações
chave.
Apesar de ter sido construído com base no Linux, não é um Linux, não possui
windowing system nativo, não suporta glibc1 e não possui algum dos conjuntos de padrões
apresentados em algumas distribuições Linux (PEREIRA e SILVA, 2009, p.4).
A plataforma Android foi construída de forma que permite que os desenvolvedores
possam criar aplicações capazes de tirar o melhor proveito de tudo que um dispositivo móvel
pode oferecer, como: envio de mensagens de textos, realização de chamadas telefônicas,
acesso a internet, entre outras. Não existe diferenciação para o Android entre uma aplicação
nativa e uma aplicação criada por terceiros, todas tem acesso aos mesmos recursos do
dispositivo.
Devido a isto, cada usuário pode customizar seu dispositivo da forma que melhor lhe
agradar, trocando, por exemplo, o discador, o seu navegador de Internet ou até mesmo a
interface principal do sistema.
Conforme Lecheta (2010, p. 22), esta característica, associada ao fato do Android ser
uma plataforma de código aberto, atraiu o interesse de diversas empresas, que viram no
Android uma oportunidade de terem um sistema customizado em seus dispositivos.
1 Comumente conhecida por glibc, a GNU C Library é a implementação da biblioteca C realizada pelo projeto
GNU (GNU C LIBRARY, 2012).
19
2.1.1 Componentes da plataforma Android
Para uma melhor compreensão do trabalho, serão descritos alguns dos principais
componentes da plataforma Android utilizados durante o desenvolvimento do mesmo.
2.1.1.1 Activity
Uma activity é um conceito de interface ao usuário. Ela geralmente representa uma tela
da aplicação e contem um ou mais componentes gráficos associados, embora não seja
obrigatório conter (HASHIMI e KOMATINENI, 2009, p. 24). Embora na maioria das vezes
uma activity seja apresentada em tela cheia, ela pode ser também uma janela flutuante ou uma
parte integrada de outra activity.
Conforme Android Developers (2012c), as activities são gerenciadas através de um
sistema de pilha de activities (activity stack). Cada nova activity disparada será apresentada ao
usuário e colocada no topo da pilha, ficando abaixo dela a activity que estava em execução
anteriormente. Quando uma activity conclui sua execução a activity abaixo dela na pilha volta
para o topo e é apresentada ao usuário. A Figura 1 apresenta o ciclo de vida de uma activity.
Sempre que uma activity é inicializada pela primeira vez o primeiro método a ser
executado por ela é o onCreate(), geralmente é neste método em que é definido o leiaute que
será apresentado ao usuário, bem como a associação dos componentes gráficos que este
leiaute irá conter com variáveis da activity. Na sequencia é executado o método onStart()
apresentando a activity ao usuário. O método onResume(), executado logo na sequencia,
permite a interação do usuário com a activity. Após a execução destes três métodos uma
activity entra no estado de execução.
Quando uma nova activity será apresentada, o método onPause() é executado na
activity atual, é neste método em que geralmente são executados ações de salvamento de
dados alterados, interrupção de animações e outras ações que possam consumir tempo do
processador. Após o método onPause() uma activity pode executar um de três métodos,
dependendo do que vier a acontecer com ela. Se a activity não for mais apresentada ao usuário
então é executado o método onStop(). Se a activity será apresentada novamente ao usuário é
executado novamente o método onResume(). Por fim, caso o sistema necessite liberar espaço
em memória ele irá remover activities que estiverem em pausa ou interrompidas, neste caso a
20
activity terá de começar seu ciclo novamente pelo método onCreate().
Uma vez executado o método onStop() uma activity pode iniciar sua execução
novamente, para isto ela executará o método onRestart(), neste método o desenvolvedor
pode definir ações que serão executadas antes da activity ser apresentada novamente ao
usuário. Se a activity tiver sido eliminada de memória enquanto estava interrompida, será
executada seu ciclo todo novamente, começando pelo método onCreate(). Por fim, caso
esteja sendo finalizada sua execução, é executado então o método onDestroy(), a partir de
então ela não estará mais em memória (ANDROID DEVELOPERS, 2012c).
Fonte: adaptado de Android Developers (2012c).
Figura 1 – Ciclo de vida de uma activity
21
2.1.1.2 Service
Conforme Pereira e Silva (2009, p. 34), services são códigos sem interface de usuário,
que rodam em segundo plano não tendo sua execução interrompida quando da troca de
activities. Quando iniciado só é interrompido sua execução quando solicitado.
Um service não é um processo separado, a menos que seja especificado desta maneira,
o service executa no mesmo processo em que a aplicação está executando. Tão pouco deve
ser considerado como uma thread, pois executa na mesma thread da classe que o criou, a
menos que seja implementado para executar em uma thread a parte (ANDROID
DEVELOPERS, 2012d).
Lecheta (2010, p. 318) ressalta ainda que o uso de services em detrimento a simples
threads Java se mostra mais eficiente e seguro, pois o Android conhece a classe Service e
pode gerenciar sua execução com os outros processos do sistema operacional. Assim como
ocorre com activities, um service pode ter sua execução interrompida caso seja necessário
liberar espaço em memória, no entanto, ao contrário das activities o Android tentará executa-
lo novamente quando possuir memória disponível.
Para criar um service é necessário criar uma subclasse de android.app.Service e
substituir os métodos principais para atender as necessidades específicas da aplicação e
possibilitar o controle desta sobre o service (ANDROID DEVELOPERS, 2012d).
Um service pode ser executado de duas formas: pelo método startService(intent)
e pelo método bindService(intent, com, flags). Quando executado pelo método
startService(intent) o service ficará em execução por tempo indeterminado, até que seja
executado o método stopService(intent), ou se o próprio service executar o método
stopSelf(), neste caso a execução será dada pelo método onStartCommand(). Pelo método
bindService(intent, com, flags) o service será criado, caso ainda não tenha sido
(execução do método onCreate()), mas não irá iniciar sua execução, ao invés disto, será
retornado a classe criadora uma referência a uma classe ou interface responsável por
manipular o service, neste cenário o service executa somente enquanto estiver conectado a
classe criadora através do método onBind() e deixa de executar quando a conexão a classe
criadora deixar de existir no método onUnbind() (LECHETA, 2010, p. 319). Embora as duas
formas de execução sejam explicadas separadamente, nada impede que um service
implemente ambas. A Figura 2 apresenta o ciclo de vida de um service.
22
Fonte: adaptado de Android Developers (2012d).
Figura 2 – Ciclo de vida de um service
2.1.1.3 AsyncTask
Uma AsyncTask pode ser definida como uma computação que executa em segundo
plano, cujo resultado é apresentado na linha de execução da interface do usuário. Durante a
execução da AsyncTask a tela do usuário é bloqueada, não permitido que o usuário realize
ações e geralmente neste período é apresentado uma barra de progresso que reflete o
andamento da execução da tarefa pela AsyncTask (ANDROID DEVELOPERS, 2012e).
Para criar uma AsyncTask é necessário criar uma classe que seja subclasse desta e
substituir os métodos principais de forma que atendam as necessidades específicas da
aplicação. Uma AsyncTask contém cinco métodos principais:
a) onPreExecute(): é invocado assim que a AsyncTask é disparada, este método é
23
responsável por realizar o bloqueio da interface do usuário e apresentar um
componente definido pelo usuário, geralmente uma barra de progresso;
b) publishProgress(): é invocado sempre que existir um novo dado referente o
progresso da execução da tarefa;
c) onProgressUpdate(): responsável por atualizar a interface do usuário com o novo
dado referente o progresso da execução da tarefa, este método é invocado logo após
o método publishProgress();
d) doInBackground(): é invocado em uma segunda thread e é responsável por
executar a tarefa destinada a AsyncTask. Ele executa o método
publishProgress() para informar do andamento da tarefa que está sendo
executada;
e) onPostExecute(): é invocado na thread da interface do usuário após a conclusão
da tarefa executada no método doInBackground(), geralmente utilizado para
remover a barra de progresso e apresentar o resultado da execução da tarefa.
2.2 WEB SERVICES
Conforme Chappel e Jewell (2002, p. 1), “um web service é uma peça de lógica de
negócio, localizada em algum lugar na Internet, que é acessível através de protocolos padrões
da Internet tais como HyperText Transport Protocol (HTTP) ou Simple Mail Transfer
Protocol (SMTP)”.
O que diferencia um web service de outra tecnologia semelhante é o uso do protocolo
EXtensible Markup Language (XML) para a representação de dados, tornando-o independente
de linguagem.
Em essência, então, um web service é algo que provê uma interface definida em
termos de mensagens XML e que pode ser acessado de qualquer ponto da Internet ou de uma
intranet (TOPLEY, 2003, p. 32).
Os dados formatados em XML são transmitidos entre o cliente e o web service através
do protocolo Simple Object Access Protocol (SOAP), que também é estruturado em XML.
Este protocolo é utilizado para permitir a interação entre os elementos da comunicação. Para
ser transportado, o protocolo SOAP utiliza diretamente o serviço do protocolo de aplicação
HTTP (W3C, 2004).
24
Para descrever os serviços de comunicação disponíveis, bem como os detalhes de
acesso, como parâmetros e dados de retorno, é utilizado o protocolo Web Services Definition
Language (WSDL). O WSDL também é baseado em formatação XML (W3C, 2001).
O processo de publicação e pesquisa de web services utiliza o protocolo Universal
Descritption, Discovery and Integration (UDDI). O objetivo é criar um repositório de web
services, de uma forma semelhante ao serviço de registro Remote Method Invocation (RMI)
do Java (OASIS, 2011).
O que vem fomentando a utilização de web services são as inúmeras possibilidades
oferecidas por esta tecnologia, tais como a flexibilidade de funcionar com sistemas
desenvolvidos por plataformas diferentes, o baixo custo por utilizar somente tecnologias
abertas e a facilidade de proporcionar novos negócios, já que simplifica a integração com
outros sistemas, ainda mais quando considerado a abrangência e o alcance da Internet
(COSTA, 2008, p. 115).
2.3 GEOLOCALIZAÇÃO
A geolocalização é utilizada desde a antiguidade. Antes do advento dos mapas, os
viajantes triangularizavam suas posições baseando-se na posição das estrelas no céu. Isso se
mostrou uma ciência bastante inexata devido a baixa precisão das medidas, a dependência de
um céu livre de nuvens e a mudança da posição das estrelas devido a posição dos viajantes e
das estações do ano.
No meio tecnológico o uso da geolocalização aplicou-se na criação do Global
Positioning System (GPS), quando em 1920 alguns navios próximos a uma base terrestre
tiveram sua direção e distância calculadas com base em sinais de rádio. O uso de satélites para
obtenção de dados de posicionamento global surgiu em 1957 quando a Rússia lançou o
satélite Sputnik (GRAZIADIO E-LEARNING, 2011).
Conforme Campesato, Chin e Iverson (2011, p. 273), atualmente o dado de
posicionamento global pode vir da triangularização de torres de telefonia móvel, uma base de
dados de pontos de acesso Wi-Fi2 conhecidos e de satélites GPS. Dados de localização
baseados em Wi-Fi e em torres de telefonia móvel não são tão precisos quanto dados de
25
satélites, mas são mais fáceis de serem obtidos e consomem menos energia da bateria do
dispositivo do que o receptor GPS do mesmo.
O predomínio de serviços de geolocalização em dispositivos móveis levou nos últimos
anos a um rápido crescimento no número de aplicações cientes de localização, disponíveis no
mercado.
Para o calculo de distância entre coordenadas geográficas a formula mais utilizada
atualmente é a formula de Haversine. Conforme Madden (2011, p. 117), a formula de
Haversine é uma equação, usada na navegação, com o propósito de calcular a distância mais
curta entre dois pontos dispostos sobre a superfície de uma esfera através de suas coordenadas
de longitude e latitude. A Figura 3 apresenta a formula de Haversine.
Figura 3 – Formula de Haversine
A formula de Haversine faz uso da função de Haversine, que pode ser definida como 1
menos o cosseno de um determinado valor dividido por 2. O raio da esfera também é
utilizado, prevendo que este seja igual para qualquer ponto da mesma, ou seja, que a esfera
seja perfeita.
2.3.1 Geolocalização na plataforma Android
Na plataforma Android é possível obter coordenadas de geolocalização de duas
formas, via satélites GPS ou através dos Network Location Providers. A coordenada obtida
através dos satélites GPS é mais precisa, no entanto exige que o usuário esteja a céu aberto,
consome mais bateria do dispositivo e nem sempre é rápida de ser obtida. A coordenada
fornecida por um Network Location Provider é calculada com base em torres de telefonia e
2 Marca registrada da Wi-Fi Alliance, utilizada por produtos certificados que pertencem à classe de dispositivos
de rede local sem fios (WLAN) baseados no padrão IEEE 802.11 (WI-FI, 2011).
26
pontos de acesso Wi-Fi, permitindo que seja fornecida mesmo quando o usuário esteja em um
lugar fechado (ANDROID DEVELOPERS, 2012a).
Para que o Android comece a fornecer as coordenadas do dispositivo, o mesmo deverá
informar à plataforma que deseja ter sua localização fornecida. Para isto é necessário utilizar a
classe LocationManager e uma segunda classe que implemente a interface
LocationListener.
A classe LocationManager providencia o acesso ao sistema de serviços de
localização. Estes serviços permitem que as aplicações obtenham atualizações periódicas da
localização geográfica do dispositivo, ou disparem uma Intent específica de uma aplicação
quando o dispositivo estiver em uma determinada localização geográfica.
A classe que implementa a interface LocationListener é utilizada para receber
notificações da classe LocationManager quando a localização do dispositivo sofrer alteração.
Os métodos desta interface são utilizados quando o LocationListener é vinculado ao
LocationManager pelo método requestLocationUpdates(String, long, float,
LocationListener) (ANDROID DEVELOPERS, 2012b).
No Quadro 1 é apresentado um exemplo de como definir um LocationListener
// Adquire uma referencia do LocationManager do sistema
LocationManager locationManager = (LocationManager)
this.getSystemService(Context.LOCATION_SERVICE);
// Define o LocationListener que responde às atualizações de localização
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Executado quando uma nova localização é encontrada pelo network
location provider.
makeUseOfNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle
extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Registra o LocationListener com o LocationManager para receber
atualizações de localização
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0, 0, locationListener);
Fonte: adaptado de Android Developers (2012a).
Quadro 1 – Definição de um LocationListener
27
2.4 TRABALHOS CORRELATOS
Existem alguns sistemas, incluído ferramentas comerciais, semelhantes ao trabalho
proposto. Dentre eles foram escolhidos três cujas principais características assemelham-se nos
objetivos deste trabalho. Foram escolhidos os projetos, descritos em: Conceição (2010),
Foursquare (2011) e SCVNGR (2012).
2.4.1 Framework para gerenciamento e disponibilização de informações multimídia
geolocalizadas na plataforma Android
Conceição (CONCEIÇÃO, 2010) apresenta o desenvolvimento de uma ferramenta
para a definição de informações de georreferenciamento vinculadas às mídias de áudio, vídeo,
imagens, textos e pontos de interesse em um aplicativo na plataforma Android.
A ferramenta permite também o compartilhamento das mídias georreferenciadas entre
usuários conectados, além da consulta a localização destes usuários. As informações de
georreferenciamento são armazenadas em um banco de dados local e a comunicação com o
servidor é efetuada através de requisições do HTTP.
A visualização e reprodução das mídias é efetuada através de bibliotecas da própria
plataforma Android. Já a exibição dos mapas e obtenção das coordenadas selecionadas pelo
usuário são efetuadas através de bibliotecas externas disponibilizadas para a plataforma.
Durante a evolução deste trabalho, a plataforma Android é apresentada, através de
conceitos e utilização de funcionalidades da mesma.
A Figura 4 apresenta uma das interfaces do trabalho.
28
Fonte: adaptado de Conceição (2010).
Figura 4 – Interface do trabalho correlato Framework para gerenciamento e disponibilização de
informações multimídia geolocalizadas na plataforma Android
2.4.2 Foursquare
O Foursquare (FOURSQUARE, 2011) é um sistema para smartphones desenvolvido
pela empresa de mesmo nome, lançado em março de 2009, cujo propósito é ajudar os usuários
a fazer novas amizades e descobrir novos lugares.
O sistema mantém um cadastro de usuários e localidades permitindo que um usuário
informe aos seus amigos onde ele está em determinado momento. Além disso, o usuário pode
também dar a sua opinião sobre aquela localidade associando uma mensagem de texto com o
local.
As localidades podem ser residências, empresas, hospitais, restaurantes, praças, praias,
etc. Quando um usuário está em um determinado local ele pode efetuar um “check-in”,
indicando ao sistema que ele está naquele local naquele momento.
Para estimular o uso do Foursquare, foi desenvolvido um sistema de recompensas,
onde os usuários devem atingir certos objetivos para ganhar troféus, representados por
29
imagens no sistema. Os objetivos variam desde um grande número de check-ins, até check-ins
em lugares diferentes ou horários e situações diferentes. Outra forma de estímulo oferecida é a
possibilidade de estabelecimentos comerciais criarem promoções com base no Foursquare,
concedendo descontos ou brindes aos usuários que fizerem check-in no estabelecimento.
O Foursquare conta atualmente com mais de 10 milhões de usuários cadastrados e já
contabilizou mais de um bilhão de check-ins.
A Figura 5 apresenta a interface principal do sistema e o descritivo de uma localidade.
Fonte: adaptado de Foursquare (2011).
Figura 5 – Interface do trabalho correlato Foursquare
2.4.3 SCVNGR
O SCVNGR (SCVNGR, 2012) é um jogo social baseado em localização, criado em
2008 pela empresa de mesmo nome, que incentiva os usuários a visitarem locais e realizarem
alguma tarefa ou desafio em troca de pontos que permitem adquirir algum benefício no jogo
ou na vida real.
30
Utilizando um smartphone com o sistema Android ou o sistema iOS3, os usuários
podem visualizar onde estão e quais são os estabelecimentos mais próximos do seu local que
estão cadastrados no SCVNGR. Uma vez estando em um destes estabelecimentos os usuários
podem realizar o check-in, e visualizar quais são as atividades e desafios que podem ser
realizados.
Se um usuário não estiver satisfeito com os desafios propostos pelo jogo, ele mesmo
pode criar seus desafios e compartilhar com seus amigos utilizando a ferramenta para criação
de desafios ofertada no web site do SCVNGR.
O sistema ganhou notoriedade quando começou a ser utilizado por universidades
americanas como meio de os novos alunos conhecerem a estrutura dos campi, substituindo
então os clássicos passeios com guia. O SCVNGR pode ser obtido gratuitamente na loja de
aplicativos do Android e do iOS e já conta com mais de 1.000.000 de usuários.
A Figura 6 apresenta os detalhes de um desafio cadastrado na aplicação.
Fonte: adaptado de SCVNGR (2012).
Figura 6 – Interface do trabalho correlato SCVNGR
3 Sistema operacional móvel da empresa Apple (IOS, 2012).
31
3 DESENVOLVIMENTO DO PROTÓTIPO
Neste capítulo são abordadas as etapas de desenvolvimento do protótipo. A primeira
seção apresenta os principais requisitos do problema trabalhado. A segunda seção descreve a
especificação da solução através de diagramas da Unified Modeling Language (UML) e de
Modelos de Entidades e Relacionamentos (MER). A terceira seção apresenta a
implementação da solução, incluindo os principais trechos do código fonte e exemplos de uso
do protótipo. Por fim, a quarta seção aborda resultados deste trabalho.
No que se refere ao ambiente de desenvolvimento, considerando as especificidades do
aplicativo cliente, do servidor e do webservice, o presente trabalho foi desenvolvido em três
projetos. Em um projeto o aplicativo cliente foi desenvolvido, de forma independente das
outras duas partes. No segundo projeto o servidor foi desenvolvido, de modo a prover suporte
para algumas das funcionalidades demonstradas no aplicativo cliente. No terceiro projeto foi
desenvolvido o webservice, também responsável por prover suporte para algumas das
funcionalidades demonstradas no aplicativo cliente, além de, fazer a ponte entre o aplicativo
cliente e o servidor.
O aplicativo cliente foi desenvolvido utilizando o Android SDK versão 2.1, ambiente
de desenvolvimento padrão da plataforma. Para a comunicação com o webservice foi utilizada
a Application Programming Interface (API) KSOAP2 versão 2.6.0.
O webservice foi desenvolvido sobre a plataforma JEE, no ambiente de
desenvolvimento Eclipse. Como servidor de aplicação foi utilizado o servidor Apache
Tomcat. O acesso ao banco de dados foi efetuado através de um driver Java DataBase
Connectivity (JDBC) para o banco de dados Oracle.
O servidor foi desenvolvido sobre a plataforma JSE, no ambiente de desenvolvimento
Eclipse. A comunicação entre o webservice e o servidor é realizada com a tecnologia RMI.
3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO
Quanto ao aplicativo cliente, os Requisitos Funcionais (RFs) são:
a) RF01: permitir que o usuário crie um nome de usuário e uma senha para
possibilitar o uso do sistema;
32
b) RF02: permitir que o usuário realize a autenticação no sistema, com seu nome de
usuário e senha;
c) RF03: permitir que o usuário altere sua senha de acesso ao sistema;
d) RF04: permitir que o usuário visualize o nome dos usuários que estão próximos às
coordenadas em que o mesmo se encontra;
e) RF05: permitir que o usuário altere a configuração de distância em que deseja
procurar por outros usuários;
f) RF06: permitir que o usuário envie mensagens para outros usuários;
g) RF07: permitir que o usuário visualize as mensagens enviadas por outros usuários;
h) RF08: permitir que o usuário visualize uma lista contendo os arquivos
compartilhados por outro usuário do sistema;
i) RF09: permitir que o usuário realize o download de um arquivo contido na lista de
arquivos compartilhados por um usuário;
j) RF10: permitir que o usuário compartilhe arquivos do seu dispositivo móvel;
k) RF11: permitir que o usuário interrompa o compartilhamento de um arquivo
previamente compartilhado;
l) RF12: recuperar a coordenada geográfica do usuário;
m) RF13: enviar para o webservice as coordenadas geográficas do usuário;
n) RF14: permitir que o usuário altere os dados para conexão com a parte webservice
do sistema;
o) RF15: enviar para o webservice o pedido de saída do usuário do sistema;
p) RF16: gerar um alerta visual para informar que o usuário recebeu uma nova
mensagem.
Os Requisitos Não Funcionais (RNFs) do aplicativo cliente são:
a) RNF01: ser desenvolvido em Java, na plataforma Android, no ambiente Eclipse.
Quanto ao servidor, os requisitos funcionais são:
a) RF17: manter uma lista com a conexão dos usuários autenticados no sistema;
b) RF18: receber as atualizações das coordenadas geográficas dos usuários;
c) RF19: calcular a distância entre os usuários autenticados no sistema;
d) RF20: manter uma lista com as mensagens enviadas pelos usuários;
e) RF21: remover da lista de conexões os usuários autenticados que não estiverem
comunicando.
Os requisitos não funcionais do servidor são:
a) RNF02: ser desenvolvido em Java no ambiente Eclipse;
33
b) RNF03: realizar a comunicação com o webservice através da tecnologia RMI.
Quanto ao webservice, os requisitos são:
a) RF22: receber os dados de cadastro de um usuário e armazená-los no banco de
dados;
b) RF23: realizar a autenticação dos usuários no sistema;
c) RF24: enviar ao servidor os dados de um usuário que se autenticou no sistema;
d) RF25: receber os dados de posicionamento de um usuário e envia-los ao servidor;
e) RF26: solicitar ao servidor a lista de usuários próximos a um determinado usuário;
f) RF27: receber os arquivos que um usuário deseja compartilhar;
g) RF28: enviar a lista de arquivos compartilhados de um determinado usuário.
O requisito não funcional do webservice é:
a) RNF04: ser desenvolvido em Java, com o framework Axis, no ambiente Eclipse.
3.2 IMPLEMENTAÇÃO
A especificação deste trabalho foi desenvolvida utilizando diagramas da UML aliados
ao MER. Os casos de uso são apresentados através de um diagrama de casos de uso, seguido
da descrição do cenário de cada caso de uso. Em seguida, os componentes da aplicação cliente
são apresentados através de um diagrama de componentes. As classes do aplicativo cliente, do
servidor e do webservice são apresentadas através de diagramas de classes. Como forma de
facilitar a implementação, dois casos de uso foram representados através de diagramas de
sequência. Complementando a especificação, as entidades dos bancos de dados do webservice
são demonstradas através de diagramas MER, que não pertencem ao conjunto de diagramas
da UML.
3.2.1 Casos de uso
A partir dos requisitos criados para o protótipo, foram desenvolvidos dezoito casos de
uso (Figura 7). Esses casos de uso objetivam organizar os requisitos em funcionalidades que
possam ser executadas de forma simples pelo usuário. O desenvolvimento dos casos de uso
também levou em consideração os padrões da plataforma Android. Em nenhum dos casos de
34
uso foi disponibilizada opção de voltar ou cancelar na tela. Essa opção já existe nos
dispositivos com a plataforma Android na forma de um botão voltar.
Figura 7 – Diagrama de casos de uso do protótipo desenvolvido
35
Os casos de uso desenvolvidos são desempenhados por três atores. O ator Usuário
representa o utilizador do sistema, sendo capaz de interagir através dos casos de uso que
apresentam interfaces gráficas. Já o ator Cliente representa o aplicativo cliente, que interage
através de serviços que rodam em segundo plano e não apresentam interface gráfica. Esses
serviços apenas disparam notificações para o sistema em alguns eventos específicos. O ator
Servidor representa o aplicativo servidor, responsável por manter as sessões dos usuários
autenticados e as mensagens trocadas entre eles.
O diagrama de casos de uso foi desenvolvido observando os padrões da UML. Cada
caso de uso foi detalhado em cenários e vinculado a, pelo menos, um RF. Essa vinculação
objetiva facilitar a identificação do propósito do caso de uso e justificar sua existência.
3.2.1.1 Efetuar login
Esse caso de uso apresenta uma janela para informação do nome de usuário e senha. O
usuário deve informar uma combinação válida para poder prosseguir na utilização do sistema.
O Quadro 2 contém os cenários do caso de uso Efetuar login.
36
UC01. Efetuar login: Possibilita ao usuário validar seu nome de usuário e senha do protótipo
e acessar a tela principal
Requisitos atendidos RF02, RF23 e RF24
Pré-condições Nenhuma
Cenário principal 1) o sistema apresenta campos para informar nome de usuário e
senha seguida das opções para registrar um usuário no sistema e
alterar as configurações do sistema;
2) o usuário informa seu nome de usuário e senha;
3) o sistema envia a combinação de nome de usuário e senha ao
webservice onde esta combinação é verificada;
4) o sistema informa se a combinação é válida ou inválida.
Fluxo alternativo 01 No passo 1, caso o usuário selecione a opção para registrar um
usuário:
1) executa o caso de uso UC02.
Fluxo alternativo 02 No passo 1, caso o usuário selecione a opção para alterar as
configurações do sistema:
1) executa o caso de uso UC03.
Fluxo alternativo 03 No passo 4, caso a combinação nome de usuário/senha for válida:
1) apresenta a tela principal do sistema.
Fluxo alternativo 04 No passo 2, caso o usuário não preencha um dos campos:
1) o sistema apresenta uma mensagem informado que todos os
campos devem ser preenchidos;
2) o sistema posiciona o cursor no campo que não foi preenchido.
Exceção 01 No passo 3, caso não ocorra a conexão com o webservice:
1) o sistema informa que um erro ocorreu durante a tentativa de
login do usuário.
Pós-condições 1) código e nome de usuário armazenados na classe de parâmetros
da parte cliente do sistema;
2) serviço de verificação dos dados geográficos do usuário é
iniciado;
3) serviço de recuperação dos usuários próximos e das mensagens
enviadas é iniciado;
4) objeto de sessão criado na parte servidor do sistema.
Quadro 2 – Caso de uso Efetuar login
3.2.1.2 Registrar usuário
Esse caso de uso apresenta uma janela para que o usuário informe seu nome, um nome
de usuário e uma senha. O usuário deve informar um nome de usuário não existente no
sistema. O Quadro 3 contém os cenários do caso de uso Registrar usuário.
37
UC02. Registrar usuário: Possibilita ao usuário a criação de um nome de usuário e uma senha
para possibilitar o uso do sistema
Requisitos atendidos RF01 e RF22
Pré-condições Nenhuma
Cenário principal 1) o sistema apresenta campos para informar o nome do usuário, um
nome de usuário e senha;
2) o usuário informa seu nome, seu nome de usuário e senha;
3) o sistema envia a combinação de nome, nome de usuário e senha
ao webservice onde esta combinação é verificada;
4) o sistema informa se a combinação é válida ou inválida.
Fluxo alternativo 01 No passo 1 ou 2, caso o usuário pressione o botão voltar do
dispositivo:
1) retorna a tela de login do sistema.
Fluxo alternativo 02 No passo 2, caso o usuário deixe de preencher um dos campos:
1) o sistema apresenta uma mensagem informando que o usuário
deve preencher todos os campos;
2) posiciona o cursor no campo que não foi preenchido.
Fluxo alternativo 03 No passo 4, caso o nome de usuário já exista previamente:
1) o sistema apresenta uma mensagem informado que o nome de
usuário já existe;
2) o sistema move o cursor para o campo nome de usuário.
Fluxo alternativo 04 No passo 4, caso o registro ocorra com sucesso:
1) o sistema apresenta a mensagem de que o usuário foi registrado
com sucesso;
2) o sistema volta para a tela de login.
Pós-condições Nenhuma
Quadro 3 – Caso de uso Registrar usuário
3.2.1.3 Alterar configurações
Esse caso de uso apresenta uma janela para que o usuário informe o hostname e a porta
para comunicação com a parte webservice do sistema, além de um botão para restaurar a
configuração padrão do sistema. O Quadro 4 contém os cenários do caso de uso Alterar
configurações.
38
UC03. Alterar configurações: Possibilita ao usuário a alteração dos dados de comunicação da
parte cliente com a parte web-service do sistema, assim como restaurar estes dados ao padrão
inicial do sistema.
Requisitos atendidos RF14
Pré-condições Nenhuma
Cenário principal 1) o sistema apresenta campos para informar o hostname e a porta
de acesso ao web-service do sistema já preenchidos com um
valor padrão seguido da opção de restaurar os valores padrões;
2) o usuário altera os valores de hostname e/ou porta;
3) o sistema grava os novos valores no cartão SD do dispositivo.
Fluxo alternativo 01 No passo 1 ou 2, caso o usuário pressione o botão voltar do
dispositivo:
1) retorna a tela de login do sistema.
Fluxo alternativo 02 No passo 2, caso o usuário deixe algum dos campos sem dados:
1) o sistema apresenta uma mensagem informando que o usuário
deve preencher todos os campos;
2) o sistema posiciona o cursor no campo que não foi preenchido.
Fluxo alternativo 03 No passo 1 ou 2, caso o usuário pressione no botão de restaurar as
configurações padrões:
1) o sistema solicita confirmação do usuário para a ação;
2) caso o usuário confirme o sistema informa que os parâmetros
voltaram ao padrão;
3) caso o usuário não confirme, nada é feito.
Fluxo alternativo 04 No passo 3, caso a alteração é realizado com sucesso:
1) o sistema apresenta a mensagem de que os parâmetros foram
alterados;
2) o sistema volta para a tela de login.
Pós-condições Os novos dados são gravados no cartão SD do dispositivo.
Quadro 4 – Caso de uso Alterar configurações
3.2.1.4 Alterar senha
Esse caso de uso apresenta uma janela para que o usuário informe sua senha de acesso
atual, a senha nova e a confirmação da senha nova. O Quadro 5 contém os cenários do caso de
uso Alterar senha.
39
UC04. Alterar senha: Possibilita ao usuário a alteração da sua senha de acesso ao sistema.
Requisitos atendidos RF03
Pré-condições O usuário deve estar autenticado no sistema.
Cenário principal 1) o sistema apresenta campos para informar a senha atual, uma
nova senha e a repetição desta nova senha;
2) o usuário preenche os campos;
3) o sistema verifica se a senha nova e a repetição dela são o mesmo
valor;
4) o sistema verifica a senha atual;
5) o sistema encaminha para o webservice a alteração de senha.
Fluxo alternativo 01 No passo 1 ou 2, caso o usuário pressione o botão voltar do
dispositivo:
2) retorna a tela principal do sistema.
Fluxo alternativo 02 No passo 3, caso a senha nova e a repetição dela não forem iguais:
1) o sistema apresenta uma mensagem informando que a nova
senha e a repetição dela não condizem;
Fluxo alternativo 03 No passo 4, caso a senha atual do usuário não estiver correta:
1) o sistema informa que a senha atual não está correta;
2) o sistema posiciona o cursor no campo da senha atual.
Fluxo alternativo 04 No passo 5, caso a alteração é realizado com sucesso:
1) o sistema apresenta a mensagem de que a senha foi alterada com
sucesso;
2) o sistema volta para a tela principal.
Exceção 01 No passo 4 ou 5 ocorre um erro na conexão com o webservice:
1) o sistema apresenta uma mensagem informando que ocorreu um
erro de conexão com o webservice.
Pós-condições Nenhuma
Quadro 5 – Caso de uso Alterar senha
3.2.1.5 Visualizar usuários próximos de sua localização
Após autenticação no sistema, será apresentada ao usuário a tela principal do sistema,
onde ele poderá visualizar quais usuários estão próximos de sua localização. O Quadro 6
contém os cenários do caso de uso Visualizar usuários próximos de sua localização.
40
UC05. Visualizar usuários próximos de sua localização: Possibilita ao usuário a visualização
dos usuários que estão próximos da sua localização, contendo o nome do usuário e a
distância que este está da sua posição.
Requisitos atendidos RF04, RF19 e RF26
Pré-condições O usuário deve estar autenticado no sistema.
Cenário principal 1) o sistema apresenta a tela principal contendo um botão para
atualizar a lista de usuários próximos, uma seekbar para
alteração da distancia de visualização de usuários, uma lista de
usuários próximos, cada um com um botão para conversa e
visualização de arquivos compartilhados, um menu com a opção
de alteração de senha e com a opção de compartilhamento de
arquivos.
Fluxo alternativo 01 No passo 1, caso o usuário pressione o botão voltar do dispositivo:
1) executa o caso de uso UC09.
Fluxo alternativo 02 No passo 1, caso o usuário acesse o menu de alteração da senha:
1) executa o caso de uso UC04.
Fluxo alternativo 03 No passo 1, caso o usuário acesso o menu de visualização de
arquivos compartilhados:
1) executa o caso de uso UC07.
Fluxo alternativo 04 No passo 1, caso o usuário pressione o botão de atualização da lista
de usuários:
1) executa este caso de uso novamente.
Fluxo alternativo 05 No passo 1, caso o usuário pressione no botão de conversa de um
usuário:
1) o sistema apresenta a tela de conversa com o usuário.
Fluxo alternativo 06 No passo 1, caso o usuário pressione no botão de arquivos
compartilhados de um usuário:
1) executa o caso de uso UC10.
Fluxo alternativo 07 No passo 1, o usuário moveu a seekbar e alterou a configuração de
visualização:
1) executa o caso de uso UC06.
Exceção 01 No passo 1, caso ocorra um erro de conexão com o webservice:
1) o sistema não apresenta nenhum usuário;
2) o sistema apresenta uma mensagem de erro de conexão com o
webservice.
Pós-condições A lista de usuários baseado na distância especificada é apresentada
ao usuário.
Quadro 6 – Caso de uso Visualizar usuários próximos de sua localização
3.2.1.6 Alterar distância para visualização de usuários
Durante a utilização do sistema o usuário pode aumentar ou diminuir a distância limite
para comunicação com outros usuários. Isto limitará a quantidade de usuários que será
apresentada na lista de usuários próximos. O Quadro 7 contém os cenários do caso de uso
Alterar distância para visualização de usuários.
41
UC06. Alterar distância para visualização de usuários: Possibilita ao usuário restringir ou
expandir sua lista de usuários próximos alterando
Requisitos atendidos RF05
Pré-condições O usuário deve estar autenticado no sistema.
Cenário principal 1) o sistema apresenta a tela principal contendo um botão para
atualizar a lista de usuários próximos, uma seekbar para
alteração da distancia de visualização de usuários, uma lista de
usuários próximos, cada um com um botão para conversa e
visualização de arquivos compartilhados, um menu com a opção
de alteração de senha e com a opção de compartilhamento de
arquivos.
Fluxo alternativo 01 No passo 1, caso o usuário pressione o botão voltar do dispositivo:
1) executa o caso de uso UC09.
Fluxo alternativo 02 No passo 1, caso o usuário acesse o menu de alteração da senha:
1) executa o caso de uso UC04.
Fluxo alternativo 03 No passo 1, caso o usuário acesso o menu de visualização de
arquivos compartilhados:
1) executa o caso de uso UC07.
Fluxo alternativo 04 No passo 1, caso o usuário pressione o botão de atualização da lista
de usuários:
1) executa o caso de uso UC05 com a distância atual do sistema.
Fluxo alternativo 05 No passo 1, caso o usuário pressione no botão de conversa de um
usuário:
1) o sistema apresenta a tela de conversa com o usuário.
Fluxo alternativo 06 No passo 1, caso o usuário pressione no botão de arquivos
compartilhados de um usuário:
1) executa o caso de uso UC10.
Fluxo alternativo 07 No passo 1, o usuário moveu a seekbar e alterou a configuração de
visualização:
1) executa o caso de uso UC05 com a nova distância.
Pós-condições A lista de usuários baseado na distância especificada é apresentada
ao usuário.
Quadro 7 – Caso de uso Alterar distância para visualização de usuários
3.2.1.7 Visualizar arquivos compartilhados
Uma das funcionalidades propostas pelo sistema é permitir a troca de arquivos entre
usuários. O caso de uso Visualizar arquivos compartilhados objetiva apresentar uma
tela onde o usuário possa visualizar quais arquivos já está compartilhando e permitir o
compartilhamento de outros. O Quadro 8 contém os cenários do caso de uso Visualizar
arquivos compartilhados.
42
UC07. Visualizar arquivos compartilhados: Possibilita ao usuário visualizar uma lista com os
arquivos que está compartilhando com outros usuários.
Requisitos atendidos RF10
Pré-condições O usuário deve estar autenticado no sistema.
Cenário principal 1) o sistema carrega do cartão SD o arquivo que contém a lista de
arquivos compartilhados do usuário;
2) o sistema apresenta uma tela contendo a lista dos arquivos já
compartilhados pelos usuário, se houver algum, e um botão para
que usuário possa compartilhar outros arquivos.
Fluxo alternativo 01 No passo 2, caso o usuário pressione o botão voltar do dispositivo:
1) retorna para a tela principal do sistema.
Fluxo alternativo 02 No passo 2, caso o usuário pressione o botão de compartilhamento
de arquivos:
1) executa o caso de uso UC08
Fluxo alternativo 03 No passo 2, caso o usuário pressione em um dos arquivos
compartilhados:
1) executa o caso de uso UC09
Pós-condições A lista de arquivos compartilhados do usuário é apresentada.
Quadro 8 – Caso de uso Visualizar arquivos compartilhados
3.2.1.8 Compartilhar um arquivo
O caso de uso Compartilhar um arquivo objetiva apresentar uma tela onde o usuário
possa visualizar a estrutura de pastas e arquivos do cartão SD do seu dispositivo e selecionar
um para ser compartilhado com os outros usuários do sistema. O Quadro 9 contém os cenários
do caso de uso Compartilhar um arquivo.
43
UC08. Compartilhar um arquivo: Possibilita ao usuário selecionar arquivos do dispositivo
móvel para compartilhar com outros usuários do sistema.
Requisitos atendidos RF10 e RF27
Pré-condições O usuário deve estar autenticado no sistema.
Cenário principal 1) o sistema apresenta a estrutura de pastas do cartão SD do
dispositivo do usuário;
2) o usuário navega nesta estrutura e seleciona um arquivo;
3) o sistema solicita confirmação para compartilhar o arquivo;
4) o sistema envia o arquivo para o webservice;
5) o sistema atualiza a lista de arquivos compartilhados do usuário.
Fluxo alternativo 01 No passo 1 ou 2, caso o usuário pressione o botão voltar do
dispositivo:
1) retorna para a tela principal do sistema.
Fluxo alternativo 02 No passo 3, caso o usuário não confirme o compartilhamento do
arquivo:
1) retorna para a tela principal do sistema.
Fluxo alternativo 03 No passo 5, caso o compartilhamento ocorra com sucesso:
1) o sistema apresenta uma mensagem informando que o arquivo
foi compartilhado;
Exceção 01 No passo 4, caso ocorra um erro de conexão com o webservice:
1) o sistema apresenta uma mensagem informando que ocorreu um
erro na conexão com o webservice durante o compartilhamento
do arquivo;
2) retorna para a tela principal do sistema.
Pós-condições A lista de arquivos compartilhados é atualiza com o novo arquivo
compartilhado.
Quadro 9 – Caso de uso Compartilhar um arquivo
3.2.1.9 Remover compartilhamento de arquivo
O caso de uso Remover compartilhamento de arquivo permite que o usuário
interrompa o compartilhamento de um arquivo previamente selecionado para
compartilhamento. O Quadro 10 contém os cenários do caso de uso Remover
compartilhamento de arquivo.
44
UC09. Remover compartilhamento de arquivo: Possibilita ao usuário selecionar um dos
arquivos que está compartilhando e remover o compartilhamento do mesmo.
Requisitos atendidos RF11
Pré-condições O usuário deve estar autenticado no sistema e compartilhando pelo
menos um arquivo.
Cenário principal 1) o sistema solicita ao usuário confirmação da interrupção de
compartilhamento do arquivo;
2) o sistema envia ao webservice solicitação para remoção de
compartilhamento de arquivo;
3) o sistema atualiza o arquivo com a lista de arquivos
compartilhados;
4) o sistema atualiza na tela a lista de arquivos compartilhados.
Fluxo alternativo 01 No passo 1, caso o usuário não confirme a remoção de
compartilhamento:
1) retorna a tela de arquivos compartilhados.
Exceção 01 No passo 2, caso ocorra um erro de conexão com o webservice:
1) o sistema apresenta uma mensagem informando que ocorreu um
erro na conexão com o webservice durante o compartilhamento
do arquivo;
2) retorna para a tela de arquivos compartilhados.
Pós-condições A lista de arquivos compartilhados é atualizada em tela, sem o
arquivo que foi removido o compartilhamento.
Quadro 10 – Caso de uso Remover compartilhamento de arquivo
3.2.1.10 Listar arquivos compartilhados de um usuário
O caso de uso Listar arquivos compartilhados de um usuário objetiva
apresentar ao usuário uma lista de arquivos, com seus respectivos tamanhos e Uniform
Resource Locators (URLs), que um usuário está compartilhando. O Quadro 11 contém os
cenários do caso de uso Listar arquivos compartilhados de um usuário.
45
UC10. Listar arquivos compartilhados de um usuário: Possibilita ao usuário visualizar os
arquivos que um usuário está compartilhando bem como o tamanho de cada um destes
arquivos.
Requisitos atendidos RF08 e RF28
Pré-condições O usuário deve estar autenticado no sistema
Cenário principal 1) o sistema solicita ao webservice a lista dos arquivos
compartilhados do usuário;
2) se o usuário estiver compartilhando algum, será listado na tela.
Fluxo alternativo 01 No passo 1, caso o usuário não confirme a remoção de
compartilhamento:
1) retorna a tela de arquivos compartilhados.
Exceção 01 No passo 1, caso ocorra um erro de conexão com o webservice:
1) o sistema apresenta uma mensagem informando que ocorreu um
erro na conexão com o webservice;
2) retorna para a tela principal do sistema.
Pós-condições A lista de arquivos compartilhados do usuário é apresentada.
Quadro 11 – Caso de uso Listar arquivos compartilhados de um usuário
3.2.1.11 Realizar download de um arquivo
O caso de uso Realizar download de um arquivo permite que o usuário realize o
download de um arquivo compartilhado de um usuário, este processo é iniciado na tela de
arquivos compartilhados de um usuário. O Quadro 12 contém os cenários do caso de uso
Realizar download de um arquivo.
46
UC11. Realizar download de um arquivo: Possibilita ao usuário realizar o download de um
arquivo compartilhado por outro usuário.
Requisitos atendidos RF09
Pré-condições O usuário deve estar autenticado no sistema, com pelo menos um
usuário com arquivos compartilhados em sua lista.
Cenário principal 1) o sistema apresenta ao usuário a lista de arquivos compartilhados
do usuário;
2) o usuário escolhe o arquivo que deseja realizar o download;
3) o sistema solicita confirmação do download;
4) o sistema realiza o download do arquivo e grava no dispositivo
móvel do usuário;
Fluxo alternativo 01 No passo 1, caso o usuário pressione o botão voltar do dispositivo:
1) retorna a tela principal do sistema.
Fluxo alternativo 02 No passo 3, caso o usuário não confirme o download:
1) retorna a tela de arquivos compartilhados do usuário.
Fluxo alternativo 03 No passo 4, caso o download é concluído com sucesso:
1) o sistema apresenta uma mensagem informando que o download
foi concluído com sucesso.
Exceção 01 No passo 4, caso ocorra um erro de conexão com o webservice:
1) o sistema apresenta uma mensagem informando que ocorreu um
erro na conexão com o webservice;
2) retorna para a tela de arquivos compartilhados do usuário.
Exceção 02 No passo 4, caso ocorra um erro na gravação do arquivo para o
cartão SD:
1) o sistema apresenta uma mensagem informando que ocorreu erro
na gravação do arquivo para o cartão SD;
2) Retorna para a tela de arquivos compartilhados do usuário.
Pós-condições Nenhuma
Quadro 12 – Caso de uso Realizar download de um arquivo
3.2.1.12 Efetuar logoff
O caso de uso Realizar download de um arquivo permite que o usuário realize o
download de um arquivo compartilhado de um usuário, este processo é iniciado na tela de
arquivos compartilhados de um usuário. O Quadro 13 contém os cenários do caso de uso
Efetuar logoff.
47
UC12. Efetuar logoff: Descreve as ações executadas quando o usuário opta por sair do
sistema.
Requisitos atendidos RF15
Pré-condições O usuário deve estar autenticado no sistema
Cenário principal 1) o sistema interrompe o serviço de obtenção das coordenadas de
geolocalização;
2) o sistema interrompe o serviço de busca de usuários e
mensagens;
3) o sistema encaminha ao webservice a solicitação de logoff do
usuário;
Fluxo alternativo 01 No passo 3, caso o logoff é concluído com sucesso:
1) o sistema retorna a tela de login.
Exceção 01 No passo 3, caso ocorra um erro na conexão com o webservice:
1) Não é apresentada uma mensagem, pois a sessão será destruída
posteriormente pelo servidor devido falta de atividade.
Pós-condições Nenhuma
Quadro 13 – Caso de uso Efetuar logoff
3.2.1.13 Recuperar coordenadas geográficas do usuário
Um dos principais requisitos do sistema é permitir a interação de usuários que estejam
geograficamente próximos, para que isto seja possível, o primeiro passo é obter os dados de
geolocalização dos usuários. O Quadro 14 contém os cenários do caso de uso Recuperar
coordenadas geográficas do usuário.
UC13. Recuperar coordenadas geográficas do usuário: Descreve as ações executadas para
recuperação das coordenadas de geolocalização do usuário.
Requisitos atendidos RF12
Pré-condições O usuário deve estar autenticado no sistema
Cenário principal 1) o sistema inicializa os listeners de geolocalização para satélites
GPS e para localização via torres de telefonia;
2) o sistema recupera a coordenada do usuário e grava em variáveis
internas;
3) executa o caso de uso UC14;
Fluxo alternativo 01 No passo 2, caso a coordenada seja proveniente das torres de
telefonia e a ultima coordenada também foi obtida desta forma:
1) o sistema analisa se já se passaram 5 segundos desde a ultima
coleta;
2) se sim a nova coordenada é armazenada e enviada ao
webservice;
3) se não, ela é ignorada e consequentemente não é enviado ao
webservice;
Pós-condições Nenhuma
Quadro 14 – Caso de uso Recuperar coordenadas geográficas do usuário
48
3.2.1.14 Envia coordenadas geográficas do usuário para o servidor
Após o sistema ter obtido as coordenadas geográficas do usuário é necessário envia-las
ao servidor para que seja calculado a sua distância em relação aos outros usuários do sistema.
O Quadro 15 contém os cenários do caso de uso Envia coordenadas geográficas do
usuário para o servidor.
UC14. Envia coordenadas geográficas do usuário para o servidor: O sistema transmite para o
webservice as coordenadas geográficas do dispositivo do usuário.
Requisitos atendidos RF13, RF18 e RF25
Pré-condições O usuário deve estar autenticado no sistema e a coordenada de
geolocalização do usuário obtida.
Cenário principal 1) o sistema envia as coordenadas ao webservice.
Exceção 01 No passo 1, caso ocorra um erro na conexão com o webservice:
1) o sistema apresenta uma mensagem informado que não pode
enviar os dados de geolocalização ao webservice;
Pós-condições Nenhuma
Quadro 15 – Caso de uso Envia coordenadas geográficas do usuário para o servidor
3.2.1.15 Atualiza lista de usuários próximos
Constantemente enquanto o usuário utiliza o sistema é verificado se existem outros
usuários próximos, esta tarefa é desempenhada em segundo plano pelo sistema instalado no
dispositivo móvel. O Quadro 16 contém os cenários do caso de uso Atualiza lista de
usuários próximos.
49
UC15. Atualiza lista de usuários próximos: Recupera uma lista contendo o nome e a
distancia dos usuários próximos do usuário solicitante.
Requisitos atendidos RF04 e RF05
Pré-condições O usuário deve estar autenticado no sistema e a coordenada de
geolocalização do usuário obtida.
Cenário principal 1) o sistema solicita a lista dos usuários que estão próximos do
usuário solicitante;
2) o webservice solicita ao servidor esta lista;
3) o servidor aplica a formula de Haversine para encontrar os
usuários que estão próximos do usuário solicitante;
4) o servidor repassa a lista para o webservice;
5) o webservice repassa a lista para o usuário solicitante.
Fluxo alternativo 01 No passo 5 caso não ocorra uma exceção:
1) A nova lista de usuários substitui a lista atual.
Exceção 01 No passo 1, caso ocorra um erro na conexão com o webservice:
1) o sistema apresenta uma mensagem informado que não pode
recuperar a lista de usuários próximos devido falha de conexão
com o webservice;
Exceção 02 No passo 2 ou 4 caso ocorra um erro na conexão entre o webservice
e o servidor:
1) Uma lista vazia é retornada ao usuário;
2) O erro gerado na conexão é gravado nos logs do servidor de
aplicações.
Pós-condições A nova lista de usuários próximos é apresentada.
Quadro 16 – Caso de uso Atualiza lista de usuários próximos
3.2.1.16 Gerar notificação para mensagem recebida
Além da atualização da lista de usuários próximos, o sistema constantemente busca por
mensagens que possam ter sido enviadas para o usuário solicitante, e caso o usuário não esteja
já em conversa com o autor da mensagem, esta é apresentada como uma notificação do
sistema Android. O Quadro 17 contém os cenários do caso de uso Gerar notificação para
mensagem recebida.
50
UC16. Gerar notificação para mensagem recebida: O sistema busca as mensagens enviadas
para o usuário solicitante e gera notificações para elas.
Requisitos atendidos RF16
Pré-condições O usuário deve estar autenticado no sistema e a coordenada de
geolocalização dele obtida.
Cenário principal 1) o sistema solicita a lista de mensagens recebidas para o
webservice;
2) o webservice solicita ao servidor esta lista;
3) o servidor retorna a lista de mensagens ao webservice;
4) o servidor remove da lista as mensagens que repassou ao
webservice;
5) o webservice repassa a lista para o usuário solicitante.
Fluxo alternativo 01 No passo 5 caso não ocorra uma exceção e a mensagem tiver sido
enviada por um usuário com o qual o usuário solicitante está
conversando:
1) A nova mensagem é apresentada na área de conversa da tela.
Fluxo alternativo 02 No passo 5 caso não ocorra uma exceção e a mensagem tiver sido
enviada por um usuário com o qual o usuário solicitante não está
conversando:
1) A nova mensagem é apresentada na barra de notificações do
sistema.
2) Ao pressionar sobre esta notificação, o usuário é levado a tela de
conversa com o usuário que enviou a mensagem.
Exceção 01 No passo 1, caso ocorra um erro na conexão com o webservice:
2) o sistema apresenta uma mensagem informado que não pode
recuperar a lista de mensagens devido falha de conexão com o
webservice;
Exceção 02 No passo 2 ou 4 caso ocorra um erro na conexão entre o webservice
e o servidor:
3) Uma lista vazia é retornada ao usuário;
4) O erro gerado na conexão é gravado nos logs do servidor de
aplicações.
Pós-condições A mensagem é apresentada ou uma notificação criada para o usuário
Quadro 17 – Caso de uso Gerar notificação para mensagem recebida
3.2.1.17 Cria sessão para usuário autenticado
Quando um usuário autentica-se no sistema é criado um objeto de Sessão na parte
servidor. Este objeto armazena as coordenadas geográficas do usuário e data do ultimo
contato do mesmo. O Quadro 18 contém os cenários do caso de uso Cria sessão para
usuário autenticado.
51
UC17. Cria sessão para usuário autenticado: O sistema cria um objeto de sessão para
armazenar as coordenadas geográficas do usuário e a data do ultimo contato do mesmo.
Requisitos atendidos RF17
Pré-condições Nenhuma
Cenário principal 1) o sistema recebe o código do usuário a ser criado a sessão;
2) o sistema verifica se já existe uma sessão para o usuário criado;
3) o sistema retorna verdadeiro se conseguiu criar a sessão do
usuário, falso do contrário.
Fluxo alternativo 01 No passo 2 caso não exista previamente uma sessão do usuário:
1) o sistema cria o objeto de sessão e retorna verdadeiro ao
webservice.
Fluxo alternativo 02 No passo 2 caso exista previamente uma sessão do usuário:
1) o sistema verifica que se o ultimo contato do usuário já faz mais
de 5 minutos.
2) Se sim utiliza esta sessão como sessão corrente do usuário;
3) Se não, retorna falso ao webservice, informando que não foi
possível criar a sessão do usuário.
Exceção 01 No passo 1 e 3, caso ocorra um erro na conexão com o webservice:
1) A mensagem da exceção é gravada nos logs do servidor
aplicações;
2) É informado ao usuário que não foi possível autenticar no
sistema devido falha no servidor da aplicação.
Pós-condições Nenhum
Quadro 18 – Caso de uso Cria sessão para usuário autenticado
3.2.1.18 Remove sessão de usuário inativo
Ao terminar o uso do sistema, o mesmo envia uma solicitação de logoff, para que o
usuário em questão deixe de constar na lista de usuários próximos de outros usuários. No
entanto pode ocorrer de um usuário desligar seu dispositivo móvel, ou ainda o mesmo ficar
sem bateria, nestes casos o servidor percebe que o usuário está sem atividade a um certo
tempo e o considera como inativo. O Quadro 19 contém os cenários do caso de uso Remove
sessão de usuário inativo.
UC18. Remove sessão de usuário inativo: O sistema marca sessões como inativas caso não
tenha ocorrido uma comunicação nos últimos 5 minutos.
Requisitos atendidos RF21
Pré-condições Existirem usuários autenticados no sistema
Cenário principal 1) o sistema verifica uma a uma todas as sessões criadas;
2) caso a sessão esteja a 5 minutos ou mais sem comunicar é
marcada como inativa;
Pós-condições Nenhum
Quadro 19 – Caso de uso Remove sessão de usuário inativo
52
3.2.2 Componentes do aplicativo cliente
Considerando o modelo de desenvolvimento em torno dos componentes básicos da
plataforma Android, o aplicativo cliente foi organizado em activities, tasks e services. Para
atender aos requisitos apresentados, os componentes responsáveis pela interação com o
usuário foram definidos como especializações de activities. Os outros componentes definidos
não possuem interação com o usuário, porém efetuam processamentos periódicos de
atualização de informações. Esses últimos foram definidos como especializações de services e
tasks.
A representação dos componentes definidos foi feita através de um diagrama de
componentes da UML. No diagrama, as activities são representadas com o estereótipo
Activity. As tasks são representadas com o estereótipo Task. Por fim os services são
apresentados com o estereótipo Service. A Figura 8 contém o diagrama de componentes do
aplicativo cliente.
53
Figura 8 – Componentes do aplicativo cliente
A activity LoginUsuario é responsável pela inicialização da aplicação e por permitir
que o usuário autentique-se no sistema. A partir dela o usuário pode também acessar a activity
de cadastro de usuários (CadastroUsuario) e a activity de configurações do sistema
(Configuracoes). Na activity de cadastro de usuários serão apresentados os campos para que
o usuário preencha seu nome, seu nome de acesso (login) e sua senha, uma vez preenchido
estes campos e pressionado o botão “OK” é disparada a task RegistroTask que enviará os
dados preenchidos para o webservice do sistema para analise enquanto apresenta em tela uma
mensagem de aguarde. Na activity de configurações do sistema, é possível definir um
endereço Internet Protocol (IP) e uma porta, para acessar o webservice do sistema, assim
54
como voltar para os valores padrões do sistema, caso ocorra alteração o sistema gravará estes
dados no cartão SD do dispositivo móvel.
Na activity LoginUsuario, caso o usuário informe seus dados de acesso e pressione o
botão “Login” será executado a task Login que enviará ao webservice os dados de
autenticação e aguardará o retorno da validação destes dados, enquanto apresenta em tela uma
mensagem de aguarde. Caso ocorra com sucesso a autenticação, a task Login inicia a activity
AtividadePrincipal, do contrário apresenta na activity LoginUsuario uma mensagem
informado a razão da falha de autenticação.
A activity AtividadePrincipal, como o nome sugere é a principal do sistema, por
conter os meios de o usuário realizar as principais tarefas propostas pelo trabalho, é através
dela que é possível visualizar os usuários que estão próximos e definir a distância limite para
visualização de usuários. A partir dela é possível também iniciar uma conversa com um
usuário (AtividadeConversa), visualizar os arquivos compartilhados por um usuário
(ArquivosUsuario), alterar a senha de acesso ao sistema (AtividadeAlteracaoSenha) e
visualizar os arquivos que estão sendo compartilhados (MeusArquivos).
Quando inicializada ela inicia a execução em segundo plano dos services
Geolocalização, responsável por interagir com o dispositivo GPS para manter atualizada a
posição do usuário no sistema, e Sincronização, responsável por manter atualizada a lista
dos usuários próximos e recuperar as mensagens enviadas por outros usuários.
Até que o service Geolocalização consiga as primeiras coordenadas do usuário a task
AguardarGPS executa apresentando a mensagem aguarde para o usuário, após é executada a
task ProcurarUsuarios para iniciar a lista de usuários próximos baseado nas coordenadas
recém obtidas.
A task ProcurarUsuarios também pode ser executada manualmente através do botão
de atualização localizado no canto superior direito da activity AtividadePrincipal.
Quando finalizada a activity AtividadePrincipal dispara a task Logout, que envia
um aviso ao webservice de que o usuário está saindo do sistema.
A activity AtividadeAlteracaoSenha permite que o usuário informe sua senha atual
e defina uma nova senha para acessar o sistema, ela dispara a task AlterarSenha que realiza
a comunicação com o webservice informando que o usuário quer trocar sua senha e recebe a
resposta se a ação foi realizada com sucesso ou não.
A activity MeusArquivos permite ao usuário visualizar os arquivos que está
compartilhando, escolher novos arquivos para compartilhar ou cancelar o compartilhamento
55
de algum. Quando o usuário escolhe um novo arquivo para compartilhar é executado a task
EnviarArquivo, responsável por fazer o upload do arquivo ao webservice do sistema. Caso o
usuário cancele o compartilhamento de um arquivo é executado então a task
RemoverArquivo, que informa ao webservice que o arquivo não é mais compartilhado pelo
usuário.
A activity AtividadeConversa é responsável por permitir que o usuário envie
mensagens a um determinado usuário e visualize as mensagens enviadas por este mesmo
usuário. Sempre que uma mensagem é enviada pelo usuário, a task EnviarMensagem é
disparada, realizando a conexão com o webservice para fazer a transferência da mensagem.
Esta task não apresenta uma ação em tela, logo, o usuário não tem conhecimento da sua
execução.
Por fim, a activity ArquivosUsuario é responsável por apresentar ao usuário a lista de
arquivos compartilhados de um determinado usuário e permitir que seja realizado o download
destes arquivos. Ao ser iniciada ela dispara a task RecuperarArquivosUsuario que solicita
ao webservice a lista com nome, tamanho e URL dos arquivos compartilhados pelo usuário,
enquanto apresenta ao usuário uma mensagem de aguarde. Quando o usuário escolhe o
arquivo que vai realizar o download, é disparada então a task DownloadArquivo, responsável
por realizar o download do arquivo em questão enquanto apresenta em tela uma mensagem de
aguarde.
3.2.3 Classes do aplicativo cliente
Partindo da definição dos componentes do aplicativo cliente, os mesmos foram
organizados em pacotes e classes, de acordo com a proximidade das funções e dos tipos de
componentes. Os componentes do tipo activity são implementados como classes que
estendem android.app.Activity. Com a finalidade de simplificar os diagramas e facilitar a
visualização, essas classes são representadas com o estereótipo Activity. Os services são
implementados como classes que estendem android.app.Service. Nos diagramas, os
services são representados com o estereótipo Service. As tasks são implementadas como
classes que estendem android.os.AsyncTask. Nos diagramas, as tasks são representadas
com o estereótipo AsyncTask. Cada aplicação Android é estruturada sob um pacote raiz, que
deve ser único no dispositivo. Assim, a aplicação foi implementada sob o pacote
56
br.com.cesar.tcc2. A Figura 9 apresenta o diagrama do pacote raiz da aplicação cliente.
Figura 9 – Pacote br.com.cesar.tcc2 do aplicativo cliente
É importante observar que não há conexões entre activities ou activities e services no
diagrama de classes. A navegação entre as activities é feita através de intents, que não tem
referência direta às classes. O pacote raiz contém todas as activities do sistema, sendo o inicio
57
da aplicação realizado pela classe LoginUsuario.
3.2.3.1 Pacote br.com.cesar.tcc2.task
As classes relativas às tasks foram implementadas no pacote
br.com.cesar.tcc2.task. A Figura 10 contém o diagrama de classes do pacote
br.com.cesar.tcc2.task.
A classe abstrata TaskPadrao é a única que é extensão direta de AsyncTask, todas as
outras são extensões dela.
O método onPreExecute é utilizado para mostrar uma progressDialog ao usuário
solicitando que aguarde a tarefa ser concluída.
O método doInBackground é utilizado com frequência para comunicação com o
webservice, o que pode demorar dependendo da velocidade da conexão de Internet do usuário.
Por fim, o método onPostExecute é usado para interromper o progressDialog que é
apresentado ao usuário e avaliar se a tarefa da task foi concluída com sucesso ou não.
58
class br.com.cesar.tcc2.task
AsyncTask
TaskPadrao
- acao: String = ""
# progressDialog: ProgressDialog = null
- titulo: String = ""
# umContexto: Context
# doInBackground(Void) : Void
# onPostExecute(Void) : void
# onPreExecute() : void
+ TaskPadrao(Context, String, String)
Remov erArquiv o
{leaf}
- erro: String = null
- resultado: int = 0
- umArquivo: Arquivo = null
# doInBackground(Void) : Void
# onPostExecute(Void) : void
+ RemoverArquivo(Context, Arquivo)
RecuperarArquiv osUsuario
- arrayArquivos: Arquivo ([]) = null
- erro: String = null
- umUsuario: Usuario = null
# doInBackground(Void) : Void
# onPostExecute(Void) : void
+ RecuperarArquivosUsuario(Context, Usuario)
ProcurarUsuarios
- arrayUsuarios: Usuario ([]) = null
- erro: String = null
- l istView: ListView = null
- sincronizandoPeloServico: boolean = false
# doInBackground(Void) : Void
# onPostExecute(Void) : void
+ ProcurarUsuarios(Context, ListView)
Logout
{leaf}
- codigoUsuario: int = -1
# doInBackground(Void) : Void
+ Logout(Context, int)
# onPostExecute(Void) : void
# onPreExecute() : void
Login
- erro: String = ""
- login: String = null
- resultado: int = -2
- senha: String = null
# doInBackground(Void) : Void
+ Login(Context, String, String)
# onPostExecute(Void) : void
Env iarMensagem
{leaf}
- erro: String = null
- mensagem: String = null
- umaConversa: Conversa = null
# doInBackground(Void) : Void
+ EnviarMensagem(Context, Conversa, String)
# onPostExecute(Void) : void
# onPreExecute() : void
Env iarArquiv o
{leaf}
- arquivoAEnviar: File = null
- erro: String = null
- resultado: int = 0
- carregarArquivo() : byte[]
# doInBackground(Void) : Void
+ EnviarArquivo(Context, File)
# onPostExecute(Void) : void
DownloadArquiv o
- erro: String = null
- nomeArquivo: String = null
- nomeUsuario: String = null
- urlArquivo: String = null
- urlLocal: String = null
# doInBackground(Void) : Void
+ DownloadArquivo(Context, String, String, String)
- downloadArquivo() : ByteArrayBuffer
- gravarArquivoSD(ByteArrayBuffer) : void
# onPostExecute(Void) : void
- validarEstruturaPastas() : boolean
AlterarSenha
{leaf}
- erro: String = null
- resultado: int = 0
- senhaAtual: String = null
- senhaNova: String = null
+ AlterarSenha(Context, String, String)
# doInBackground(Void) : Void
# onPostExecute(Void) : void
AguardarGPS
{leaf}
+ AguardarGPS(Context)
# doInBackground(Void) : Void
Figura 10 – Pacote br.com.cesar.tcc2.task
59
3.2.3.2 Pacote br.com.cesar.tcc2.adapter
O pacote br.com.cesar.tcc2.adapter possui todas as classes de adapters do
sistema e todas estendem a classe BaseAdapter.
A classe ConversaAdapter é responsável por definir o formato de cada item da lista
de conversas que o usuário tem em aberto.
A classe UsuarioAdapter é responsável por definir o formato de cada item da lista de
usuários próximos.
A classe RowViewHolder é utilizada pela classe UsuarioAdapter para permitir que
dois botões possam ser inseridos em cada linha da lista de usuários próximos. Um botão é
utilizado para iniciar a troca de mensagens com o usuário e outro para visualizar os arquivos
que o usuário está compartilhando.
A classe ArquivoAdapter é responsável por definir o formato de cada item da lista de
arquivos compartilhados. Ela é utilizada tanto na listagem de arquivos compartilhados do
usuário do sistema, quando dos usuários que ele pode visualizar.
A Figura 11 contém o diagrama de classes do pacote br.com.cesar.tcc2.adapter.
Figura 11 – Pacote br.com.cesar.tcc2.adapter
3.2.3.3 Pacote br.com.cesar.tcc2.ws
As classes do pacote br.com.cesar.tcc2.ws são responsáveis por realizar a conexão
60
com o webservice do sistema, provendo os meios das outras classes do sistema realizarem a
troca de informações com o mesmo.
A classe LocalSocialWS é a principal do pacote, pois é ela que implementa os
métodos específicos de cada funcionalidade do sistema que requer a comunicação com o
webservice. Para realizar a conexão com o webservice ela utiliza métodos da API kSOAP2.
A classe MarshalDouble foi criada para suprir uma deficiência da API kSOAP2 de
não permitir a transmissão de informações do tipo Double, ela provê os métodos necessários
para que a API compreenda este tipo de dado.
A Figura 12 apresenta as classes do pacote br.com.cesar.tcc2.ws.
class br.com.cesar.tcc2.ws
Marshal
MarshalDouble
+ readInstance(XmlPullParser, String, String, PropertyInfo) : Object
+ register(SoapSerializationEnvelope) : void
+ writeInstance(XmlSerializer, Object) : void
LocalSocialWS
{leaf}
- NAMESPACE: String = "http://ws.tcc2... {readOnly}
- URL: String = "http://" + Par... {readOnly}
+ alterarSenhaUsuario(int, String, String) : int
+ atualizarPosicaoUsuario(int, double, double) : void
+ autenticarUsuario(String, String) : int
+ deletarArquivoUsuario(int, String) : int
+ desconectarUsuario(int) : void
- getResponse(SoapObject) : Object
- getResponse(SoapObject, MarshalDouble) : Object
- getResponse(SoapObject, MarshalBase64) : Object
- getSoapObject(String) : SoapObject
+ gravarMensagemUsuario(int, int, String, String, double) : void
+ recuperarListaArquivosUsuario(int) : Arquivo[]
+ recuperarListaUsuarios(int, int) : Usuario[]
+ recuperarMensagensUsuario(int) : Mensagem[]
+ registrarUsuario(String, String, String) : int
+ uploadArquivoUsuario(int, String, byte[]) : int
Figura 12 – Pacote br.com.cesar.tcc2.ws
3.2.3.4 Pacotes br.com.cesar.tcc2.service e br.com.cesar.tcc2.listener
O pacote br.com.cesar.tcc2.service contém as duas classes responsáveis pelas
atividades em segundo plano da aplicação.
Ambas são extensões de android.app.Service e ambas implementam a interface
java.lang.Runnable. Assim que inicializadas, ambas disparam uma segunda linha de
execução (Thread) onde suas atividades são desempenhadas.
A classe Georastreamento é encarregada de continuamente verificar a posição do
usuário através dos LocationListeners providos pelas classes
LocationListenerSatelite, responsável por recuperar a coordenada do usuário através de
um satélite GPS e LocationListenerNetwork, responsável por recuperar a coordenada do
61
usuário através das torres de telefonia, ambas pertencem ao pacote
br.com.cesar.tcc2.listener. Depois de obtida a coordenada do usuário ela transmite para
o webservice através da classe LocalSocialWS (vide 3.3.3.3).
A classe Sincronizacao tem como principais atividades manter atualizada a lista de
usuários próximos e recuperar as mensagens enviadas por outros usuários. Além disto, ela
também é responsável por criar notifications no Android para as mensagens enviadas por
outros usuários.
A Figura 13 apresenta as classes do pacote br.com.cesar.tcc2.service e a Figura
14 apresenta as classes do pacote br.com.cesar.tcc2.listener.
class br.com.cesar.tcc2.serv ice
Service
Runnable
Sincronizacao
{leaf}
- executar: boolean = true
- criarNotificacaoConversa(String, String, String, int) : void
+ onBind(Intent) : IBinder
+ onCreate() : void
+ onDestroy() : void
+ run() : void
Service
Runnable
Georastreamento
{leaf}
- executar: boolean = true
- mlocListenerNET: LocationListener = null
- mlocListenerSAT: LocationListener = null
- mlocManagerNET: LocationManager = null
- mlocManagerSAT: LocationManager = null
+ onBind(Intent) : IBinder
+ onCreate() : void
+ onDestroy() : void
+ run() : void
Figura 13 – Pacote br.com.cesar.tcc2.service
class br.com.cesar.tcc2.ws.listener
LocationListener
LocationListenerSatelite
{leaf}
+ onLocationChanged(Location) : void
+ onProviderDisabled(String) : void
+ onProviderEnabled(String) : void
+ onStatusChanged(String, int, Bundle) : void
LocationListener
LocationListenerNetwork
{leaf}
+ onLocationChanged(Location) : void
+ onProviderDisabled(String) : void
+ onProviderEnabled(String) : void
+ onStatusChanged(String, int, Bundle) : void
Figura 14 – Pacote br.com.cesar.tcc2.listener
3.2.3.5 Pacote br.com.cesar.tcc2.modelo
As classes disponibilizadas no pacote br.com.cesar.tcc2.modelo visam agrupar
informações que sejam comuns a algum artefato ou ator pertencente ao sistema. Todas elas
implementam a interface java.io.Serializable, o que permite que objetos destas classes
62
possam ser transmitidos via Internet.
A classe Usuario é utilizada para armazenar os dados de um usuário da aplicação,
objetos desta classe são transmitidos da parte servidor do sistema para a parte cliente através
da classe UsuarioWrapper.
A classe Mensagem é utilizada para armazenar os dados de uma mensagem enviada
para um determinado usuário, objetos desta classe são transmitidos da parte servidor para a
parte cliente através da classe MensagemWrapper.
A classe Arquivo é utilizada para armazenar os dados de um arquivo compartilhado de
um usuário. Esta classe é utilizada em duas situações distintas, no primeiro caso ela é utilizada
para armazenar dados dos arquivos que o usuário do aplicativo está compartilhando, no
segundo caso ela é utilizada para armazenar os dados dos arquivos que um determinado
usuário está compartilhando, neste caso objetos da classe são transmitidos da parte webservice
para a parte cliente através da classe ArquivoWrapper.
Por fim, a classe Conversa mantem os dados de uma conversa que o usuário está tendo
com outro usuário, inclusive uma lista com todas as mensagens que já foram trocadas entre
eles. Esta classe apesar de implementar a interface java.io.Serializable, não é transmitida
via Internet, mas é transmitida entre as activities AtividadePrincipal e
AtividadeConversa, o que demanda a implementação da interface em questão.
A Figura 15 apresenta as classes do pacote br.com.cesar.tcc2.modelo.
63
class br.com.cesar.tcc2.modelo
java.io.Serializable
UsuarioWrapper
- arrayUsuarios: Usuario ([]) = null
- serialVersionUID: long = 8530548992372871283L {readOnly}
+ getArrayUsuarios() : Usuario[]
+ setArrayUsuarios(Usuario[]) : void
Serializable
Usuario
- codigo: int = -1
- distancia: double = 0d
- login: String = null
- serialVersionUID: long = 3233920660509249025L {readOnly}
+ getCodigo() : int
+ getDistancia() : double
+ getLogin() : String
+ setDistancia(double) : void
+ Usuario(int, String)
MensagemWrapper
- arrayMensagem: Mensagem ([]) = null
+ getArrayMensagem() : Mensagem[]
+ setArrayMensagem(Mensagem[]) : void
Serializable
Mensagem
{leaf}
- codigoUsuario: int = -1
- distancia: double = 0d
- loginUsuario: String = null
- mensagem: String = null
- serialVersionUID: long = 2540937528655550165L {readOnly}
+ getCodigoUsuario() : int
+ getDistancia() : double
+ getLoginUsuario() : String
+ getMensagem() : String
+ Mensagem(int, String, String, double)
Serializable
Conv ersa
{leaf}
- apelidoUsuario: String = null
- ativa: boolean = false
- codigoUsuario: int = -1
- distanciaUsuario: double = 0D
- historicoConversa: ArrayList<String> = new ArrayList<S... {readOnly}
- serialVersionUID: long = 1L {readOnly}
+ addLinhaConversa(String) : void
+ Conversa(int, String, double)
+ getApelidoUsuario() : String
+ getCodigoUsuario() : int
+ getDistanciaUsuario() : double
+ getHistoricoConversa() : ArrayList<String>
+ isAtiva() : boolean
+ setAtiva(boolean) : void
+ setDistanciaUsuario(double) : void
Serializable
Arquiv oWrapper
- arrayArquivos: Arquivo ([]) = null
- serialVersionUID: long = 5462423978431849678L {readOnly}
+ ArquivoWrapper(Arquivo[])
+ getArrayArquivos() : Arquivo[]
Serializable
Arquiv o
{leaf}
- nome: String = null
- tamanho: long = 0L
- caminho: String = null
- serialVersionUID: long = 4479755469128441904L {readOnly}
+ Arquivo(String, long, String)
+ getNome() : String
+ getTamanho() : long
+ getCaminho() : String
-arrayArquivos
-arrayMensagem
-arrayUsuarios
Figura 15 – Pacote br.com.cesar.tcc2.modelo
3.2.3.6 Pacote br.com.cesar.tcc2.util
O pacote br.com.cesar.tcc2.util é responsável por armazenar duas classes cujos
64
propósitos são fornecer atributos e métodos que possam ser utilizados por qualquer outra
classe do sistema.
Todos atributos e métodos destas classes são estáticos, o que permite que as outras
classes os utilizem sem a necessidade de instanciar um objeto destas classes.
A Figura 16 apresenta as classes do pacote br.com.cesar.tcc2.util.
class br.com.cesar.tcc2.util
Util
{leaf}
+ formatarDouble(double, String) : String
+ criptografarSenha(String) : String
+ formatarDistancia(double) : String
+ formatarTamanhoArquivo(long) : String
+ recuperarArrayArquivos() : Arquivo[]
+ carregarArquivoParametros() : void
+ gravarAlteracoes() : void
+ gravarListaArquivos() : void
+ carregarArquivoCompartilhados() : void
+ recuperarArrayConversas() : Conversa[]
Parametros
{leaf}
+ PORTA_WEBSERVICE: int = 8080 {readOnly}
+ URL_WEBSERVICE: String = "192.168.0.185" {readOnly}
+ CAMINHO_PASTA_APLICACAO: String = Environment.get... {readOnly}
+ CAMINHO_PASTA_DOWNLOADS: String = Environment.get... {readOnly}
+ CAMINHO_ARQUIVO_CONFIGURACAO: String = Environment.get... {readOnly}
+ CAMINHO_ARQUIVO_COMPARTILHADOS: String = Environment.get... {readOnly}
+ LIMITE_TAMANHO_ARQUIVO: long = 10485760L {readOnly}
+ sistemaInicializado: boolean = false
+ sistemaEmPausa: boolean = false
+ sincronizacaoEmAndamento: boolean = false
- codigoUsuario: int = Integer.MIN_VALUE
- apelidoUsuario: String = null
+ urlWebService: String = Parametros.URL_...
+ portaWebService: int = Parametros.PORT...
- origemAtualizacaoPosicao: int = -1
- dataUltimaAtualizacaoPosicao: long = 0L
- dataSincronizacaoUsuarios: long = 0L
- dataSincronizacaoMensagens: long = 0L
- latitudeUsuario: double = 0.0d
- longitudeUsuario: double = 0.0d
+ distanciaComunicacao: int = 100
+ hashConversas: HashMap<Integer,Conversa> = new HashMap<Int... {readOnly}
+ listaNotifications: ArrayList<Integer> = new ArrayList<I... {readOnly}
+ listaArquivosComparilhados: ArrayList<String> = new ArrayList<S... {readOnly}
+ getCodigoUsuario() : int
+ getApelidoUsuario() : String
+ getLatitudeUsuario() : double
+ getLongitudeUsuario() : double
+ getDataUltimaAtualizacaoPosicao() : long
+ getDataSincronizacaoUsuarios() : long
+ getDataSincronizacaoMensagens() : long
+ setCodigoUsuario(int) : void
+ setApelidoUsuario(String) : void
+ setPosicaoUsuario(int, double, double) : void
+ atualizarDataSincronizacaoUsuarios() : void
+ atualizarDataSincronizacaoMensagens() : void
Figura 16 – Pacote br.com.cesar.tcc2.util
3.2.4 Classes do aplicativo webservice
Partindo da definição dos objetivos deste trabalho, cujo foco é a criação de um
aplicativo para a plataforma Android, o webservice foi desenvolvido com o propósito de
suprir algumas das necessidades apresentadas no aplicativo cliente e prover o meio de
comunicação entre o aplicativo cliente e o aplicativo servidor. As classes do webservice foram
desenvolvidas no pacote br.com.cesar.tcc2 em um projeto separado do aplicativo cliente.
A classe LocalSocial é a principal do aplicativo webservice, pois é ela que
65
implementa os métodos que são disponibilizados ao aplicativo cliente através do servidor de
aplicações Tomcat.
O pacote br.com.cesar.tcc2.modelo é semelhante ao descrito no aplicativo cliente
(vide 3.3.3.5), somente não contendo a classe Conversa, exclusiva da parte cliente do sistema.
O pacote br.com.cesar.tcc2.server.rmi contém a interface com os métodos de
acesso remoto da parte servidor e será descrito com mais detalhes nos diagramas de classe da
parte servidor.
A Figura 17 apresenta o diagrama de classes do aplicativo webservice.
Figura 17 – Pacote br.com.cesar.tcc2 do aplicativo webservice
3.2.4.1 Pacote br.com.cesar.tcc2.dao
Os dados dos usuários bem como dos arquivos que são compartilhados pelos mesmos
são armazenados em um banco de dados Oracle, as classes que implementam o acesso e a
interação com este banco de dados são implementadas no pacote br.com.cesar.tcc2.dao.
A classe DAOFactory é utilizada para estabelecer a conexão com o banco de dados e
criar objetos da classe UsuarioDAO.
66
A classe UsuarioDAO implementa os métodos correspondentes à ações executadas no
banco de dados da aplicação, todos os métodos exigem que seja tratado a exceção
SQLException pela classe solicitante, não ficando a cargo dela o tratamento destas exceções.
A Figura 18 apresenta as classes do pacote br.com.cesar.tcc2.dao.
Figura 18 – Pacote br.com.cesar.tcc2.dao
3.2.5 Classes do aplicativo servidor
Assim como o webservice, o aplicativo servidor foi desenvolvido para suprir algumas
necessidades do aplicativo cliente. Ele tem como principais funções armazenar as sessões dos
usuários conectados no sistema e as mensagens trocadas entre estes usuários. As classes do
servidor foram desenvolvidas no pacote br.com.cesar.tcc2.server em um projeto
separado do aplicativo cliente.
O aplicativo servidor não troca mensagens diretamente com o aplicativo cliente,
somente com o aplicativo webservice, através da tecnologia RMI.
A inicialização é feita através da classe Inicio, que registra os métodos remotos com
o aplicativo RMIRegistry e inicia em uma nova thread o controle de sessões através da classe
ControleSessoes.
A Figura 19 apresenta as classes do pacote br.com.cesar.tcc2.server.
67
Figura 19 – Pacote br.com.cesar.tcc2.server
O pacote br.com.cesar.tcc2.server.util contém uma única classe que contém
um único método cujo propósito é calcular a distancia entre dois usuários baseado nas
coordenadas geográfica de ambos utilizando a formula matemática de Haversine.
A Figura 20 apresenta a classe Util do pacote br.com.cesar.tcc2.server.util.
class br.com.cesar.tcc2.server.util
Util
{leaf}
- RAIO_TERRA: double = 6371d {readOnly}
+ aplicarFormulaHarversine(double, double, double, double) : double
Figura 20 – Pacote br.com.cesar.tcc2.server.util
Para permitir a troca de informações entre a parte servidor e a parte webservice foi
utilizado a tecnologia RMI, o pacote br.com.cesar.tcc2.server.rmi contém a interface
que é compartilhada com o aplicativo webservice (LocalSocialRMI) e a classe
(LocalSocialImpl) que implementa os métodos apresentados por esta interface.
A Figura 21 apresenta a classe e a interface do pacote
br.com.cesar.tcc2.server.rmi.
68
Figura 21 – Pacote br.com.cesar.tcc2.server.rmi
3.2.5.1 Pacote br.com.cesar.tcc2.server.controle e br.com.cesar.tcc2.server.lock
O pacote br.com.cesar.tcc2.server.controle contem as duas principais classes
do aplicativo servidor, ControleSessoes, destinada a armazenar as sessões dos usuários
conectados no sistema, bem como remover as sessões que estão inativas a 5 minutos ou mais
e a classe ControleMensagens, destinada a armazenar as mensagens trocadas entre os
usuários.
As sessões dos usuários ficam armazenados em um HashMap da classe
ControleSessoes, cada sessão é um objeto da classe Sessao (pacote
br.com.cesar.tcc2.modelo) e é indexada pelo código do usuário.
As mensagens trocadas entre os usuário ficam armazenadas em um objeto de HashMap
da classe ControleMensagens até serem recuperadas pelos usuários destinatários, após isto
são removidas, cada mensagem é um objeto da classe Mensagem (pacote
br.com.cesar.tcc2.modelo) e a lista de mensagens de um determinado usuário é indexada
no HashMap pelo código do usuário.
A Figura 22 apresenta o pacote br.com.cesar.tcc2.modelo do aplicativo servidor
69
class br.com.cesar.tcc2.modelo
Serializable
Mensagem
{leaf}
- serialVersionUID: long = 2540937528655550165L {readOnly}
- codigoUsuario: int = -1
- loginUsuario: String = null
- mensagem: String = null
- distancia: double = 0d
+ Mensagem(int, String, String, double)
+ getCodigoUsuario() : int
+ getLoginUsuario() : String
+ getMensagem() : String
+ getDistancia() : double
Serializable
Sessao
{leaf}
- serialVersionUID: long = -651870789602966885L {readOnly}
- codigoUsuario: int = -1
- loginUsuario: String = null
- ociosa: boolean = true
- inativa: boolean = false
- dataUltimoContato: long = System.currentT...
- valorLatitude: double = Double.MIN_VALUE
- valorLongitude: double = Double.MIN_VALUE
+ Sessao(int, String)
+ getCodigoUsuario() : int
+ getLoginUsuario() : String
+ getDataUltimoContato() : long
+ updateDataUltimoContato() : void
+ getValorLatitude() : double
+ setPosicao(double, double) : void
+ getValorLongitude() : double
+ isOciosa() : boolean
+ setOciosa(boolean) : void
+ isInativa() : boolean
+ setInativa(boolean) : void
Serializable
Usuario
- serialVersionUID: long = 3233920660509249025L {readOnly}
- codigo: int = -1
- login: String = null
- distancia: double = 0d
+ Usuario(int, String)
+ getCodigo() : int
+ getLogin() : String
+ getDistancia() : double
+ setDistancia(double) : void
Figura 22 – Pacote br.com.cesar.tcc2.modelo
Para evitar que o HashMap fique inconsistente e que alguma mensagem se perca, o
acesso a ele é feito mediante um bloqueio no mesmo. Este bloqueio é implementado através
da classe Lock do pacote br.com.cesar.tcc2.server.lock, a Figura 23 apresenta a classe
Lock.
class br.com.cesar.tcc2.serv er....
Lock
{leaf}
- isLocked: boolean = false
+ lock() : void
+ unlock() : void
Figura 23 – Pacote br.com.cesar.tcc2.server.lock
A Figura 24 apresenta o pacote br.com.cesar.tcc2.server.controle
70
class br.com.cesar.tcc2.serv er.controle
ControleMensagens
{leaf}
- hashMensagens: HashMap<Integer,ArrayList<Mensagem>> = new HashMap<Int... {readOnly}
- controleLock: Lock = new Lock() {readOnly}
+ adicionarMensagem(int, Mensagem) : void
+ recuperarListaMensagens(int) : ArrayList<Mensagem>
Thread
ControleSessoes
{leaf}
+ executar: boolean = true
- hashSessoes: HashMap<Integer,Sessao> = new HashMap<Int... {readOnly}
+ adicionarSessao(Sessao) : boolean
+ desconectarUsuario(int) : void
+ recuperarSessaoUsuario(int) : Sessao
+ atualizarPosicaoUsuario(int, double, double) : void
+ recuperarSessoes(int) : ArrayList<Sessao>
+ run() : void
Figura 24 – Pacote br.com.cesar.tcc2.server.controle
3.2.6 Diagramas de sequencia
Os diagramas de sequência tem como finalidade demonstrar a troca de mensagens
entre as classes criadas, facilitando a implementação dos casos de uso. Nesta seção são
apresentados os diagramas de sequência para os casos de uso Visualizar usuários
próximos da sua localização (UC05) e Compartilhar um arquivo (UC08).
3.2.6.1 Diagrama de sequencia Visualizar usuários próximos da sua localização
O caso de uso Visualizar usuários próximos da sua localização tem como
requisitos o usuário estar autenticado no sistema e já ter a sua localização geográfica obtida.
Assim o inicio da recuperação da lista de usuários próximos é inicializada pela activity
AtividadePrincipal que inicia em segundo plano a task ProcurarUsuarios. A lista de
usuários é mantida em uma variável da classe ControleSessoes do aplicativo servidor, o
acesso a essa classe pelo aplicativo cliente é feita via o aplicativo webservice.
Para realizar a conexão com o webservice é utilizado a classe LocalSocialWS do
71
aplicativo cliente, quem recepciona as solicitações feitas por ela é a classe LocalSocial do
aplicativo webservice, que por sua vez conecta-se ao aplicativo servidor via a interface
LocalSocialRMI.
A avaliação da distancia entre dois usuários é feita via a classe Util do aplicativo
servidor e a montagem da lista dos usuários é feita na classe LocalSocialImpl também do
aplicativo servidor.
A Figura 25 apresenta o diagrama de sequencia Visualizar usuários próximos da
sua localização.
72
Figura 25 – Diagrama de sequencia Visualizar usuários próximos da sua localização
73
3.2.6.2 Diagrama de sequencia Compartilhar um arquivo
O caso de uso Compartilhar um arquivo tem como requisito o usuário estar
autenticado no sistema. Assim o inicio da recuperação da lista de usuários próximos é
inicializada pela activity MeusArquivos onde o usuário pode visualizar os arquivos que já está
compartilhando, remover o compartilhamento de algum arquivo ou compartilhar novos
arquivos.
Para iniciar o compartilhamento de um arquivo o usuário deve pressionar o botão +
disponível em tela, este por sua vez irá apresentar uma dialog contendo a estrutura de pastas e
arquivos do cartão SD do dispositivo do usuário.
Após escolhido o arquivo a ser compartilhado será solicitado a confirmação do
compartilhamento, e uma vez confirmado é iniciado então a task EnviarArquivo que será
responsável por tratar o envio do arquivo ao webservice do sistema, através da classe
LocalSocialWS, enquanto apresenta ao usuário uma mensagem de aguarde.
A classe LocalSocial no webservice é que atendera o envio do arquivo, ela irá gravar
o arquivo no disco físico do servidor e irá criar uma referência ao arquivo no banco de dados,
vinculando ao código do usuário que está enviando, após isto responde ao aplicativo cliente
que o compartilhamento foi realizado com sucesso.
A task EnviarArquivo no aplicativo cliente irá receber a confirmação e atualizar a
lista de arquivos compartilhados que fica no cartão SD do dispositivo móvel, após feito isto
ela informa a activity MeusArquivos que o compartilhamento foi realizado com sucesso e o
usuário então é informado através de uma mensagem desta situação.
A Figura 26 apresenta o diagrama de sequencia Compartilhar um arquivo.
74
Figura 26 – Diagrama de sequencia Compartilhar um arquivo
75
3.2.7 Banco de dados
As informações dos usuários e dos arquivos que estes estão compartilhando ficam
armazenados em banco de dados Oracle no servidor do aplicativo webservice. A única classe
que interage com estas tabelas é a UsuarioDAO pertencente ao aplicativo webservice.
A Figura 27 apresenta o MER das tabelas do banco de dados do sistema.
dm Banco de Dados
LS_USUARIO
«column»
*PK CD_USUARIO: NUMBER(9)
* NM_USUARIO: VARCHAR2(200)
* DS_LOGIN: VARCHAR2(10)
* DS_SENHA: VARCHAR2(32)
* DT_CADASTRO: DATE
«PK»
+ PK_LS_USUARIO(NUMBER)
LS_ARQUIVOS
«column»
*pfK CD_USUARIO: NUMBER(9)
*PK NM_ARQUIVO: VARCHAR2(200)
* VL_ARQUIVO_TAM: NUMBER(20)
* DS_CAMINHO: VARCHAR(2000)
* DS_CAMINHO_LOCAL: VARCHAR2(2000)
* DT_UPLOAD: DATE
«FK»
+ FK_LS_ARQUIVOS_LS_USUARIO(NUMBER)
«PK»
+ PK_LS_ARQUIVOS(NUMBER, VARCHAR2)
+FK_LS_ARQUIVOS_LS_USUARIO
(CD_USUARIO = CD_USUARIO)
«FK»
+PK_LS_USUARIO
Figura 27 – MER das tabelas do banco de dados do sistema
A tabela LS_USUARIO armazena os dados dos usuários do sistema, ela é utilizada
sempre que um novo usuário é cadastrado, quando um usuário deseja autenticar-se no sistema
ou trocar sua senha.
A tabela LS_ARQUIVOS armazena os dados dos arquivos que os usuários estão
compartilhando, ela é utilizada sempre que um usuário deseja adicionar ou remover um
arquivo na sua lista de arquivos compartilhados, bem como quando deseja listar os arquivos
que outro usuário está compartilhando. Vale ressaltar que somente informações referentes os
arquivos compartilhados são gravados nesta tabela, os arquivos em si são armazenados em
diretórios externos e apenas uma referência dos mesmos é armazenada na tabela.
3.3 IMPLEMENTAÇÃO
A seguir são mostradas as técnicas e ferramentas utilizadas e a operacionalidade da
implementação.
76
3.3.1 Técnicas e ferramentas utilizadas
A implementação do sistema proposto foi efetuado em três partes, de forma paralela.
As funcionalidades propostas foram desenvolvidas em um aplicativo cliente, a ser executado
na plataforma Android. Para atender algumas das funcionalidades propostas no aplicativo
cliente foram desenvolvidos ainda um aplicativo webservice e um segundo aplicativo que
atende como servidor.
Para a implementação da aplicação cliente foi utilizado o ambiente de
desenvolvimento Eclipse, versão 3.7.2 (Indigo) combinado com o Android SDK, versão
2.1_r3. Esse ambiente foi executado sobre o Java Development Kit (JDK) versão 1.7.0 de 64
bits, para Microsoft Windows. Foi utilizado o nível 7 da API Android. Assim, o aplicativo
desenvolvido é compatível com a versão 2.1 do sistema operacional Android ou versões
superiores compatíveis. Para adicionar a capacidade de efetuar requisições SOAP foi
adicionada a biblioteca kSOAP2, versão 2.6.0. Essa biblioteca é fornecida pelo Massachusetts
Institute of Techonology (MIT). Os testes do aplicativo cliente foram efetuados em
dispositivos Android com as versões 2.1, 2.2, 2.3 e 4.0. Para integrar a IDE Eclipse ao
Android SDK, foi utilizado o plugin ADT.
O webservice foi implementado com base na plataforma JSE, através do ambiente de
desenvolvimento Eclipse, versão 3.7.2 (Indigo). Esse ambiente foi executado sobre o Java
Development Kit (JDK) versão 1.7.0 de 64 bits, para Microsoft Windows. Como servidor de
aplicação foi utilizado o servidor Apache Tomcat, versão 7.0.26. A engine Axis2 versão 1.6.1
foi utilizada para disponibilizar os métodos a serem acessados via o protocolo SOAP pelo
aplicativo cliente, o Axis2 é fornecido pela fundação Apache. A persistência das informações
é efetuada através de um Sistema Gerenciador de Banco de Dados (SGBD) Oracle versão
11.2.0. Para realizar o acesso ao banco de dados foi utilizado um driver Java JDBC para
Oracle, versão 6. Os testes do aplicativo webservice foram feitos com classes de teste através
do Apache Tomcat.
O servidor foi implementado com base na plataforma JSE, através do ambiente de
desenvolvimento Eclipse, versão 3.7.2 (Indigo). Esse ambiente foi executado sobre o Java
Development Kit (JDK) versão 1.7.0 de 64 bits, para Microsoft Windows.
77
3.3.2 Arquivo AndroidManifest.xml
O arquivo AndroidManifest.xml contém informações que são necessárias para a
execução da aplicação em qualquer dispositivo Android. Algumas informações são
obrigatórias e existem em todas as aplicações, como o pacote, o código da versão e o nome da
versão. Para o correto funcionamento da aplicação cliente foi necessário definir algumas
permissões e uma restrição. O Quadro 20 apresenta o cabeçalho do arquivo
AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="br.com.cesar.tcc2" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="7" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Quadro 20 – Cabeçalho do arquivo AndroidManifest.xml
O atributo package="br.com.cesar.tcc2" indica o pacote padrão da aplicação. Esse
pacote é considerado a raiz da aplicação e é usado para definição de namespaces das aplicações.
Os atributos android:versionCode="1" e android:versionName="1.0" indicam
informações da versão da aplicação. A tag <uses-sdk android:minSdkVersion="7" />
define que somente dispositivos Android com a SDK versão 7 ou superior poderão executar a
aplicação cliente. A tag <uses-permission
android:name="android.permission.INTERNET"/> define que o aplicativo tem permissão
para realizar acesso a Internet. Essa permissão é necessária para que o aplicativo possa
conectar-se ao aplicativo webservice. A tag <uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/> define que a aplicação
tem permissão para recuperar as coordenadas de geolocalização do dispositivo móvel. A tag
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
define que a aplicação pode ter acesso ao cartão SD do dispositivo móvel. Esta permissão é
necessária para gravar o arquivo de configuração e a lista de arquivos compartilhados.
As informações e componentes da aplicação são informadas dentro da tag
application. Além das informações básicas da aplicação, o arquivo AndroidManifest.xml
deve conter também a declaração de cada componente da aplicação, neste caso activities e
78
services. O Quadro 21 apresenta um trecho de declaração das activities e dos services do
aplicativo cliente.
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".LoginUsuario" android:theme="@android:style/Theme.NoTitleBar" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".service.Georastreamento"> <intent-filter> <action android:name="LSGEO" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
Quadro 21 – Declaração de activities e services no arquivo AndroidManifest.xml
As tags android:icon="@drawable/ic_launcher" e
android:label="@string/app_name" definem respectivamente o ícone e o texto que serão
utilizados para apresentar o executável do aplicativo no sistema Android. Os dados das
activities e dos services são declarados dentro das tags <activity> e <service>
respectivamente. A tag android:name=".LoginUsuario" define a classe que a activity está
implementada, o ponto que antecede o nome da classe é utilizado para suprimir o caminho da
package do sistema. A tag android:theme="@android:style/Theme.NoTitleBar" define
que a activity não irá apresentar a barra de titulo superior, padrão dos aplicativos Android. A
tag android:screenOrientation="portrait" define que a activity vai ser apresentada no
modo retrato no dispositivo e não sofrerá alteração caso o dispositivo seja posicionado na
horizontal.
Todas as intents que uma activity ou service implementam são declaradas dentro da tag
<intent-filter>. A activity em questão contem um intent com a ação definida pela tag
<action android:name="android.intent.action.MAIN" /> que indica que ela pode ser
utilizada pelo Android para a inicialização do sistema. A action implementada pelo service foi
definida no momento do desenvolvimento e é utilizada durante a execução da aplicação para
que o service seja executado ou interrompido.
79
3.3.3 Arquivos de leiaute e constantes de texto
No Android existem duas formas de definir o leiaute de uma tela ou componente de
uma aplicação, através de código Java ou de código XML. Para a aplicação cliente do
sistema, foi utilizado o formato de código XML, onde foram definidos tags para os
componentes, os quais posteriormente foram associados com objetos instanciados nas classes
estendidas de Activity e BaseAdapter.
O Quadro 22 apresenta o arquivo layout/tela_config.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/fundo"
android:theme="@android:style/Theme.NoTitleBar">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/confTvHostLocalSocial"
/>
<EditText
android:id="@+id/confEtHostLocalSocial"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="text"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dip"
android:text="@string/confTvPortaLocalSocial"
/>
<EditText
android:id="@+id/confEtPortaLocalSocial"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="number"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_gravity="bottom"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/confBtPadrao"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/confBtPadrao"
/>
<Button
android:id="@+id/confBtOK"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/confBtOK"
/>
</LinearLayout>
</LinearLayout>
</ScrollView> Quadro 22 – Arquivo layout/tela_config.xml
80
Os componentes ScrollView e LinearLayout são utilizados para definir a disposição
de outros componentes na tela. Os componentes TextView são utilizados para apresentar
informações de texto ao usuário. Os componentes EditText são utilizados como campos de
entrada de dados, o tipo de dado que o usuário poderá informar neles é definido pela tag
android:inputType. Os componentes Button são utilizados para apresentar botões na tela
que na codificação Java recebem ações específicas a serem executadas quando pressionados
pelo usuário.
É possível observar que os componentes do tipo TextView já recebem o valor de texto
através da tag android:text, no entanto, o valor não é especificado diretamente no arquivo
de leiaute, mas sim em um arquivo de constantes de texto chamado values/strings.xml.
O arquivo values/strings.xml foi criado com o intuito de centralizar valores
alfanuméricos, facilitando assim a internacionalização da aplicação.
O Quadro 23 apresenta o arquivo values/strings.xml e o Quadro 24 apresenta um
trecho da activity Configuracoes, que utiliza o arquivo de leiaute tela_config.xml.
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">LocalSocial</string> <string name="loginBtRegistrar">Registrar</string> <string name="loginBtSair">Sair</string> <string name="loginBtLogin">Login</string> <string name="loginTvUsuario">Usuario</string> <string name="loginTvSenha">Senha</string> <string name="loginBtConfig">Configurações</string> <string name="principalBtSair">Sair</string> <string name="principalBtArquivos">Meus arquivos</string> <string name="principalTvDistancia">Distância limite para visualização de usuários</string> <string name="convBtEnviar">Enviar</string> <string name="confTvHostLocalSocial">URL do WEBService do LocalSocial</string> <string name="confTvPortaLocalSocial">Porta do WEBService do LocalSocial</string> <string name="confBtPadrao">Restaurar padrão</string> <string name="confBtOK">OK</string> <string name="registroTvNome">Nome</string> <string name="registroTvLogin">Login</string> <string name="registroTvSenha">Senha</string> <string name="registroBtCancelar">Cancelar</string> <string name="registroBtRegistrar">Registrar</string> <string name="altSenhaTitulo">Alteração de senha</string> <string name="altSenhaAtual">Informe a senha atual</string> <string name="altSenhaNova">Informe a nova senha</string> <string name="altSenhaNovaRp">Repita a senha nova</string> <string name="altBtCancelar">Cancelar</string> <string name="altBtOK">OK</string> <string name="arqBtCompartilhar">+</string> <string name="arqTvTitulo">Meus arquivos compartilhados</string> </resources>
Quadro 23 – Arquivo values/strings.xml
81
private void inicializarComponentes() {
this.edUrlWebService = (EditText)
findViewById(R.id.confEtHostLocalSocial);
this.edPortaWebService = (EditText)
findViewById(R.id.confEtPortaLocalSocial);
Button botaoPadrao = (Button) findViewById(R.id.confBtPadrao);
botaoPadrao.setOnClickListener(this);
Button botaoOK = (Button) findViewById(R.id.confBtOK);
botaoOK.setOnClickListener(this);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tela_config);
this.inicializarComponentes();
this.recuperarDadosConfiguracao();
} Quadro 24 – Trecho da activity Configuracoes
No método onCreate(Bundle savedInstanceState) é possível visualizar o vinculo
do arquivo de leiaute com a activity através do método
setContentView(R.layout.tela_config).
No método inicializarComponentes() é possível visualizar o vinculo dos
componentes definidos no arquivo de leiaute com variáveis da classe, para isto é utilizado o
método findViewById, que recebe como parâmetro o ID do componente a ser vinculado.
3.3.4 Arquivo services.xml
No aplicativo webservice os métodos que serão publicados pelo servidor Tomcat são
definidos em um arquivo XML chamado services.xml, este arquivo pode ser encontrado na
pasta META-INF do projeto e é encapsulado juntamente com as classes Java.
A tag <parameter
name="ServiceClass">br.com.cesar.tcc2.ws.LocalSocial</parameter> define qual a
classe dentro do projeto que contém a implementação dos métodos que serão disponibilizados
pelo servidor Tomcat.
As tags iniciadas por <operation definem os nomes dos métodos publicados. Para
cada operation deve existir um método com mesmo nome na classe definida pelo parâmetro
ServiceClass. Observa-se que não são informados os tipos de retorno dos métodos nem os
parâmetros de entrada dos mesmos, isto ocorre porque a própria engine do Axis2 realiza esta
82
tarefa.
O Quadro 25 apresenta o arquivo services.xml e o Quadro 26 um trecho da classe
LocalSocial do aplicativo webservice.
<service > <parameter name="ServiceClass">br.com.cesar.tcc2.ws.LocalSocial</parameter> <operation name="autenticarUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="registrarUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="atualizarPosicaoUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="recuperarListaUsuarios"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="desconectarUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="gravarMensagemUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="recuperarMensagensUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="alterarSenhaUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="uploadArquivoUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="deletarArquivoUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> <operation name="recuperarListaArquivosUsuario"> <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </operation> </service>
Quadro 25 – Arquivo services.xml
83
public void gravarMensagemUsuario(int codigoUsuarioDestino, int codigoUsuarioOrigem, String loginUsuarioOrigem, String mensagem, double distancia) { try { System.out.println("Conectando ao server"); LocalSocialRMI interfaceRMI = this.conectarLocalSocialServer(); System.out.println("Enviando mensagem ao server"); interfaceRMI.gravarMensagemUsuario(codigoUsuarioDestino, codigoUsuarioOrigem, loginUsuarioOrigem, mensagem, distancia); System.out.println("Mensagem enviada"); } catch(NotBoundException nbe) { this.imprimirExcecao("gravarMensagemUsuario(int codigoUsuarioDestino, int codigoUsuarioOrigem, String loginUsuarioOrigem, String mensagem, double distancia)", "NotBoundException", nbe.getMessage()); } catch(MalformedURLException mue) { this.imprimirExcecao("gravarMensagemUsuario(int codigoUsuarioDestino, int codigoUsuarioOrigem, String loginUsuarioOrigem, String mensagem, double distancia)", "MalformedURLException", mue.getMessage()); } catch(RemoteException re) { this.imprimirExcecao("gravarMensagemUsuario(int codigoUsuarioDestino, int codigoUsuarioOrigem, String loginUsuarioOrigem, String mensagem, double distancia))", "RemoteException", re.getMessage()); } } public MensagemWrapper recuperarMensagensUsuario(int codigoUsuario) { MensagemWrapper mw = null; try { LocalSocialRMI interfaceRMI = this.conectarLocalSocialServer(); ArrayList<Mensagem> listaMensagens = interfaceRMI.recuperarMensagensUsuario(codigoUsuario); if( listaMensagens != null && !listaMensagens.isEmpty() ) { Mensagem[] arrayMensagens = new Mensagem[listaMensagens.size()]; for( int indice = 0; indice < listaMensagens.size(); indice++ ) arrayMensagens[indice] = listaMensagens.get(indice); mw = new MensagemWrapper(); mw.setArrayMensagem(arrayMensagens); } } catch(NotBoundException nbe) { this.imprimirExcecao("recuperarMensagensUsuario(int codigoUsuario)", "NotBoundException", nbe.getMessage()); } catch(MalformedURLException mue) { this.imprimirExcecao("recuperarMensagensUsuario(int codigoUsuario)", "MalformedURLException", mue.getMessage()); } catch(RemoteException re) { this.imprimirExcecao("recuperarMensagensUsuario(int codigoUsuario)", "RemoteException", re.getMessage()); } return mw; }
Quadro 26 – Trecho da classe LocalSocial
84
3.3.5 Persistência dos dados no aplicativo cliente
No aplicativo cliente a persistência de dados é observada em dois pontos: quando o
usuário altera as configurações de acesso ao aplicativo webservice e quando está
compartilhando pelo menos um arquivo.
Quando o usuário altera o IP e/ou a porta para conexão com o webservice, o sistema
grava os novos dados de acesso em um arquivo no cartão SD do dispositivo móvel. Este
arquivo é lido na inicialização do sistema e caso não seja encontrado o sistema assume que
deve usar os valores padrões para conexão com o webservice.
O Quadro 27 apresenta o método utilizado para os dados de configuração no cartão
SD.
public static void gravarAlteracoes() throws IOException, Exception { File pastaLocalSocial = new File(Parametros.CAMINHO_PASTA_APLICACAO); File arquivoConf = new File(Parametros.CAMINHO_ARQUIVO_CONFIGURACAO); if( !pastaLocalSocial.exists() ) pastaLocalSocial.mkdir(); if( arquivoConf.exists() ) arquivoConf.delete(); BufferedWriter escritor = null; try { escritor = new BufferedWriter(new FileWriter(arquivoConf)); escritor.write("URL_WEBSERVICE=" + Parametros.urlWebService); escritor.newLine(); escritor.write("PORTA_WEBSERVICE=" + Parametros.portaWebService); } finally { if( escritor != null ) escritor.close(); } }
Quadro 27 – Método para gravação dos dados de acesso ao webservice
Quando um usuário compartilha um arquivo, além do envio do arquivo ao webservice,
também é realizado a gravação de uma lista de arquivos compartilhados na parte cliente. Esta
lista é salva para que a aplicação cliente não necessite consultar a aplicação webservice para
saber que arquivos o usuário está compartilhando do cartão SD do seu dispositivo móvel. A
lista é carregada para a memória da aplicação na inicialização da mesma.
O Quadro 28 apresenta o método utilizado para gravação da lista de arquivos
compartilhados.
85
public static void gravarListaArquivos() throws IOException, Exception { File pastaLocalSocial = new File(Parametros.CAMINHO_PASTA_APLICACAO); File arquivoComp = new File(Parametros.CAMINHO_ARQUIVO_COMPARTILHADOS); if( !pastaLocalSocial.exists() ) pastaLocalSocial.mkdir(); if( arquivoComp.exists() ) arquivoComp.delete(); if( Parametros.listaArquivosComparilhados != null && !Parametros.listaArquivosComparilhados.isEmpty() ) { BufferedWriter escritor = null; try { escritor = new BufferedWriter(new FileWriter(arquivoComp)); for( int indice = 0; indice < Parametros.listaArquivosComparilhados.size(); indice++ ) { escritor.write(Parametros.listaArquivosComparilhados.get(indice)); if( indice != Parametros.listaArquivosComparilhados.size() - 1 ) escritor.newLine(); } } finally { if( escritor != null ) escritor.close(); } }
Quadro 28 – Método para gravação da lista de arquivos compartilhados
Observa-se que em ambos os casos é utilizado as classes nativas de entrada e saída da
plataforma Java.
3.3.6 Persistência dos dados no aplicativo webservice
Conforme descrito no preambulo deste capitulo, o aplicativo webservice utilizada um
SGBD Oracle para a persistência dos dados de autenticação dos usuários e dos arquivos que
estes usuários estão compartilhando, o acesso ao SGBD é realizado por um driver JDBC para
Oracle.
As classes br.com.cesar.tcc2.dao.DAOFactory e
br.com.cesar.tcc2.dao.UsuarioDAO foram criadas para realizar a tarefa de interagir com
o SGBD, criando assim uma camada de abstração para a classe
br.com.cesar.tcc2.ws.LocalSocial onde está implementado a lógica do aplicativo
webservice.
A classe br.com.cesar.tcc2.dao.DAOFactory é responsável por recuperar os dados
de acesso e autenticação do SGBD, realizar a conexão com o mesmo e criar objetos da classe
br.com.cesar.tcc2.dao.UsuarioDAO, passando como parâmetro a conexão com o banco de
dados no construtor da mesma. O Quadro 29 apresenta a classe
86
br.com.cesar.tcc2.dao.DAOFactory.
package br.com.cesar.tcc2.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public final class DAOFactory { public static UsuarioDAO getUsuarioDAO() throws SQLException, ClassNotFoundException { return new UsuarioDAO(DAOFactory.getConnection()); } private static Connection getConnection() throws SQLException, ClassNotFoundException { Class.forName("oracle.jdbc.driver.OracleDriver"); String hostOracle = System.getProperty("lsOracleHost"), portOracle = System.getProperty("lsOraclePort"), userOracle = System.getProperty("lsOracleUser"), passOracle = System.getProperty("lsOraclePass"), sidOracle = System.getProperty("lsOracleSID"); String url = "jdbc:oracle:thin:@" + hostOracle + ":" + portOracle + "/" + sidOracle; return DriverManager.getConnection(url, userOracle, passOracle); } }
Quadro 29 – Classe br.com.cesar.tcc2.dao.DAOFactory
A classe br.com.cesar.tcc2.dao.UsuarioDAO é responsável por conter os comandos
Sequel Query Language (SQL) para administração dos dados no SGBD. Cada atividade a ser
realizada no SGBD foi separada em métodos específicos. O tratamento de exceções que
possam ocorrer durante a realização destas atividades foi delegado, através da clausula
throws, a qualquer classe que possa vir utiliza-la. O Quadro 30 apresenta um trecho da classe
br.com.cesar.tcc2.dao.UsuarioDAO.
87
public int recuperarCodigoUsuario() throws SQLException { int codigo = -1; PreparedStatement ps = null; ResultSet rs = null; try { ps = this.conn.prepareStatement("select ls_sq_usuario.nextval from dual"); rs = ps.executeQuery(); if( rs.next() ) codigo = rs.getInt(1); } finally { if( rs != null ) rs.close(); if( ps != null ) ps.close(); } return codigo; } public String[] recuperarDadosUsuario(String nmLogin) throws SQLException { String[] dados = null; PreparedStatement ps = null; ResultSet rs = null; try { ps = this.conn.prepareStatement("select cd_usuario, ds_senha from ls_usuario where ds_login = ?"); ps.setString(1, nmLogin); rs = ps.executeQuery(); if( rs.next() ) { dados = new String[2]; dados[0] = rs.getString(1); dados[1] = rs.getString(2); } } finally { if( rs != null ) rs.close(); if( ps != null ) ps.close(); } return dados; }
Quadro 30 – Trecho da classe br.com.cesar.tcc2.dao.UsuarioDAO
3.3.7 Conexão do aplicativo cliente com o aplicativo webservice
Um grande numero das atividades desempenhadas pelo aplicativo cliente necessitam
interação com o webservice do sistema. Para possibilitar a conexão entre as duas aplicações
foi utilizada uma API externa chamada kSOAP2 que foi desenvolvida visando a conexão de
dispositivos móveis à webservices SOAP. O Quadro 31 apresenta o trecho de conexão da
88
classe br.com.cesar.tcc2.ws.LocalSocialWS.
public final class LocalSocialWS { private final String URL = "http://" + Parametros.urlWebService + ":" + Parametros.portaWebService + "/axis2/services/localsocial"; private final String NAMESPACE = "http://ws.tcc2.cesar.com.br"; private SoapObject getSoapObject(String metodo) { SoapObject soap = new SoapObject(this.NAMESPACE, metodo); return soap; } private Object getResponse(SoapObject soap) throws IOException, XmlPullParserException { SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(soap); HttpTransportSE httpTransport = new HttpTransportSE(this.URL,15000); httpTransport.call("", envelope); return envelope.getResponse(); } private Object getResponse(SoapObject soap, MarshalDouble md) throws IOException, XmlPullParserException { SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(soap); md.register(envelope); HttpTransportSE httpTransport = new HttpTransportSE(this.URL,15000); httpTransport.call("", envelope); return envelope.getResponse(); } private Object getResponse(SoapObject soap, MarshalBase64 md) throws IOException, XmlPullParserException { SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(soap); md.register(envelope); HttpTransportSE httpTransport = new HttpTransportSE(this.URL,15000); httpTransport.call("", envelope); return envelope.getResponse(); }
Quadro 31 – Trecho de conexão da classe br.com.cesar.tcc2.ws.LocalSocialWS
O método getSoapObject cria um objeto do tipo SoapObject, onde é informado o
namespace do webservice e o método disponibilizado que deseja ser executado, este objeto é
utilizado pelos métodos getResponse. Os métodos getResponse são os responsáveis por
efetivamente realizar a conexão com o webservice e recuperar o resultado da execução do
método especificado no SoapObject com os parâmetros informados pelo usuário.
Foi necessário a criação de três métodos getResponse, devido necessidades específicas
de algumas das atividades desempenhadas pelo aplicativo cliente. O método
getResponse(SoapObject soap) é utilizado para executar os métodos do webservice que
89
não demandam um atributo complexo. Os métodos em questão possuem somente atributos
String e int.
O método getResponse(SoapObject soap, MarshalBase64 md) é utilizado para o
método uploadArquivoUsuario do webservice, responsável por receber os arquivos que os
usuários estão compartilhando. Para que fosse possível enviar um arquivo para o webservice
pela API kSOAP2, foi necessário utilizar a classe MarshalBase64, também da API, para que
o código binário do arquivo fosse traduzido para uma informação interpretável pelo
webservice.
O método getResponse(SoapObject soap, MarshalDouble md) é utilizado para
executar métodos do webservice que necessitam que seja informado algum atributo do tipo
Double, como os valores de latitude e longitude do usuário. Para que fosse possível atender
este tipo de atributo foi necessário criar um Marshaller que pudesse traduzir este atributo
para algo entendível pela API kSOAP2. O Quadro 32 apresenta o código da classe
MarshalDouble.
package br.com.cesar.tcc2.ws; import java.io.IOException; import org.ksoap2.serialization.Marshal; import org.ksoap2.serialization.PropertyInfo; import org.ksoap2.serialization.SoapSerializationEnvelope; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; public class MarshalDouble implements Marshal { public Object readInstance(XmlPullParser parser, String namespace, String name, PropertyInfo expected) throws IOException, XmlPullParserException { return Double.parseDouble(parser.nextText()); } public void register(SoapSerializationEnvelope cm) { cm.addMapping(cm.xsd, "double", Double.class, this); } public void writeInstance(XmlSerializer writer, Object obj) throws IOException { writer.text(obj.toString()); } }
Quadro 32 – Classe MarshalDouble
3.3.8 Conexão do aplicativo webservice com o aplicativo servidor
Algumas das funcionalidades implementadas no aplicativo cliente necessitam a
interação com outros usuários, o aplicativo servidor é que fica a cargo de manter as sessões
90
dos usuários conectados, no entanto, não é realizada a conexão do aplicativo cliente
diretamente ao aplicativo cliente, mas somente pelo aplicativo webservice.
Este por sua vez conecta-se ao aplicativo servidor para atender a solicitação do
aplicativo cliente. Esta conexão é realizada através da tecnologia RMI, nativa da linguagem
Java, implementada através da classe br.com.cesar.tcc2.server.rmi.LocalSocialImpl
e da interface br.com.cesar.tcc2.server.rmi.LocalSocialRMI. O Quadro 33 apresenta a
interface br.com.cesar.tcc2.server.rmi.LocalSocialRMI.
package br.com.cesar.tcc2.server.rmi; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.ArrayList; import br.com.cesar.tcc2.modelo.Mensagem; import br.com.cesar.tcc2.modelo.Usuario; public interface LocalSocialRMI extends Remote { public boolean criarSessao(int codigoUsuario, String loginUsuario) throws RemoteException; public void atualizarPosicaoUsuario(int codigoUsuario, double valorLatitude, double valorLongitude) throws RemoteException; public void desconectarUsuario(int codigoUsuario) throws RemoteException; public ArrayList<Mensagem> recuperarMensagensUsuario(int codigoUsuario) throws RemoteException; public ArrayList<Usuario> recuperarListaUsuarios(int codigoUsuario, int distanciaLimite) throws RemoteException; public void gravarMensagemUsuario(int codigoUsuarioDestino, int codigoUsuarioOrigem, String loginUsuarioOrigem, String mensagem, double distancia) throws RemoteException; public void interromperExecucao() throws RemoteException; }
Quadro 33 – Interface br.com.cesar.tcc2.server.rmi.LocalSocialRMI
Esta interface é implementada no aplicativo cliente e no aplicativo webservice, pois é
através dela que o aplicativo webservice realiza a execução dos métodos por ela apresentados.
Dos métodos apresentados por ela, somente interromperExecucao() não tem relação
com atividades relacionadas ao aplicativo cliente, este método é utilizado para interromper a
execução do aplicativo servidor.
A implementação dos métodos apresentados pela interface
br.com.cesar.tcc2.server.rmi.LocalSocialRMI é realizada pela classe
br.com.cesar.tcc2.server.rmi.LocalSocialImpl. O Quadro 34 apresenta um trecho da
classe br.com.cesar.tcc2.server.rmi.LocalSocialImpl.
91
package br.com.cesar.tcc2.server.rmi; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.util.ArrayList; import br.com.cesar.tcc2.modelo.Mensagem; import br.com.cesar.tcc2.modelo.Sessao; import br.com.cesar.tcc2.modelo.Usuario; import br.com.cesar.tcc2.server.controle.ControleMensagens; import br.com.cesar.tcc2.server.controle.ControleSessoes; import br.com.cesar.tcc2.server.util.Util; public class LocalSocialImpl extends UnicastRemoteObject implements LocalSocialRMI { public LocalSocialImpl() throws RemoteException { super(); } private static final long serialVersionUID = 8118568660679293472L; @Override public boolean criarSessao(int codigoUsuario, String loginUsuario) throws RemoteException { return ControleSessoes.adicionarSessao(new Sessao(codigoUsuario,loginUsuario)); } @Override public void atualizarPosicaoUsuario(int codigoUsuario, double valorLatitude, double valorLongitude) throws RemoteException { ControleSessoes.atualizarPosicaoUsuario(codigoUsuario, valorLatitude, valorLongitude); } @Override public void desconectarUsuario(int codigoUsuario) throws RemoteException { ControleSessoes.desconectarUsuario(codigoUsuario); } @Override public ArrayList<Usuario> recuperarListaUsuarios(int codigoUsuario, int distanciaLimite) throws RemoteException { ArrayList<Usuario> listaUsuarios = new ArrayList<Usuario>(); ArrayList<Sessao> listaSessoes = ControleSessoes.recuperarSessoes(codigoUsuario); if( listaSessoes != null && !listaSessoes.isEmpty() ) { Sessao sessaoSolicitante = ControleSessoes.recuperarSessaoUsuario(codigoUsuario); if( sessaoSolicitante != null ) for( Sessao umaSessao : listaSessoes ) { double distanciaEntreUsuarios = Util.aplicarFormulaHarversine(sessaoSolicitante.getValorLatitude(), sessaoSolicitante.getValorLongitude(), umaSessao.getValorLatitude(), umaSessao.getValorLongitude()); if( distanciaLimite == 0 || distanciaLimite >= distanciaEntreUsuarios ) { Usuario umUsuario = new Usuario(umaSessao.getCodigoUsuario(),umaSessao.getLoginUsuario()); umUsuario.setDistancia(distanciaEntreUsuarios); listaUsuarios.add(umUsuario); } } } return listaUsuarios; }
Quadro 34 – Trecho da classe br.com.cesar.tcc2.server.rmi.LocalSocialImpl
92
O Quadro 35 apresenta o trecho de código onde o aplicativo webservice realiza a
conexão com o aplicativo servidor.
private LocalSocialRMI conectarLocalSocialServer() throws RemoteException, MalformedURLException, NotBoundException { return (LocalSocialRMI) Naming.lookup("//localhost/localsocial"); }
Quadro 35 – Abertura de conexão com o aplicativo servidor
3.3.9 Recuperação das coordenadas geográficas do usuário
A principal característica do sistema é permitir a interação entre usuários próximos, para
isto, é necessário primeiramente saber onde exatamente estão estes usuários. O primeiro passo
então é recuperar as coordenadas geográficas destes usuários. Para realizar está atividade
foram implementadas as classes
br.com.cesar.tcc2.listener.LocationListenerSatelite e
br.com.cesar.tcc2.listener.LocalListenerNetwork, responsáveis respectivamente por
recuperar as coordenadas do usuários por satélites GPS e torres de telefonia.
O service Georastreamento no aplicativo cliente é o responsável por iniciar e
interromper a coleta das coordenadas do usuário, através da classe LocationManager, e
transmiti-las ao aplicativo webservice, que por sua vez repassa estas coordenadas ao
aplicativo servidor, responsável por manter uma lista de todos os usuários conectados na
aplicação. O Quadro 36 apresenta o primeiro trecho da classe Georastreamento.
public final class Georastreamento extends Service implements Runnable { private LocationListener mlocListenerSAT = null; private LocationListener mlocListenerNET = null; private LocationManager mlocManagerSAT = null; private LocationManager mlocManagerNET = null; private boolean executar = true; public void onCreate() { this.mlocListenerSAT = new LocationListenerSatelite(); this.mlocManagerSAT = (LocationManager)getSystemService(Context.LOCATION_SERVICE); this.mlocManagerSAT.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this.mlocListenerSAT); this.mlocListenerNET = new LocationListenerNetwork(); this.mlocManagerNET = (LocationManager) getSystemService(Context.LOCATION_SERVICE); this.mlocManagerNET.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 5, this.mlocListenerNET); new Thread(this).start(); } public void onDestroy() { this.executar = false; this.mlocManagerSAT.removeUpdates(this.mlocListenerSAT); this.mlocManagerNET.removeUpdates(this.mlocListenerNET); }
Quadro 36 – Primeiro trecho da classe br.com.cesar.tcc2.service.Georastreamento
93
O método onCreate(), executado na criação do service, é responsável instanciar os
LocationListeners e os LocationManagers, que irão realizar a tarefa de recuperar as
coordenadas geográficas do usuário. Em sequencia é executado o método
requestLocationUpdates(String provider, long minTime, float
minDistance, LocationListener listener) que efetivamente inicia a coleta das
coordenadas geográficas. Os valores 5000 e 5 respectivamente representam o intervalo
mínimo de tempo em milissegundos e o espaço mínimo em metros entre uma coleta e outra
das coordenadas. Após isto é iniciado a execução em segundo plano da Thread implementada
pela própria classe Georastreamento. O Quadro 37 apresenta o segundo trecho da classe
Georastreamento.
O método onDestroy(), executado quando o usuário finaliza a execução da aplicação,
finaliza os LocationManagers e informa a execução em segundo planto que deve
interromper sua atividade também, interrompendo assim a coleta de coordenadas geográficas
da aplicação.
public void run() { long ultimaDataTransmissao = Parametros.getDataUltimaAtualizacaoPosicao(); while(this.executar) { try { if( ultimaDataTransmissao != Parametros.getDataUltimaAtualizacaoPosicao() ) { LocalSocialWS lsws = new LocalSocialWS(); lsws.atualizarPosicaoUsuario(Parametros.getCodigoUsuario(), Parametros.getLatitudeUsuario(), Parametros.getLongitudeUsuario()); ultimaDataTransmissao = Parametros.getDataUltimaAtualizacaoPosicao(); } Thread.sleep(1000); } catch(IOException io) { Intent it = new Intent(AtividadePrincipal.BROADCAST_ERROS); it.putExtra("erro", "Falha ao atualizar sua posição no sistema: IOException - " + io.getMessage()); sendBroadcast(it); } catch(XmlPullParserException xppe) { Intent it = new Intent(AtividadePrincipal.BROADCAST_ERROS); it.putExtra("erro", "Falha ao atualizar sua posição no sistema: XmlPullParserException - " + xppe.getMessage()); sendBroadcast(it); } catch(InterruptedException ie) { Intent it = new Intent(AtividadePrincipal.BROADCAST_ERROS); it.putExtra("erro", "Falha ao atualizar sua posição no sistema: InterruptedException - " + ie.getMessage()); sendBroadcast(it); } } }
Quadro 37 – Segundo trecho da classe br.com.cesar.tcc2.service.Georastreamento
O objetivo do método run(), é ficar constantemente verificando se ocorreu atualização
94
nas coordenadas do usuário, e caso tenha ocorrido, realizar a transmissão destes dados para o
webservice do sistema. Qualquer erro que possa ocorrer neste processo é encaminhado para a
activity AtividadePrincipal, por meio de um Broadcast, como pode ser observado nos
blocos catch.
O Quadro 38 apresenta a classe
br.com.cesar.tcc2.listener.LocationListenerSatelite e o Quadro 39 apresenta a
classe br.com.cesar.tcc2.listener.LocalListenerNetwork.
package br.com.cesar.tcc2.listener; import android.location.Location; import android.location.LocationListener; import android.os.Bundle; import br.com.cesar.tcc2.util.Parametros; public final class LocationListenerSatelite implements LocationListener { public void onLocationChanged(Location location) { Parametros.setPosicaoUsuario(0, location.getLatitude(), location.getLongitude()); } public void onProviderDisabled(String provider) {} public void onProviderEnabled(String provider) {} public void onStatusChanged(String provider, int status, Bundle extras) {} }
Quadro 38 – Classe br.com.cesar.tcc2.listener.LocationListenerSatelite
package br.com.cesar.tcc2.listener; import android.location.Location; import android.location.LocationListener; import android.os.Bundle; import br.com.cesar.tcc2.util.Parametros; public final class LocationListenerNetwork implements LocationListener { public void onLocationChanged(Location location) { Parametros.setPosicaoUsuario(1, location.getLatitude(), location.getLongitude()); } public void onProviderDisabled(String arg0) {} public void onProviderEnabled(String arg0) {} public void onStatusChanged(String arg0, int arg1, Bundle arg2) {} }
Quadro 39 – Classe br.com.cesar.tcc2.listener.LocationListenerNetwork
Percebe-se que ambas as classes realizam a execução do método
setPosicaoUsuario(int origem, double latitudeUsuario, double
longitudeUsuario) alterando somente o valor informado no parâmetro origem, isto ocorre
porque as coordenadas tem tratamentos distintos dependendo se são obtidas por satélite ou
torres de telefonia. O Quadro 40 apresenta o método setPosicaoUsuario da classe
br.com.cesar.tcc2.util.Parametros responsável por realizar o tratamento das
coordenadas obtidas.
95
public static void setPosicaoUsuario(int origem, double latitudeUsuario, double longitudeUsuario) { if( origem == 0 ) { Parametros.latitudeUsuario = latitudeUsuario; Parametros.longitudeUsuario = longitudeUsuario; Parametros.origemAtualizacaoPosicao = 0; Parametros.dataUltimaAtualizacaoPosicao = System.currentTimeMillis(); Log.v("GPS", "Atualizado posição via Satelite"); } else { if( Parametros.origemAtualizacaoPosicao == 1 ) { Parametros.latitudeUsuario = latitudeUsuario; Parametros.longitudeUsuario = longitudeUsuario; Parametros.origemAtualizacaoPosicao = 1; Parametros.dataUltimaAtualizacaoPosicao = System.currentTimeMillis(); Log.v("GPS", "Atualizado posição via torre"); } else if( Parametros.dataUltimaAtualizacaoPosicao + 5000 <= System.currentTimeMillis() ) { Parametros.latitudeUsuario = latitudeUsuario; Parametros.longitudeUsuario = longitudeUsuario; Parametros.origemAtualizacaoPosicao = 1; Parametros.dataUltimaAtualizacaoPosicao = System.currentTimeMillis(); Log.v("GPS", "Atualizado posição via torre"); } } }
Quadro 40 – Método setPosicaoUsuario da classe br.com.cesar.tcc2.util.Parametros
Caso a coordenada tiver sido obtida por satélite GPS (origem = 0) ela é aceita e
definida nas variáveis Parametros.latitudeUsuario e Parametros.longitudeUsuario,
além de ser definido que estes valores foram definidos por satélite GPS
(Parmetros.origemAtualizacaoPosicao = 0) e a data da obtenção dos dados atualizada
para a data atual (Parametros.dataUltimaAtualizacaoPosicao =
System.currentTimeMillis();).
No entanto, se a coordenada for obtida por torres de telefonia (origem = 1) são
realizadas duas analises. Se a ultima coordenada obtida tiver sido realizada também por torres
de telefonia, então ela é aceita e atualizada no sistema, porém, se a coordenada anterior tiver
sido obtida por satélite GPS, então é analisado se já se passaram mais de cinco segundos
desde a ultima obtenção das coordenadas do usuário (if(
Parametros.dataUltimaAtualizacaoPosicao + 5000 <=
System.currentTimeMillis() )), caso sim, então as coordenadas são atualizadas, do
contrário, prioriza-se as coordenadas obtidas pelo satélite GPS. Esta analise ocorre porque,
apesar de mais fáceis de serem obtidas, as coordenadas obtidas por torres de telefonia são
menos precisas.
96
3.3.10 Cálculo da distancia entre dois usuários
Depois de recuperado as coordenadas de geolocalização dos usuários, o próximo passo
é utilizar estes valores para calcular o quão próximo estes usuários estão entre si. Para realizar
este calculo foi utilizado a formula matemática de Haversine, destinada a calcular a distancia
entre dois pontos sobre uma esfera a partir de suas latitudes e longitudes.
O Quadro 41 apresenta a classe br.com.cesar.tcc2.util.Util do aplicativo
webservice, onde esta implementado o método aplicarFormulaHarversine.
package br.com.cesar.tcc2.server.util; public final class Util { private static final double RAIO_TERRA = 6367.46d; public static double aplicarFormulaHarversine(double lat1, double long1, double lat2, double long2) { double difLat = Math.toRadians(lat2 - lat1); double difLong = Math.toRadians(long2 - long1); double lat1Rad = Math.toRadians(lat1); double lat2Rad = Math.toRadians(lat2); double a = Math.sin(difLat/2) * Math.sin(difLat/2) + Math.sin(difLong/2) * Math.sin(difLong/2) * Math.cos(lat1Rad) * Math.cos(lat2Rad); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return c * RAIO_TERRA * 1000; } }
Quadro 41 – Classe br.com.cesar.tcc2.util.Util
A constante RAIO_TERRA é uma média do raio do planeta Terra em quilômetros, isto
porque a esfera do planeta não é perfeita, podendo variar de 6356,78km nos polos até
6378,14 km no equador.
O método aplicarFormulaHarversine(double lat1, double long1, double
lat2, double long2) recebe a longitude e a latitude de dois usuários e retorna a distancia
em metros entre estes dois usuários. Percebe-se que os valores são convertidos para radianos
antes de utilizados na formula. Ao final, o valor obtido, é multiplicado pela constante
RAIO_TERRA e então pelo valor 1000, isto ocorre porque se deseja obter o valor da distancia
em metros e não em quilômetros.
3.3.11 Download de um arquivo compartilhado
Diferentemente das outras atividades desempenhadas pelo aplicativo cliente, onde a
97
troca de informações é realizada através da comunicação com o aplicativo webservice através
da tecnologia SOAP, o download de um arquivo compartilhado por outro usuário é realizado
através de uma conexão direta com o servidor de aplicações Apache Tomcat. Optou-se por
realizar desta forma, devido a possibilidade de trazer o arquivo por pedaços (chunks), o que
não causa um impacto grande no tráfego de dados do dispositivo móvel. O Quadro 42 contém
o método downloadArquivo() da task br.com.cesar.tcc2.task.DownloadArquivo.
private ByteArrayBuffer downloadArquivo() throws IOException { ByteArrayBuffer bab = null; URL urlArquivo = new URL(this.urlArquivo); URLConnection urlConn = urlArquivo.openConnection(); BufferedInputStream bis = new BufferedInputStream(urlConn.getInputStream()); bab = new ByteArrayBuffer(50); int current = 0; while( (current = bis.read()) != -1 ) bab.append((byte) current); bis.close(); return bab; }
Quadro 42 – Método downloadArquivo() da task br.com.cesar.tcc2.task.DownloadArquivo
Primeiramente é convertido a URL do arquivo que está no formato String para o tipo
URL e então é aberta a conexão com o servidor Tomcat. Após esta etapa são instanciadas as
variáveis necessárias para a recuperação do fluxo de dados da conexão e armazenagem dos
dados já recebidos, o método então entra no ciclo recursivo onde é realizado o download do
arquivo byte a byte, até que o byte enviado pelo servidor Apache seja igual a -1, o que indica
que não há mais bytes do arquivo a serem enviados. A conexão então é fechada e o arquivo
retornado no formato ByteArrayBuffer.
O passo seguinte é gravar o arquivo no cartão SD do dispositivo móvel, o Quadro 43
apresenta o método gravarArquivoSD(ByteArrayBuffer bab)responsável por realizar esta
tarefa.
private void gravarArquivoSD(ByteArrayBuffer bab) throws IOException {
this.urlLocal = Parametros.CAMINHO_PASTA_DOWNLOADS + File.separator +
this.nomeUsuario + File.separator + this.nomeArquivo;
File arquivo = new File(this.urlLocal);
if( arquivo.exists() )
arquivo.delete();
FileOutputStream fos = new FileOutputStream(arquivo);
fos.write(bab.toByteArray());
fos.close();
}
Quadro 43 – Método gravarArquivoSD(ByteArrayBuffer bab) da task br.com.cesar.tcc2.task.DownloadArquivo
Percebe-se que foram utilizados os métodos nativos de entrada e saída da linguagem
98
Java para a realização da tarefa. No momento de ser gravado, o ByteArrayBuffer é
convertido para um simples array de bytes, conforme pode ser observado na linha
fos.write(bab.toByteArray());.
Vale ressaltar que todos os arquivos que o usuário realizar download serão gravados no
cartão SD do dispositivo móvel no caminho
Environment.getExternalStorageDirectory().toString() + File.separator +
"LocalSocial" + File.separator + "downloads", sendo separados em pastas com o
nome dos usuários que estão compartilhando-os.
3.3.12 Operacionalidade da implementação
As principais funcionalidades do aplicativo cliente estão relacionadas à visualização
dos usuários próximos, a troca de mensagens com estes usuários, o compartilhamento de
arquivos e o download dos arquivos compartilhados pelos usuários. Esta seção apresenta a
operacionalidade da aplicação demonstrando o cadastro de um novo usuário, a visualização
dos usuários próximos, a troca de mensagens com um usuário, o compartilhamento de um
arquivo exemplo e o download de um arquivo exemplo compartilhado por outro usuário.
3.3.12.1 Cadastro de usuário
A tela inicial da aplicação apresenta opções para login de um usuário já existente, o
cadastro de um novo usuário e a alteração das configurações de acesso ao webservice do
sistema. Como o login é obrigatório, ao utilizar o aplicativo pela primeira vez o usuário deve
selecionar a opção para cadastro de um novo usuário. Ao selecionar esta opção, o aplicativo
apresentará uma tela contendo os campos relativos ao cadastro do usuário. Após preencher os
campos, o usuário poderá salvar as informações através do botão de confirmação. Ao fazê-lo,
as informações são enviadas ao webservice e, em caso de sucesso, o aplicativo apresentará a
tela inicial do sistema. A Figura 28 apresenta a execução dos passos para o cadastro do
usuário dentro do aplicativo.
99
Figura 28 – Passos para criação de um usuário
3.3.12.2 Visualização dos usuários próximos
Assim que o usuário realizar o login no sistema, será iniciada a verificação da sua
localização e na sequencia a verificação dos usuários próximos. Estas duas verificações são
realizadas periodicamente em segundo plano e atualizam dos dados em tela sem necessidade
de ação do usuário, no entanto, se o usuário alterar a distancia mínima para visualização de
outros usuários a verificação dos usuários próximos será executada imediatamente. A Figura
29 apresenta a tela principal do sistema.
Figura 29 – Tela principal do sistema
100
No canto superior direito pode se ver o botão de atualização da lista de usuários, este
botão é utilizado caso o usuário deseja atualizar a lista sem alterar a limitação distância
previamente configurada. Logo abaixo está a seekbar, onde o usuário pode alterar o limite de
distância (em metros) para visualização de usuários, sendo 0 (Sem limite) o valor mais a
esquerda e 10.000m o valor mais a direita. Abaixo estão as abas de Usuários e Conversas. A
aba Usuários apresenta todos os usuários conectados na aplicação que atendem o critério de
distancia especificado pelo usuário, já a aba Conversas, apresenta somente os usuários com os
quais já houve alguma troca de mensagens previamente. É possível observar que um único
usuário atendeu o critério de distancia (100m) especificado na imagem. Abaixo do nome do
usuário é apresentado a distancia que este se localiza, na direita são apresentados dois botões,
um para iniciar a troca de mensagens (esquerdo) e outro para a visualização dos arquivos
compartilhados pelo usuário (direito).
Quando pressionado o botão menu do dispositivo, é apresentado o context menu com as
opções para compartilhamento de arquivos e alteração de senha. A Figura 30 apresenta o
context menu da tela principal.
Figura 30 – Context menu da tela principal do sistema
101
3.3.12.3 Troca de mensagens com um usuário
Para iniciar a troca de mensagens com outro usuário, primeiramente é necessário
definir o limite de distancia de visualização para que seja apresentado pelo menos um usuário
na lista de usuários. Em seguida, é necessário pressionar no botão de conversa do usuário em
questão, neste instante será apresentada a tela de conversa com o usuário com as mensagens,
se existir alguma, trocadas anteriormente. Para enviar uma mensagem, basta pressionar no
campo de texto na parte inferior da tela, utilizar o teclado virtual que irá surgir para escrever a
mensagem e por fim pressionar o botão enviar. A Figura 31 apresenta a tela de conversa e
uma mensagem sendo escrita.
Figura 31 – Tela de conversas e escrita de mensagem
Caso o usuário opte por deixar a tela da conversa e voltar para a tela principal, isto não
impedirá que ele receba as mensagens enviadas por um usuário com o qual ele manteve uma
conversa anteriormente, ou até mesmo mensagens de outros usuários. Para permitir isto foi
utilizado o sistema de notificações da plataforma Android, a Figura 32 demonstra a recepção
de uma mensagem quando o usuário não estava na tela da conversa. Pressionando na
notificação será apresentada a tela de conversa do usuário que enviou a mensagem.
102
Figura 32 – Notificação de nova mensagem
3.3.12.4 Compartilhamento de arquivos
A partir do contexto menu da tela principal do sistema (Figura 24), o usuário pode
acessar a tela de compartilhamento de arquivos, onde poderá visualizar os arquivos já
compartilhados, remover o compartilhamento de algum destes ou ainda compartilhar um novo
arquivo.
A Figura 33 apresenta os passos para que o usuário compartilhe um arquivo do seu
dispositivo móvel.
Figura 33 – Passos para compartilhar arquivo
Primeiramente o usuário deverá pressionar no botão + no canto superior direito da tela
dos arquivos compartilhados o que irá apresentar a tela com a estrutura de pastas e arquivos
103
do cartão SD do seu dispositivo móvel. Após escolhido o arquivo desejado o sistema
solicitará uma confirmação antes de realizar o compartilhamento. Uma vez confirmado, é
realizado o upload do arquivo para o aplicativo webservice, e caso tudo ocorra com sucesso é
apresentado a mensagem de sucesso ao usuário e a lista de arquivos compartilhados é
atualizada com o arquivo recém compartilhado.
Para interromper o compartilhamento de um arquivo, basta pressionar sobre um deles,
será apresentado então uma caixa de confirmação e caso seja confirmado o aplicativo informa
ao webservice que o arquivo não é mais compartilhado pelo usuário. A Figura 34 apresenta os
passos para interrupção de compartilhamento de um arquivo.
Figura 34 – Passos para interromper compartilhamento de arquivo
3.3.12.5 Download de um arquivo compartilhado por outro usuário
Semelhante à troca de mensagens, para realizar o download de um arquivo
compartilhado por outro usuário primeiramente é necessário definir o limite de distancia para
visualização de usuários de tal forma que pelo menos um usuário esteja visível na lista.
Após isto, basta pressionar no botão de arquivos compartilhados (o mais a direita) para
visualizar os arquivos que o usuário está compartilhando. Para realizar o download de algum
basta pressionar sobre ele, será apresentada então uma caixa de confirmação e caso ocorra a
confirmação o download é iniciado e o arquivo armazenado no cartão SD do dispositivo
móvel, a Figura 35 apresenta os passos para a realização do download de um arquivo
compartilhado por outro usuário.
104
Figura 35 – Passos para download de arquivo compartilhado
3.4 RESULTADOS E DISCUSSÃO
O objetivo inicial deste trabalho era disponibilizar um protótipo de sistema,
desenvolvido para a plataforma Android, capaz de relacionar usuários que estivessem
geograficamente próximos e permitir a troca de mensagens e arquivos entre estes usuários.
Havia sido proposto também que esta troca de mensagens e arquivos fosse realizada com uma
conexão direta entre os dispositivos móveis, não necessitando de outro ator para a realização
destas tarefas. No entanto, durante os primeiros testes neste modelo, detectaram-se alguns
problemas de conexão entre os dispositivos, principalmente quando utilizando a tecnologia
3g. Após uma pesquisa identificou-se que existe uma restrição, imposta pelas operadoras de
telefonia, quanto à utilização de algumas portas para conexão entre dispositivos, sendo
autorizado somente o uso de portas mais comuns, como: 80 (servidores web), 8080
(servidores de aplicação) e 22 (conexões SSH).
Optou-se então em desenvolver a troca de mensagens e arquivos entre os usuários,
através de conexões no aplicativo webservice, continuando a atender desta forma o objetivo
principal, no entanto, uma pesquisa mais aprofundada quanto a este problema é valida e
recomendada como extensão deste trabalho. Para a comunicação com o aplicativo webservice,
foi utilizada a biblioteca externa kSOAP2, devido a falta de uma biblioteca nativa da
plataforma Android que atendesse esta necessidade.
Para um melhor entendimento dos testes realizados é apresentado o cenário do sistema
105
na Figura 36.
Figura 36 – Cenário do sistema
Foram realizados testes de desempenho na aplicação cliente, visando analisar o tempo
de resposta das atividades que envolvem o acesso ao webservice. Para a realização destes
testes foram utilizadas rotinas de depuração nas atividades analisadas, recuperando desta
forma o tempo de execução de cada uma. Os testes da aplicação cliente foram realizados
através de um smartphone conectado a um computador utilizando o ambiente de
desenvolvimento Eclipse com o plugin ADT da plataforma Android. Desta forma foi possível
depurar as ações executadas pelo smartphone e visualizar os dados gerados no próprio
ambiente Eclipse.
Foram realizados também testes de memória, analisando o crescimento do banco de
dados com a adição de novos usuários e referencias de arquivos compartilhados. Não foi
analisado o crescimento de espaço utilizado no disco rígido do servidor pelos arquivos
compartilhados, primeiramente por não ser uma ação obrigatória do sistema, podendo assim
existir usuários sem nenhum arquivo compartilhado, segundo porque o tamanho dos arquivos
pode variar, sendo 10 megabytes o tamanho máximo de um arquivo compartilhado.
3.4.1 Testes de performance
Os testes de performance do aplicativo cliente foram realizados utilizando um
smartphone com processador de 1,2 Ghz, utilizando a versão 4.0.3 do Android. O webservice,
o banco de dados e o aplicativo servidor estavam alocados em um computador com
processador Intel Core i5 de quatro núcleos e velocidade de 2,5 Ghz, com 6 gigabytes de
106
memória física. A conexão entre o smartphone e o webservice foi realizada através de uma
conexão Wi-Fi de 54 megabits por segundo.
No primeiro teste foi avaliado o tempo necessário para a recuperação dos usuários
próximos, considerando um numero variado de usuários na lista retornada, foram realizados 5
(cinco) testes com cada quantidade de usuários listados. A Tabela 1 apresenta os dados
obtidos.
Tabela 1 – Tempo para recuperação da lista de usuários
Usuários conectados Média em milissegundos
0 76
1 89
2 93,6
3 98,3
4 107,4 Observa-se, a partir das informações obtidas no teste, que a cada novo usuário na lista
acresce o tempo para recuperá-la em média 7,85 milissegundos. Isto é compreensível, uma
vez que a cada novo usuário no sistema um novo calculo de distancia deve ser realizado, o
que justifica o aumento de tempo apresentado pelos dados. No entanto, deve-se ressaltar que
este valor pode sofrer variações, pois está sujeito a qualidade da conexão à internet do
dispositivo móvel do usuário.
No segundo teste foi analisado o tempo necessário para a recuperação das mensagens
enviadas por outros usuários, considerando um numero variado de mensagens, inclusive
quando não existem mensagens a serem recebidas. Para não gerar dados imprecisos, foi
enviada sempre a mesma mensagem em todos os casos, a palavra “teste”. A Tabela 2
apresenta os dados obtidos.
Tabela 2 – Tempo para recuperação da lista de mensagens enviadas
Qtde. Mensagens Tempo em milissegundos
0 50
1 120,4
2 125
3 126
4 143,4
5 182,6
10 231,6 A partir dos dados obtidos é possível observar que ocorre um acréscimo no tempo
conforme cresce o número de mensagens a serem recebidas, no entanto, os valores são
aceitáveis por não representarem um valor que cause uma espera para o usuário. Novamente
vale ressaltar que estes valores podem variar dependendo da qualidade da conexão do usuário.
107
O terceiro teste focou em avaliar o tempo para transmissão de mensagens, desta vez
variando a quantidade de caracteres de cada mensagem. Foi utilizado o caractere ‘a’,
aumentando somente a repetição do mesmo a cada teste. A Tabela 3 apresenta os resultados
obtidos.
Tabela 3 – Tempo para recuperação de mensagem
Qtde. Caracteres Tempo em milissegundos
5 89
25 97
50 77,2
100 126,2
150 114,2
300 82,4
1000 78,8 Observa-se com os dados obtidos, que o tempo para recepção da mensagem não
apresenta um valor de crescimento condizente com o numero de caracteres que ela contém o
que sugere que o tamanho da mensagem não contribui significativamente no tempo da
transmissão da mesma. É provável que as variações obtidas sejam decorrentes da qualidade da
conexão Wi-Fi no momento da realização dos testes.
O ultimo teste de performance visou testar o tempo de transferência de três arquivos,
com tamanhos diferentes, compartilhados por um usuário. Inicialmente realizaram-se os
donwloads dos arquivos utilizando a rede High-Speed Downlink Packet Access (HSDPA)
também conhecida por 3.5G. Após foi configurado o smartphone para realizar os downloads
utilizando a rede Enhanced Data for GSM Evolution (EDGE) também conhecida por 2.5G. O
Quadro 44 apresenta os dados obtidos no teste.
Numero Tamanho do arquivo em bytes Tecnologia de conexão Tempo para o download em milissegundos
1 77.824 HSPA 6564
EDGE 10162
2 514.713 HSPA 10265
EDGE 30341
3 1.174.405 HSPA 17255
EDGE 63992
Quadro 44 – Tempo de transferência de arquivos
Através dos resultados obtidos observa-se que a diferença entre as duas tecnologias é
visivelmente clara. O tempo para download dos arquivos na tecnologia HSPA mostrou-se
sempre menor, no caso do arquivo maior, chegou a ser 3,7 vezes mais rápido. A Figura 37
apresenta o crescimento no tempo de download, conforme aumenta o tamanho do arquivo, no
entanto, percebe-se que para arquivos de tamanho reduzido a diferença do tempo de download
108
não é tão expressiva.
Figura 37 – Tempo para donwload de arquivo
3.4.2 Testes de memória
Nos testes de memória o foco foi analisar o uso de espaço no banco de dados utilizado
pela tabela de usuários (LS_USUARIO) e pela tabela de arquivos compartilhados
(LS_ARQUIVOS), conforme novos usuários são cadastrados e novos arquivos compartilhados.
Para realizar os testes foram inseridos dados fictícios nas tabelas e então analisado o
espaço ocupado pelas mesmas no arquivo de dados do banco de dados, este dado pode ser
obtido pela procedure DBMS_SPACE.OBJECT_SPACE_USAGE nativa do SGBD Oracle. A Tabela
4 apresenta o comparativo do tamanho da tabela LS_USUARIO em relação a quantidade de
usuários cadastrados. Percebe-se que cada novo usuário registrado acresce em 126 bytes o
tamanho da tabela.
Tabela 4 – Espaço utilizado pela tabela LS_USUARIO
Usuarios cadastrados Tamanho da tabela em bytes
2 2262
3 2388
4 2518
5 2644
6 2768
7 2894
8 3020
9 3146
10 3272
109
A Tabela 5 apresenta o comparativo do tamanho da tabela LS_ARQUIVOS em relação a
quantidade de arquivos compartilhados. Para cada novo arquivo compartilhado observou-se
um acréscimo médio de 201,78 bytes no espaço ocupado pela tabela.
Tabela 5 – Espaço utilizado pela tabela LS_ARQUIVOS
Arquivos compartilhados Tamanho da tabela em bytes
1 2402
2 2624
3 2824
4 3042
5 3258
6 3476
7 3660
8 3846
9 4032
10 4218
3.4.3 Comparativo dos trabalhos correlatos
Para uma melhor compreensão das funcionalidades implementadas neste trabalho em
relação as funcionalidades existentes nos trabalhos correlatos foi elaborado o Quadro 45. O
presente trabalho é apresentado como LocalSocial, o trabalho descrito na seção 2.4.1 foi
apresentado como MediaShare, o trabalho descrito na seção 2.4.2 foi apresentado como
Foursquare e por fim o trabalho descrito na seção 2.4.3 foi apresentado como SCVNGR.
Trabalhos
LocalSocial MediaShare Foursquare SCVNGR
Fun
cio
nal
idad
es Geolocalização dos usuários SIM SIM SIM SIM
Troca de mensagem entre os usuários SIM NÃO SIM SIM
Troca de arquivo entre os usuários SIM SIM SIM SIM
Calculo da distancia entre os usuários SIM NÃO NÃO NÃO
Georeferenciação de mídias NÃO SIM SIM SIM Quadro 45 – Comparativo de funcionalidades entre os trabalhos correlatos
Percebe-se que todos os trabalhos têm foco na geolocalização de usuários e a troca de
informação entre os mesmos, no entanto divergem na forma como realizam estas tarefas. O
presente trabalho permite a troca de mensagens e arquivos entre os usuários, mas não permite
que uma mídia seja relacionada com uma coordenada geográfica, funcionalidade presente nos
outros trabalhos.
A troca de mensagem entre os usuários é uma funcionalidade presente em dois dos
110
outros trabalhos, no entanto somente no presente trabalho esta funcionalidade pode ser
realizada sem um vinculo prévio de amizade.
O cálculo de distância entre os usuários não é realizado pelos trabalhos correlatos,
embora em todos seja possível visualizar a posição de outros usuários em um mapa, o que não
é possível no trabalho aqui apresentado.
111
4 CONCLUSÕES
O presente trabalho apresenta três aplicações trabalhando em conjunto para prover uma
solução no cenário de comunicação e troca de arquivos entre usuários geograficamente
próximos. O foco principal se deu no aplicativo cliente, desenvolvido na plataforma Android,
onde foi analisada uma forma eficiente de comunicação com as outras aplicações do sistema.
A comunicação direta entre os aplicativos cliente seria abordada inicialmente, no
entanto, foi encontrada uma limitação quanto a este tipo de conexão quando o dispositivo está
conectado à Internet pelas tecnologias de telefonia móvel.
Optou-se então por utilizar um webservice com a tecnologia SOAP para realizar a
recepção das demandas dos aplicativos clientes e realizar a comunicação entre eles, desta
forma os requisitos do trabalho puderam ser atendidos. Para conectar-se a este webservice, foi
utilizado uma biblioteca externa, propícia para este cenário, a kSOAP2. Esta biblioteca
mostrou-se em alguns momentos ineficaz para a realização de algumas tarefas, principalmente
aquelas que envolviam a transmissão de tipos complexos da linguagem Java. Nestes casos foi
necessário utilizar uma classe wrapper no aplicativo webservice para empacotar os objetos e
então realizar a separação destes dados na aplicação cliente. Este processo poderia ser evitado
caso a biblioteca estivesse preparada para tipos complexos.
Outro ponto observado durante os testes foi a imprecisão dos dados de geolocalização
do usuário quando obtidos através de torres de telefonia. Para contornar este problema foram
priorizados os dados de geolocalização obtidos através de satélites GPS. No entanto, nas
situações em que é necessário depender somente de dados de torres de telefonia a aplicação
pode apresentar uma imprecisão no cálculo de distância entre os usuários, o que se caracteriza
como uma limitação da aplicação.
Outra limitação presente na aplicação é a impossibilidade de realizar o download de
um arquivo compartilhado por um usuário caso este não esteja autenticado no sistema e
dentro da distância limite especificada, mesmo os arquivos estando no servidor da aplicação
webservice e não dependendo desta autenticação para serem obtidos.
Para calcular a distância entre dois usuários foi utilizado a formula matemática de
Haversine, responsável por calcular a distância entre dois pontos sobre uma esfera. Foi optado
por usar esta formula por apresentar uma informação mais precisa do que, por exemplo, o
teorema de Pitágoras que é indicado para o cálculo da distância entre dois pontos em um
plano. No entanto, a formula de Haversine prevê que a esfera onde os pontos estão sendo
112
calculados seja perfeita, o que não é o caso do planeta Terra, portanto ainda podem ocorrer
pequenos erros na distância obtida, dependendo de onde o usuário esteja no planeta. Para
diminuir este erro foi calculada a média do raio da circunferência do planeta e utilizado na
formula como valor constante.
Por fim, a plataforma Android mostrou-se bastante ampla e flexível, pois forneceu
todos os artefatos necessários para a realização dos requisitos deste trabalho, sendo necessária
somente a integração de uma biblioteca externa para a comunicação com webservices, a qual
foi realizada facilmente através da tecnologia de extensão já oferecida pela tecnologia Java. A
integração do SDK do Android ao ambiente de desenvolvimento Eclipse cooperou fortemente
na depuração da codificação e na realização de testes.
4.1 EXTENSÕES
Como sugestões de extensões para a continuidade do presente trabalho, tem-se:
a) permitir a comunicação direta entre os dispositivos móveis, conforme descrito na
seção 3.4;
b) permitir a comunicação entre os usuários através de voz. Ou seja, explorar a
aplicação do conceito de voz sobre IP (VoIP) no presente trabalho;
c) adicionar a opção de visualização dos arquivos baixados de outros usuários. Como
sugestão, pode ser desenvolvida uma nova activity específica por apresentar o
conteúdo destes arquivos conforme o tipo de cada um;
d) permitir que possa ser visualizado uma foto do usuário além do seu nome. Deverá
ser analisada uma forma de obter esta imagem quando recuperado a lista de
usuários próximos;
e) permitir que a aplicação avise quando um determinado usuário esteja
geograficamente próximo. Como sugestão, pode ser desenvolvido um mecanismo
de notificação semelhante ao desenvolvido na subseção 3.3.12.3;
113
REFERÊNCIAS BIBLIOGRÁFICAS
ANDROID DEVELOPERS. Obtaining user location. [S.l.], 2012a. Disponível em:
<http://developer.android.com/guide/topics/location/obtaining-user-location.html>. Acesso
em: 10 maio 2012.
_____. LocationManager. [S.l.], 2012b. Disponível em:
<http://developer.android.com/reference/android/location/LocationManager.html>. Acesso
em: 10 maio 2012.
_____. Activity. [S.l.], 2012c. Disponível em:
<http://developer.android.com/reference/android/app/Activity.html>. Acesso em: 08 jun.
2012.
_____. Service. [S.l.], 2012d. Disponível em:
<http://developer.android.com/reference/android/app/Service.html>. Acesso em: 08 jun.
2012.
_____. AsyncTask. [S.l.], 2012e. Disponível em:
<http://developer.android.com/reference/android/os/AsyncTask.html>. Acesso em: 08 jun.
2012.
CAMPESATO Oswald; CHIN, Stephen; IVERSON Dean. Pro Android Flash: building rich
Internet flash and javafx apps for android smartphones and tablets. Nova Iorque: Apress,
2011.
CANALYS. Android takes almost 50% share of worldwide smart phone market.
[Singapura], 2011. Disponível em: <http://www.canalys.com/newsroom/android-takes-
almost-50-share-worldwide-smart-phone-market>. Acesso em: 04 nov. 2011.
CHAPPEL, David A.; JEWELL, Tyler. Java web services. Sebastopol: O’Reilly, 2002.
CIDADE BIZ. Maioria dos usuários de smartphones no Brasil usa o aparelho para
acessar redes sociais. [São Paulo], 2011. Disponível em:
<http://www.advillage.com.br/conteudo_detalhes.asp?id=57174>. Acesso em: 04 nov. 2011.
COHEN, Dadiv; VITURINO Robson. Pense pequeno: o caminho das grandes inovações é
feito de várias pequenas apostas. Época Negócios, São Paulo, v. 4, n. 52, p. 94-107, jun.
2011.
CONCEIÇÃO, David T. Framework para gerenciamento e disponibilização de
informações multimídia geolocalizadas na plataforma android. 2010. 101f. Trabalho de
Conclusão de Curso (Bacharelado em Ciências da Computação) – Centro de Ciências Exatas
e Naturais, Universidade Regional de Blumenau, Blumenau.
114
COSTA, Daniel G. Java em rede: recursos avançados de programação. Rio de Janeiro:
Brasport, 2008.
FOURSQUARE. About. [Nova Iorque], 2011. Disponível em:
<https://pt.foursquare.com/about>. Acesso em: 07 nov. 2011.
GNU C LIBRARY. ln: WIKIPÉDIA: a enciclopédia livre. [S.l.]: Wikimedia Foundation,
2012. Disponível em: <http://en.wikipedia.org/wiki/GNU_C_Library>. Acesso em: 08 jun.
2012.
GOOGLE MOBILE ADS. Smartphone user study shows mobile movement under way.
[S.l.], 2011. Disponível em: <http://googlemobileads.blogspot.com/2011/04/smartphone-user-
study-shows-mobile.html>. Acesso em: 27 fev. 2012.
GRAZIADIO E-LEARNING. History of geolocation. [Los Angeles], 2011. Disponível em:
<https://wikis.pepperdine.edu/display/GSBME/History+of+Geolocation>. Acesso em: 18
nov. 2011.
HASHIMI, Sayed Y.; KOMATINENI Satya: Pro Android. Nova Iorque: Apress, 2009.
IOS. ln: WIKIPÉDIA: a enciclopédia livre. [S.l.]: Wikimedia Foundation, 2012. Disponível
em: <http://pt.wikipedia.org/wiki/IOS>. Acesso em: 08 fev. 2012.
LECHETA, Ricardo R. Google Android: aprenda a criar aplicações para dispositivos móveis
com o android SDK. 2. ed. São Paulo: Novatec, 2010.
MADDEN, Lester. Professional augmented reality browsers for smartphones:
programming for Junaio, Layar and Wikitude. São Francisco: John Wiley & Sons, 2011.
OASIS. UDDI 101. [S.l.], 2011. Disponível em: <http://www.oasis-open.org/org>. Acesso
em: 23 fev. 2012.
OPEN HANDSET ALLIANCE. Alliance. [S.l.], [2012]. Disponível em:
<http://www.openhandsetalliance.com/android_overview.html>. Acesso em: 10 maio 2012.
PEREIRA, Lúcio C. O.; SILVA, Michel L. Android para desenvolvedores. Rio de Janeiro:
Brasport, 2009.
SVNGR. Support. [Cambridge], 2012. Disponível em:
<http://support.scvngr.com/entries/20299901-what-is-scvngr>. Acesso em: 08 fev. 2012.
TOPLEY, Kim. Java web services: in a nutshell. Sebastopol: O’Relly, 2003.
W3C. SOAP specifications. [S.l.], 2004. Disponível em: <http://www.w3.org/TR/soap/>.
Acesso em: 23 fev. 2012.
115
_____. Web services definition language (WSDL). [S.l.], 2001. Disponível em:
<http://www.w3.org/TR/wsdl>. Acesso em: 23 fev. 2012.
WI-FI. ln: WIKIPÉDIA: a enciclopédia livre. [S.l.]: Wikimedia Foundation, 2011. Disponível
em: <http://pt.wikipedia.org/wiki/Wi-Fi>. Acesso em: 18 nov. 2011.
WILKINSON, Colin. Mobile platforms: getting information on the go. Nova Iorque: The
Rosen Publishing Group, 2011.