39

Utilizando o recurso de GPS em uma app Android

by Luiz Jr 19. novembro 2011 15:03

Olá, este será mais um post sobre a melhor plataforma de desenvolvimento mobile da atualidade, o Android. Os números não me deixam mentir, com o SO do Google dominando mais de 50% do mercado de smartphones no mundo e com mais de 250 mil aplicativos disponíveis no Android Market (desses, cerca de 130 mil gratuitos). Neste post, iremos tratar do uso do hardware de GPS presente em alguns dispositivos com Android, como o Motorola Defy e o Motorola Milestone, só para citar alguns exemplos que pude utilizar (sem contar a infinidade de xing-lings que tem no mercado). A idéia é utilizar tal hardware para descobrir onde o usuário da app está e com essa informação em mãos, você fazer o que quiser, como plotar esta localização em um mapa do Google Maps, por exemplo.

Mas já não existe aplicações que fazem isso? Sim, e aos montes. Então por que diabos eu iria querer aprender a fazer isso? Simplesmente porque a idéia aqui é estudar o funcionamento de aplicações que consumam os dados do GPS nativo do aparelho, para então, desenvolver suas próprias aplicações que necessitem de tais dados. Como exemplo podemos citar aplicações como o Four Square, que coleta a informação de sua localização para garantir que você realmente está no local que diz estar ou o Google Latitude, que permite ver onde seus amigos estão neste exato momento, só para citar algumas. No meu caso o estudo é pertinente a um trabalho freelancer com a plataforma, que exigirá conhecimentos dessa API.

Usando a Android Location-Based API

O Android SDK contém uma API que foi criada especialmente para utilizar de forma abstrata sua Activity com qualquer hardware de GPS que possa existir em seu dispositivo. Uma vez que normalmente trabalhamos com um emulador baseado em software (O AVD - Android Virtual Device), e não com um dispositivo de verdade, a presença do hardware de GPS terá que ser simulada. Para que isto ocorra o emulador que você está utilizando deve prover simulação de hardware GPS, o que você pode aplicar indo no AVD Manager e criando (ou editando) um AVD, adicionando tal recurso, como mostra na tela abaixo:

Adicionando suporte ao GPS

Uma vez que seu AVD tenha suporte à GPS, você usará o console do ADB (Android Debugger Bridge) para enviar comandos de localização, simulando que o usuário do dispositivo se locomoveu. Também usaremos as ferramentas existentes no Motodev Studio 3 (e provavelmente devem existir no Eclipse tradicional também) para enviar as coordenadas ao emulador que você deseja testar. Estas ferramentas ficam disponíveis na aba Emulator Control, no rodapé da IDE, como mostra a figura abaixo. Com elas é possível simular que o celular encontra-se em uma região diferente da atual, para que você possa testar sua aplicação sob diferentes circunstâncias (as configurações de GPS estão na aba Emulator Control, porém devem rolar um pouco para baixo até encontrá-las).

Simulando coordenadas GPS

A outra forma, é usando o Console do ADB, que você habilita indo na aba Gerenciador de Dispositivos e clicando no ícone Console. Uma vez com o console aberto, você pode enviar comandos ao emulador que está rodando em seu MotoDev/Eclipse. O comando que você utiliza para enviar posições GPS é o geo. O geo na verdade é um grupo de comandos para manipulação de localização, e o que iremos usar é o geo fix. Digitando "geo fix help" no console você consegue dicas de como usar este comando. Resumindo, basta digitar "geo fix <longitude> <latitude>" visto que dificilmente você irá usar os demais parâmetros, como altitude, por exemplo. A figura abaixo mostra o funcionamento do console, inserindo as coordenadas de Porto Alegre-RS:

Comando geo fix

Lendo os dados de GPS com a Android Location-Based API

O restante deste post irá tratar exclusivamente do desenvolvimento de uma aplicação "OndEstou" que identifica a localização do usuário, sendo esta primeira parte bem simples, pois apenas exibirá a informação de latitude e longitude de onde o usuário se encontra, lhe dando uma base para prosseguir com o restante dos estudos da API. Os seguintes passos serão executados para que nossa demo tenha sucesso: devemos ajustar os níveis de permissão, criar o layout de nossa Activity, escrever o cpodigo da Activity e testá-la.

Ajustando o Nível de Permissão

O primeiro passo para trabalhar com a Android Location-Based API é ajustar o nível de permissão. Usar a API por si só não requer nenhuma permissão específica, mas usar a mesma para acessar informações de localização no GPS sim. A maneira mais fácil de setar permissões para um aplicativo é através da edição do manifesto do seu projeto, que foi descrito em meu último post. Este manifesto é facilmente editável pelo MotoDev Studio (de forma idêntica ao Eclipse tradicional).

