Home > Artigos > Java ME >
Entendendo a Java Location API
Publicado em 17/08/2009 - 8.653 visualizações
Introdução
Os LBSs (Location Based Service) definem aplicações sensíveis à localização do usuário final, um exemplo são os sistemas de rotas, onde, através de um ponto de chegada, o sistema apresenta o melhor caminho para atingir o ponto desejado. Aplicações desse porte são comuns em países como os Estados Unidos e o Japão, porém, no Brasil já podemos perceber um aumento na oferta de sistemas LBSs.
Para obter a posição da pessoa ou de um objeto, como um telefone celular, o sistema deve obrigatoriamente obter a posição geográfica, de maneira inferida ou dinâmica. Uma posição é obtida de forma inferida quando o usuário especifica sua posição, um bom exemplo é o sistema Ufind da Kwead.com, onde é definido o par endereço - número dos pontos de partida e chegada. A localização dinâmica autodenomina-se, sendo assim, a aplicação deve recuperar a posição automaticamente. Atualmente existem as soluções baseadas em rede (network-based) e as baseadas no dispositivo (handset-based). Como o foco deste artigo não é discutir estes métodos, apenas cita-se o GPS (Global Position System), um dos métodos de posicionamento global mais conhecido.
Assim como sistemas baseados em localização, a Computação Móvel e o uso de telefones celulares também evolui rapidamente, prova disso são os mais de 105 milhões de celulares habilitados no Brasil. Dentre as diversas linguagens e plataformas para desenvolvimento de aplicativos móveis, a Java ME se destaca no mercado mundial. Sendo assim, o objetivo deste artigo é mostrar o uso da API Java Location API, um dos pacotes opcionais do Java ME, que permite ao desenvolvedor criar aplicações LBS para pequenos dispositivos.
Pacotes Opcionais Java ME
A Figura 1 define a plataforma Java ME, onde, a primeira camada existente sobre o Sistema Operacional nativo do aparelho é a configuração, que pode ser a CLDC (Connected, Limited Device Configuration) ou a CDC (Connected Device Configuration), sendo que, a CLDC é a usada largamente em telefones celulares. Segundo Muchow (2004, p. 3), a configuração define uma plataforma Java para uma ampla variedade de dispositivos. Ela está intimamente ligada a uma Máquina Virtual Java. Na verdade, uma configuração define os recursos da linguagem Java e as bibliotecas básicas da JVM para uma família de tipos de dispositivos em particular.
Posteriormente, têm-se o perfil, sendo que, a MIDP (Mobile Information Device Profile) é atualmente, o único perfil existente para a CLDC. O perfil está inserido acima da configuração na arquitetura Java ME, ela define a API para um nível superior aos detalhes da JVM. Segundo Wells (2004, p. 15-16) as configurações não cobrem todos os requisitos de interoperabilidade entre os diversos dispositivos, sendo que, para tratar desta exigência, foram criados os perfis Java ME.
Figura 1? Plataforma Java ME. (SUN).
Acima da configuração e do perfil encontra-se os pacotes opcionais, que permitem às aplicações Java ME oferecer recursos especializados sem impedir que equipamentos restritos possam usufruir de seus recursos. Por exemplo, a MMAPI (Mobile Media API) define um conjunto de classes e interfaces para tratamento de dados multimídia. Se a MMAPI fosse obrigatória, os aparelhos sem câmera digital não poderiam usar a Java ME. A tabela 1 mostra apenas uma pequena parte dos pacotes opcionais existentes atualmente.
A tabela destaca a JSR 179 (a Location API for J2ME), que será trabalhada neste artigo. Esta API traz um conjunto de classes, métodos e interfaces que permite que as aplicações Java ME possam ser sistemas LBS. A JSR 179 trabalha com localização dinâmica, e não faz distinção ao método de busca da localização, pode ser um método como o GPS, mas também, pode ser um Cell ID (baseado nas Estações Rádio Base das operadoras de telefonia celular). Outra questão importante sobre a API, é o fato dela funcionar corretamente somente em dispositivos com a CLDC 1.1, devido a necessidade do uso de números em pontos flutuante.
Location API for J2ME
Há uma vasta documentação na internet, que traz um detalhamento das classes e interfaces que compõe esta API. Como não é este o objetivo do presente artigo, mas sim, mostrar através de captura de códigos uma forma sucinta e direta de construção de um sistema LBS com a JSR 179. Para rodar o exemplo deste tutorial indica-se o uso da IDE Net Beans 5.5 ou inferior juntamente com a Sun Wireçess Toolkit versão 2.5. Este artigo foi baseado no texto MIDP: Location API Developer ' s Guide, do forum Nokia para desenvolvedores. Recomenda-se a leitura deste texto, principalmente nas seções Geographic Coordinate System (fala sobre o sistema de coordenadas) e Location API Usage (que detalha as classes da API).
Criando critérios e obtendo dados geográficos
O uso da API começa pela classe LocationProvider, é ela quem fornece uma instância da classe Location, que por sua vez, informa os dados de latitude, longitude e altitude, vitais para qualquer cálculo de posição geográfica. Porém, retrocedendo alguns passos, para instanciar um LocationProvider é necessário uma instância da classe Criteria.
A classe Criteria define os parâmetro de instância do LocationProvider. Por exemplo, os métodos setHorizontalAccuracy () e setVerticalAccuracy () definem a precisão horizontal e vertical do localizador. O método setSppedAndCourseRequired () define se serão recuperadas as informações de velocidade e curso. A Listagem 1 define a criação do objeto crit1 no documento da Nokia. A Listagem 2 mostra a instância no código exemplo que acompanha este artigo.
Criteria crit1 = new Criteria(); |
Listagem 1 ? Definição dos critérios de busca
criteria.setHorizontalAccuracy(Integer.parseInt(txfPrecisaoHor.getString().trim())); |
Listagem 2 ? Definição dos critérios de busca no código exemplo
Depois de criada a instância da classe Criteria, o próximo passo é instanciar a LocationProvider. A Listagem 3 mostra como este passo foi efetuado no código exemplo deste artigo. A listagem ignora os testes feitos para saber se a instância de Criteria estava criada corretamente, para isso, veja o código completo no exemplo. A linha 1 usa os dados da Listagem 2 para criar a instância. O método setLocationListener (linha 7) adiciona um listener à aplicação, criando eventos a cada atualização da posição geográfica. A Listagem 9 mostra os métodos obrigatórios para esta interface.
1: provider = LocationProvider.getInstance(criteria); |
Listagem 3 ? Criação do LocationProvider
Com o objeto provider podemos criar objetos Location para recuperar a posição geográfica do usuário. O código exemplo não implementa nenhuma função para mostrar os dados geográficos, sendo assim, a Listagem 4 traz o código para recuperar os dados de velocidade, curso, latitude, longitude e altitude do usuário ou objeto, em qualquer momento. No método getLocation(), passamos como parâmetro o tempo máximo de espera para recuperação das informações, os métodos a seguir são auto explicativos. Na linha 4 é criado a instância de QualifiedCoordinates, responsável pela recuperação dos dados de latitude, longitude e altitude, vitais em um sistema LBS.
1: Location location = provider.getLocation(60); |
Listagem 4 ? Uso do LocationProvider
Landmark e LandmarkStore
Através das classes Landmark e LandmarkStore é possível armazenar pontos pré-definidos, definidos por suas coordenadas geográficas. Um Landmark pode ainda, ter informações adicionais anexadas a um ponto, como o nome do país, estado, cidade, rua, telefone, dentre outros. Além disso, um Landmark pode ser usado como um listener, quando o equipamento móvel se aproxima de um ponto pré-selecionado um evento é acionado. Vamos à codificação!.
Quando um Landmark é criado, o ideal é armazéna-lo em um repositório de landmarks, que é o LandmarkStore. A persistência dos Landmarks é mostrada na Listagem 5. Na primeira linha, o método getInstance() é chamado, instanciando o LandmarkStore com o nome passado por parâmetro para o método. O trecho de código que vai da linha 8 até a 22 verifica se a instância foi criada corretamente. Se isso não aconteceu, a linha 12 cria um LandmarkStore.
1: try |
Listagem 5 ? Criando LandmarkStore
O processo de criação do LandmarkStore é feito no método startApp() da MIDlet de exemplo, que segue este artigo. O próximo passo é a criação dos Landmarks. A Listagem 6 exemplifica os passos a serem tomados para a correta execução deste procedimento. Uma instância de Landmark é criada com seu construtor, através do famoso new. Seus parâmetros são: nome, descrição, instância de QualifiedCoordinates e uma instância de AddressInfo. Essas instâncias são criadas nas linhas anteriores à sua criação, que acontece na linha 12.
Como dito anteriormente, a classe LocationProvider é de suma importância no uso desta API. Com sua instância, captura-se a classe Location (linha 1), que é usada posteriormente para a criação de uma instância da classe QualifiedCoordinates (linha 11). A linha 3 instancia um objeto de AddressInfo, para que o Landmark possa ter algumas informações adicionais, sendo que, no exemplo da Listagem 6 são usados os campos CITY, COUNTRY, PHONE_NUMBER, POSTAL_CODE, DISTRICT, STATE e STREET. Porém, esses não são os únicos campos da AddressInfo.
Por fim, a linha 13 adiciona o Landmark criado ao LandmarkStore, passando como segundo parâmetro o nome da categoria do Landmark.
1: location = provider.getLocation(60); |
Listagem 6 ? Criando um Landmark
Criando liteners para Landmarks
A JSR 179 permite ainda que um listener possa ser associado a uma instância de Landmark, permitindo que avisos possam ser emitidos no momento que o dispositivo se aproxima de um ponto pré-configurado. No código exemplo do artigo, na opção de listagem dos Landmarks, os mesmos são inseridos em um vetor. A Listagem 7 ilustra o código que recupera o Landmark que está selecionado na lista, e envia suas coordenadas para o método createProximityListener, mostrado na Listagem 8.
Landmark lan = (Landmark)vetLandmarks. |
Listagem 7 ? Adicionando um listener a um Landmark
public void createProximityListener(Coordinates coordinates) |
Listagem 8 ? Método createProximityListener
O método createProximityListener chama o método estático addProximityListener da classe LocationProvider, passando como parâmetro as coordenadas do Landmark e um valor de ponto flutuante que especifica a distância que identifica a aproximação ao ponto selecionado. A classe deve implementar as interfaces LocationListener e ProximityListener, e, consequentemente seus métodos, ilustrados na Listagem 9. Na Listagem 8, o método addProximityListener passa como primeiro parâmetro, uma classe que implementa as duas interfaces.
public void locationUpdated(LocationProvider locationProvider, Location location) {} |
Listagem 9? Métodos da nterface LocationListener e ProximityListener.
No momento que o listener desta interface perceber a aproximação a um ponto pré-determinado, o método proxmityEvent é chamado. Na Listagem 9 é possível ver a ação que a aplicação mostra ao perceber esta aproximação. Um alerta é mostrado no display do equipamento, alertando sobre a aproximação a um Landmark. Para visualizar o método findNearestMark veja o código do exemplo na íntegra.
A aplicação exemplo
A aplicação exemplo é bem simples, sem nenhum recurso gráfico, apenas mostra um Form na tela principal, com as seguintes opções de Command: Opções de Busca, Criar Criteria, Criar Provider, Criar Landmark e Listar Landmark. A primeira opção traz as configurações que podem ser alteradas para a criação da instância da classe Criteria, criada com a opção Criar Criteria. A Figura 1 ilustra a tela principal e a Figura 2 o formulário de configuração dos dados para o Criteria.
| | |
| Figura 1 ? Tela inicial. | Figura 2 ? Tela de configuração dos dados para o Criteria. |
Como o emulador da Sun não vai acessar os receptores GPS através do PC, acesse o menu MIDlet - & gt; External Events para emular um comportamento semelhante, olhe as Figuras 1 e 2, na parte superior esquerda. Uma tela igual à Figura 3 deve aparecer.
Figura 3 ? Eventos externos.
Clique no botão? Browse?, na tela de diretórios que abrir, escolha a pasta CityGuide, se acaso se perder nos diretórios, procure o diretório de instalação do WTK, e entre na seguinte árvore de diretórios: \ apps \ CityGuide. O arquivo citywalk.xml ficará visível, então escolha a opção Open. Neste momento você será direcionado a tela da Figura 3 novamente, porém, agora, o botão? Play?, na parte inferior, ficará habilitado. Clique neste botão. O arquivo citywalk emula uma série de coordenadas geográficas (latitude, longitude, altitude), como se o celular mostrado pelo WTK estivesse acessando os dados GPS realmente.
Voltando para o aplicativo, escolha a opção? Criar Criteria?, se tudo correr bem, uma mensagem? Criteria criado com sucesso? aparecerá no Form principal. Em seguida, escolha a opção? Criar Provider?, da mesma forma, uma mensagem de sucesso deve aparecer no display. A opção? Crisar Landmark? mostra um formulário com os dados do Landmark a ser criado, preencha todos e dê Ok. A mensagem de confirmação aparecerá novamente. Para ver a aplicação realmente funcionando, escolha a opção? Listar Landmarks?, na lista que vem a seguir escolha a opção? Criar Listener? para um landmark. Posteriormente, volte à tela inicial do sistema, e volte a barra de progresso que aparece na Figura 3 até seu início (a barra está localizada na parte inferior). E aguarde a mensagem de aproximação ao landmark aparecer na tela, conforme a Figura 4.
Figura 4 ? Aviso da aplicação sobre aproximação ao Landmark.
Conclusão
A JSR 179 será importante à medida que os sistemas LBS ganharem mais espaço no cenário tecnológico, algo comum em países mais desenvolvidos. O conhecimento desta API pode colocar o leitor um passo à frente, pronto para as mudanças que irão acontecer, além de ter o conhecimento de mais um dos pacotes opcionais da Java ME. Com a utilização da JSR 179 várias aplicações interessantes podem ser criadas, o limite ainda é o seu uso em poucos equipamentos, mas isso vai mudar com certeza. Então, mãos à obra.
Referência Bibliográficas
MUCHOW, John W. Core J2ME: Tecnologia e MIDP. Tradução João Eduardo Nóbrega Tortello. São Paulo: Pearson Books. 2004.
SUN. Introduction to Mobility Java Technology. Disponível em: & lt; http://developers.sun.com/mobility/getstart/ & gt;. Acesso em Agosto de 2007.
WELLS, Martin J. J2ME Game Programmming. Boston. Premier Press. 2004.
Sobre o autor
Ricardo da Silva Ogliari é formando em Ciência da Computação pela Universidade de Passo Fundo? RS. Desenvolveu sistemas mobile para empresas do Rio Grande do Sul, atualmente trabalha como desenvolvedor de aplicações direcionadas a telefones celulares na Kwead.com de São Paulo. Também, foi palestrante dos eventos JustJava 2005 e EJES (Encontro Java do Espírito Santo) 2005, além de ministrar alguns cursos sobre a tecnologia Java ME.


