sexta-feira, 18 de março de 2011

Usando as API's do Android para Pegar a Latitude e Longitude

        Para acessar o GPS nas API’s do Android precisamos utilizar duas classes :
                    LocationManager;
                    Location.
        Segue abaixo um exemplo de uso das classes:
LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
   double lat = location.getLatitude();
   double lon = location.getLongitude();
}
else 
    Toast.makeText(MainActivity.this, "Sem Latitude e longitude !", Toast.LENGTH_SHORT).show();

        A latitude e longitude retornada pelos métodos getLongitude() e getLatitude() estão em graus decimais, este objeto (location) tem varios métodos para trazer dados do GPS, como getSpeed() para trazer a velocidade.
        Insira no arquivo de configuração do seu aplicativo(AndroidManifest.xml) a autorização para acessar o GPS com a seguinte linha:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
</uses-permission>

Referências:
Documentação da classe Location
Documentação da classe LocationManager
Exemplo de uso dessas classes

9 comentários :

  1. Amigo, legal o post... mas me tira uma duvida:

    esse código aí ele pega somente a ultima posição reconhecida, porém, não atualiza a posição... estou certo? pra atualizar a posição antes de pegar tinha que dar um requestLocationUpdates, e depois o getLastKnownLocation? ou só com o getLastKnownLocation ele vai pegar a posição nova sozinho?

    ResponderExcluir
  2. Romulo,

    A função requestLocationUpdates serve como uma trigger, ou seja, você configura nesta função o tempo ou a distância que você quer que um evento seja disparado para você capturar a posição do dispositivo. A função getLastKnownLocation pega a posição atual do dispositivo.
    Se você precisa monitorar o dispositivo o tempo inteiro e precisa exibir informações na tela use o requestLocationUpdates e dentro do evento você pega as coordenadas, se você precisa apenas pegar as coordenadas quando algum evento acontecer (uma foto, um cadastro, etc ...) use o exemplo que eu coloquei.

    ResponderExcluir
  3. Legal, entendi!

    é que to fazendo um localizador de celular, mas para privar a bateria, to fazendo um alarm pra disparar somente em uma determinada quantidade de tempo, acordar o telefone, pegar a posição e enviar para um banco remoto (ou gravar local caso nao haja sinal), e depois liberar pra entrar em sleep de novo... daí seria interessante o seu exemplo por isso, pois se colocar no requestLocationUpdates, ele vai gravar varias posições, e na verdade eu preciso de uma só quando der o tempo...

    obrigado pela resposta!

    ResponderExcluir
  4. Wagner,

    Concluí meu projeto, e essa informação que você comentou, não funciona na pratica não... segundo os testes que fiz aqui, ele só pega a localização certa depois de dar um requestLocationUpdates.

    Eu fiz da seguinte maneira... chamo o requestlocationupdates, daí no evento OnLocationChanged eu dou um removeUpdates... então ele atualiza a posição, e logo em seguida pára de atualizar...

    feito isso então, eu dou o comando de getLastKnownLocation para pegar a ultima posição reconhecida pelo provider.

    se der o getLastKnownLocation direto sem dar o requestlocationupdates, ele não pega a posição correta, mas sim a ultima reconhecida, que pode ser longe de onde está atualmente.

    estou comentando só pra compartilhar o conhecimento, assim como você fez com esse ótimo post!

    um abraço!

    ResponderExcluir
    Respostas
    1. Esse exemplo ele pega a posição atual do GPS (LocationManager.GPS_PROVIDER)se o seu GPS não estiver atualizado você vai ter a ultima posição valida, quando você usa o requestLocationUpdates por default ele usa todos os recursos de localização e não somente o GPS.

      Excluir
    2. Então, mas quando vc chama o requestLocationUpdates você passa como parametro qual o provider que vc quer...

      se quiser só do GPS, vc passa assim:
      lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);

      se quiser a localização pela internet, passa assim:
      lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerGps);

      se quiser os dois, vc chama os dois, e depois existe uma função pra saber qual o melhor, mas nao me lembro o nome agora... é alguma coisa parecida com getBestProvider...

      e assim por diante...

      ou seja, para que a ultima posição válida seja a posição em que você se encontra no momento, você precisa dar um requestLocationUpdates antes, pois se não, provavelmente a localização poderá vir NULL caso nao haja nada, ou vir desatualizada...

      A melhor conclusão então é usar os dois combinados:
      o requestLocationUpdates pra atualizar a posição;
      no evento onLocationChanged dá um removeUpdates pra ele parar de atualizar;
      pega o ponto com o getLastKnownLocation e faz o que quer fazer.

      lembrando que to me baseando no meu projeto, e nos testes que fiz nele pra comentar isso...

      Abraço!

      Excluir
  5. Estou fazendo um projeto parecido, teria como me passar seu fonte?
    ddianno@gmail.com

    ResponderExcluir
  6. Vou postar um pequeno trecho que eu utilizo

    // Pega a latitude e a longitude
    LocationManager lm = LocationManager)getSystemService(Context.LOCATION_SERVICE);
    Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    if (location != null) {
    values.put(Dados.TblMultas.vl_Latitude, location.getLatitude());
    values.put(Dados.TblMultas.vl_Longitude, location.getLongitude());
    } else {
    values.put(Dados.TblMultas.vl_Latitude, 0);
    values.put(Dados.TblMultas.vl_Longitude, 0);
    }

    ResponderExcluir