Primeiramente, vamos criar um novo projeto no MotoDev/Eclipse com o nome de OndEstou, a versão do Android 2.2 (a mais comum no Brasil), com a Activity MainActivity.java. Em seguida, vamos abrir o arquivo AndroidManifest.xml e na aba Permissions do editor visual do manifesto, vamos adicionar a seguinte permissão (do tipo Uses Permission): ACCESS_FINE_LOCATION, como indicado na figura abaixo:

Acces Fine Location

Criando o layout de sua aplicação

Para iniciar o desenvolvimento do seu layout, abra o arquivo main.xml no MotoDev/Eclipse. Você terá de adicionar um Button e quatro TextView no seu layout, como a tela abaixo mostra:

Layout OndEstou

Este layout pode ser obtido com o código de exemplo abaixo, mas encorajo que você tente criar o seu sem utilizar este código (afinal, é um layout bem simples):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

    <Button
    android:id="@+id/btnGps"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Onde estou?"/>
   
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
   
    <TextView
    android:id="@+id/lblLatitude"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Latitude: "/>
   
    <TextView
    android:id="@+id/txtLatitude"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    </LinearLayout>
   
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
   
    <TextView
    android:id="@+id/lblLongitude"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Longitude: "/>
   
    <TextView
    android:id="@+id/txtLongitude"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
    </LinearLayout>

</LinearLayout>

Escrevendo o código da sua Activity

Agora que você criou o layout, você pode começar a escrever o código que irá executar sua Activity. Seu Button precisa iniciar o serviço de monitoramento do GPS, para então enviar a latitude e longitude ao TextView correspondente. Primeiro você irá precisar adicionar nove diretivas import, que são os packages necessários para o funcionamento da Activity. Embora alguns programadores sintam-se tentados a adicionar imports mais genéricos como android.location.*, evitem isso para diminuir o tamanho de suas aplicações com código de biblioteca desnecessário:

 

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.content.Context;
import android.widget.Button;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;

 

A seguir, devemos criar o código para o evento OnCreate de sua Activity, que irá carregar os widgets de sua aplicação e definir o algoritmo para o evento Click do Button. O objetivo é que quando se clique no botão, seja registrado um Listener para o serviço de GPS que passará a enviar informações de localização à app. O código abaixo exemplifica o código necessário:

 

Button btnGps;
	TextView txtLatitude;
    TextView txtLongitude;
	
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        txtLatitude = (TextView) findViewById(R.id.txtLatitude);
        txtLongitude = (TextView) findViewById(R.id.txtLongitude);
        
        btnGps = (Button) findViewById(R.id.btnGps);
        btnGps.setOnClickListener(new Button.OnClickListener() {
	        public void onClick(View v){
	        	IniciarServico();
        }});
    }

Note que ainda não criamos o método IniciarServico, então é natural que sua IDE acuse um erro neste código. Além de carregarmos o botão, carregamos os TextViews que serão editados (txtLongitude e txtLatitude, neste exemplo). Os demais TextViews não serão instanciados pois eles são apenas rótulos de texto, e não serão editados posteriormente. Agora começamos a brincar com o serviço de GPS do Android, que é invocado através de um objeto Location Manager, que carrega o serviço de localização do dispositivo, como segue (agora criando nosso método IniciarServico):

 

public void IniciarServico()
    {
    	LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    	
    	LocationListener locationListener = new LocationListener() {
    	    public void onLocationChanged(Location location) {
    	      Atualizar(location);
    	    }

    	    public void onStatusChanged(String provider, int status, Bundle extras) {}

    	    public void onProviderEnabled(String provider) {}

    	    public void onProviderDisabled(String provider) {}
    	  };

    	  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
    }

 

E por fim, devemos codificar o método Atualizar, que nada mais faz do que pegar o objeto Localization enviado pelo serviço de GPS e jogar suas informações nos TextViews correspondentes à latitude e longitude:

 

public void Atualizar(Location location)
    {
    	Double latPoint = location.getLatitude();
    	Double lngPoint = location.getLongitude();
        
        txtLatitude.setText(latPoint.toString());
        txtLongitude.setText(lngPoint.toString());
    }

App GPS funcionando

Para testar sua aplicação, basta rodá-la no MotoDev/Eclipse em um AVD configurado com o hardware de GPS, como citei no início do post e clicar no botão "Onde estou?" para ficar monitorando o serviço de GPS. Nada aconteceu? Não esqueça de enviar comandos de localização pelo console (usando geo fix) ou pelo editor gráfico na aba Emulator Control. O resultado esperado você vê na direita.

Abaixo você pode fazer download de todo o código fonte do projeto. Futuramente talvez eu continue este post ensinando como plotar esta informação em uma camada overlay na App do Google Maps, disponível em todos os aparelhos Android. Espero que tenham gostado do post e até a próxima.

OndEstou.zip (53,42 kb)

Tags: , , ,

Android | Mobile

Comentários

Wenderson
Wenderson Brasil
31/1/2012 14:40:07 #

Mto bom cara, ajudou muito mesmo.

Porém o Gps fica buscando, mas não retorna nada, vou verificar o possível problema.

luizfduartejr
luizfduartejr Brasil
31/1/2012 15:05:03 #

As permissões necessárias foram definidas? Eu explico quais são as importantes no post. Você está usando o simulador de localização? Sem ele o GPS não funciona.

Wcunha
Wcunha Brasil
4/3/2012 09:03:26 #

Mandou bem. Bem explicativo.

Leandro
Leandro Brasil
31/3/2012 20:03:57 #

Muito Bom!!! Parabens!!! Colocou para rodar com poucas linhas de código. Estou me fodendo no livro do R.Lecheta. Apesar de ser um bom livro esta parte é um pouco complicada, até porque não sei programar em java direito.
Valeu!!!

Gil Novack
Gil Novack Brasil
10/4/2012 18:53:52 #

Amigo,
Estou precisando um app que capture latitude e longitude no android, vc conhece algum? Estou coordenando uma pesquisa que irá usar tablets android, mas preciso geo-referenciar o local de cada entrevista, apenas com a latitude e a longitude. Vejo que sua explicação é bem detalhada, porém não conheço programação android. Só conheço programação de softwares matemáticos e estatísticos.

Oraculum
Oraculum Brasil
15/4/2012 07:02:40 #

Bem explicado!!! Só uma observação, para enviar a geo location no linux ou mac deve-se usar o telnet veja como:

telnet localhost 5554
geo fix 48 51

mais informações podem ser encontradas aqui: oraculum.blog.br/.../

asd
asd Brasil
24/4/2012 13:48:11 #

mto bom

Silvio Márcio Lacerda Dantas
Silvio Márcio Lacerda Dantas Brasil
28/4/2012 21:11:23 #

Meu querido, seria possível enviar as coordenadas do GPS ao receber um SMS. Isso automaticamente.
public class ReceberSms extends BroadcastReceiver {
  //private static final String CATEGORIA = "livro";

  @Override
  public void onReceive(Context context, Intent intent) {
        
    //Lê a mensagem
    Sms sms = new Sms();
    SmsMessage msg = sms.receberMensagem(intent);
    String celular = msg.getDisplayOriginatingAddress(); //numero de quem enviou a sms ou email
    String mensagem = msg.getDisplayMessageBody();   //Mensagem recebida deve ser a senha

    //Senha cadastrado no txt
    String senha = "123";
    
    AquiEstou o = new AquiEstou();
    String teste = o.Aqui(null);

    
    //Toast.makeText(context, pos , Toast.LENGTH_SHORT).show();
    

        
    //Envio de uma mensagem caso o sms com a senha seja igual.
    if (mensagem.equals (senha)){
      Toast.makeText(context, teste, Toast.LENGTH_SHORT).show();
      //SmsManager sm = SmsManager.getDefault();
      //sm.sendTextMessage(celular, null, "teste" , null, null);

    }else {
      //Toast.makeText(context, mensagem + " = " + senha , Toast.LENGTH_SHORT).show();
      //SmsManager sm2 = SmsManager.getDefault();
      //sm2.sendTextMessage(celular, null, "Senha invalida!", null, null);
    }  
  
  }
}

Rudrigo Lima
Rudrigo Lima Brasil
7/8/2012 21:18:56 #

Amigo, parabéns pelo post muito bom porem ao montar no meu motodev funcionando corretamente já no tablet xoom andorid 4.0.4 não funcionou, simplesmente não instala

luizfduartejr
luizfduartejr Brasil
7/8/2012 22:12:07 #

Boa noite Rudrigo,

pode ser que aconteça mesmo. Muitas vezes as APIs são alteradas entre as versões do Android. O que te recomendo é começar um projeto específico para a versão 4 do Android e tentar executar o mesmo passo-a-passo deste tutorial para criar uma app com GPS. Se realmente mudou a API, ela não irá funcionar, dai terá que ir atrás de informações específicas dessa nova versão do Android.

assis
assis Brasil
30/8/2012 16:14:28 #

Bom testei e tudo ficou bem. mas como faz para desligar o gps, depois das coordenadas, que fica ligado direto?

assis
assis Brasil
30/8/2012 16:41:58 #

como faz para desligar o gps depois de pegar as coordenadas

luizfduartejr
luizfduartejr Brasil
30/8/2012 19:42:58 #

Da maneira como eu mostrei a app ficará sempre coletando as informações. Como este era um projeto de um cliente, implementei dessa forma, mas se der uma olhada na API de GPS do Android encontrará outras maneiras de fazer, inclusive pegando as coordenadas apenas uma vez.

assis
assis Brasil
1/9/2012 10:43:46 #

Amigo tentei de tudo mas nao consegui fazer com que a app pare de coletar as coordenadas. Voce poderia me dar uma dica? Obrigado.

luizfduartejr
luizfduartejr Brasil
5/9/2012 20:32:42 #

Boa noite Assis,

sugiro dar uma lida na documentação oficial, aqui: developer.android.com/.../index.html e aqui: developer.android.com/.../package-summary.html

Dan Martinss
Dan Martinss Brasil
23/9/2012 23:20:22 #

Pra quem está tentando pegar a localização apenas uma vez, segue código modificado:

package com.GeoTCC.cadeeu;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.content.Context;
import android.widget.Button;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;

public class MainActivity extends Activity
{
  Button btnGps;
  TextView txtLatitude;
    TextView txtLongitude;
    
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        txtLatitude = (TextView) findViewById(R.id.txtLatitude);
        txtLongitude = (TextView) findViewById(R.id.txtLongitude);
        
        btnGps = (Button) findViewById(R.id.btnGps);
        btnGps.setOnClickListener(new Button.OnClickListener() {
          public void onClick(View v){
            IniciarServico();
        }});
    }
    
    public void IniciarServico()
    {
      
      LocationManager LM = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
      String bestProvider = LM.getBestProvider(new Criteria(),true);
      
      Location location = LM.getLastKnownLocation(bestProvider);

      
        txtLatitude.setText(String.valueOf(location.getLatitude()));
        txtLongitude.setText(String.valueOf(location.getLongitude()));
      
    }
    
}

com essa implementação pode-se pegar também altitude (location.getAltitude)

luizfduartejr
luizfduartejr Brasil
24/9/2012 00:32:14 #

Opa, valeu a contribuição Daniel.
No momento estou envolvido com uns projetos para iOS e não tive tempo de ir atrás da necessidade do Assis.
Valeu mesmo.

Dan Martinss
Dan Martinss Brasil
24/9/2012 00:36:33 #

Cara,
Eu que agradeço pelo seu post. Estou fazendo meu TCC em Geoprocessamento e esse tutorial me deu uma boa base para começar. Meu desafio agora é enviar esses dados de localização, junto com uma identificação, para um web service (estou tentando usar Google Fusion Tables). Se tiver algo nesse sentido pra compartilhar ajudaria seria de grande ajuda.

Abraço.

luizfduartejr
luizfduartejr Brasil
24/9/2012 01:11:32 #

Fico feliz em saber que o post foi útil.
Pena que eu não tenho muito o que contribuir, minha única experiência com geoposicionamento foi usando o código que está nesse post. Nunca fui muito a fundo e nem mesmo conheço o Google Fusion Tables.
Boa sorte com o TCC!

Evandro
Evandro Brasil
4/10/2012 13:15:39 #

Caro colega,
eu estou com um pequeno problema, a aplicação roda, o botão funfa legal, porém nada aparece na tela.

Pode me explicar o pq ?

Grato.

luizfduartejr
luizfduartejr Brasil
4/10/2012 17:39:09 #

Boa noite Evandro, o seu AVD possui o hardware de GPS? Isso é configurável durante a criação do AVD e é necessário para o funcionamento do exemplo.

jhonny
jhonny Brasil
31/10/2012 10:13:13 #

muito sua aplicaçao, mais tenho uma pergunta e si eu quere colocar um mapa, nao precisa ser visao da rua, apena visao de cima, tem como ??

jhonny
jhonny Brasil
31/10/2012 10:19:54 #

desculpa vou reformular minha pergunta,  gostaria de saber si tem como colocar mapa offline nele ???

luizfduartejr
luizfduartejr Brasil
31/10/2012 12:12:43 #

Bom dia Jhonny, boa pergunta. Até onde sei, só se tu tiver as imagens dos mapas e carregar na tua aplicação. As APIs nativas todas tem de estar online pra funcionar. Se alguém souber alguma maneira de como ajudar o jhonny posta aí nos comentários.

Gesiel Diniz
Gesiel Diniz Brasil
7/11/2012 15:25:54 #

Valeu cara, muito bom!, parabéns pela iniciativa.

Obrigado

WFerreira
WFerreira Brasil
12/11/2012 13:16:46 #

Galera não estou conseguindo fazer rodar essa aplicação.. o que pode estar acontecendo? Fiz um novo projeto para o android 2.3.3

alguma coisa haver?

aguardo resposta!

jhonny
jhonny Brasil
16/11/2012 08:30:17 #

WFerreira qual eh o erro que ele apresenta, ele nao entra na aplicaçao ??

Valeria
Valeria Brasil
25/11/2012 19:55:02 #

Como faço pra testar em um celular de verdade com gps?
tentei aqui mas não faz nada quando eu clico no botão.

luizfduartejr
luizfduartejr Brasil
25/11/2012 20:51:02 #

Boa noite Valeria, o seu celular possui hardware de GPS? Pergunto isso pois alguns modelos possuem GPS apenas via Internet. Além disso, o seu recurso de GPS está ativado?

Valeria
Valeria Brasil
25/11/2012 21:08:34 #

Meu celular é um galaxy sII lite, não sei se possui somente via internet mas vou ver aqui, mas acabei de inserir permissão de INTERNET, ainda sem sucesso. E o recurso tá ativado sim. Gostaria de entender se existe alguma coisa a mais pra configurar direto no celular!

luizfduartejr
luizfduartejr Brasil
25/11/2012 21:49:35 #

Faz muito tempo desde que rodei este exemplo pela última vez. No simulador está funcionando para você? Se não estiver funcionando nem no simulador, aí temos um problema sério.

Uma alternativa é conectar seu smartphone via cabo USB e depurar o aplicativo diretamente nele, acompanhando o que está acontecendo passo-a-passo.

Valeria
Valeria Brasil
25/11/2012 21:54:27 #

No simulador funcionou legal, usei o Emulator Control e carreguei lá algumas coordenadas e deu certo.

Vou fazer a depuração pra tentar entender o que falta, será que não é devido a falta de modificação no posicionamento do GPS? Andei estudando que o onLocationChanged é disparado quando existe uma modificação.

luizfduartejr
luizfduartejr Brasil
25/11/2012 22:54:53 #

Sim é, mas ainda assim imagino que ele devesse disparar uma primeira vez por causa da posição inicial. Mas posso estar errado, faz tempo que não mecho com essa API do Android. Se tiver sucesso em descobrir o problema, peço que passe aqui novamente para postar pro pessoal. Pode ser?

Michel Cruz
Michel Cruz Brasil
24/1/2013 14:00:10 #

Cara, primeiramente parabéns pelo artigo, sem duvida é de muito ajuda.
Queria saber como faria pra traçar uma rota, conforme eu vo andando vai "pintando" no mapa.

luizfduartejr
luizfduartejr Brasil
24/1/2013 14:52:28 #

Boa tarde Michel, tem uma outra APi que não lembro o nome que é a dos mapas. Nela tu tem a opção de  além de exibir mapas conforme a localização do usuário, de criar uma camada transparente por cima do mapa que você pode editar, colocando pins, riscando, etc.

Dá uma procurada na documentação oficial, pois faz tempo que não mexo com isso. http://developer.android.com

feliperamos
feliperamos Brasil
13/4/2013 21:07:30 #

pessoal boa noite gostaria de saber onde poe esse codigo de  GPS ao receber um SMS

logo a acima

abraços

luizfduartejr
luizfduartejr Brasil
14/4/2013 00:34:17 #

Esse tutorial é sobre uso do GPS Felipe, não entendi o motivo do questionamento sobre SMS, sendo que uma API não tem relação alguma com a outra.

tgoferreira
tgoferreira Brasil
26/4/2013 16:07:29 #

Otimo tutorial...
Tutorial..
testei com sucesso....

teste tambem com uma chamada unica, conforme nosso amigo "Dan Martinss", mas percebi que a atualização nesse caso não esta sendo feita em tempo real...ou seja... a cada request que faço, muitas vezes ele pega a localização em caceh, ao inves de buscar a localização real... não sei se isso tem algo com o provider...

José
José Brasil
31/8/2013 11:01:05 #

Testei no galaxy 5, rodou, mas não mostrou as coordenadas.

Comentar


(Vai mostrar seu Gravatar)

  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading



Powered by BlogEngine.NET 1.6.1.0
Design por Laptop Geek, adaptado por onesoft e personalizado por mim.