A LocationManager
API do Android parece um pouco trabalhosa para um aplicativo que precisa apenas de uma aproximação aproximada e ocasional da localização do usuário.
O aplicativo em que estou trabalhando não é realmente um aplicativo de localização em si, mas precisa obter a localização do usuário para exibir uma lista de empresas próximas. Não precisa se preocupar se o usuário está se movendo ou algo assim.
Aqui está o que eu gostaria de fazer:
- Mostre ao usuário uma lista de locais próximos.
- Pré-carregue a localização do usuário para que, quando eu precisar no
Activity
X, ele esteja disponível. - Não me importo particularmente com a precisão ou a frequência da atualização. Basta pegar um local é suficiente, desde que não esteja longe. Talvez se eu quiser ser elegante, atualizo o local a cada poucos minutos, mas não é uma prioridade enorme.
- Trabalhe para qualquer dispositivo, desde que tenha um provedor de GPS ou de local de rede.
Parece que não deve ser tão difícil, mas parece-me que preciso criar dois provedores de localização diferentes (GPS e REDE) e gerenciar o ciclo de vida de cada um. Não apenas isso, mas eu tenho que duplicar o mesmo código em várias atividades para satisfazer o número 2. Eu tentei usar getBestProvider()
no passado para reduzir a solução a apenas usar um provedor de localização, mas isso parece fornecer apenas o melhor provedor "teórico", em vez do provedor que realmente fornecerá os melhores resultados.
Existe uma maneira mais simples de conseguir isso?
Respostas:
Aqui está o que eu faço:
Aqui está como eu uso minha classe:
E aqui está a classe MyLocation:
Alguém também pode querer modificar minha lógica. Por exemplo, se você receber uma atualização do provedor de rede, não pare os ouvintes, mas continue esperando. O GPS fornece dados mais precisos, pelo que vale a pena esperar por eles. Se o temporizador terminar e você tiver atualizado da Rede, mas não do GPS, poderá usar o valor fornecido pela Rede.
Mais uma abordagem é usar o LocationClient http://developer.android.com/training/location/retrieve-current.html . Mas exige que o apk do Google Play Services esteja instalado no dispositivo do usuário.
fonte
Depois de procurar a melhor implementação, como obter a melhor localização precisa do usuário, consegui combinar todos os melhores métodos e criar a seguinte classe:
Esta classe tenta se conectar aos
min_gps_sat_count
satélites se o GPS estiver ativado. Caso contrário, retorna aLocationManager.getBestProvider()
localização. Verifique o código!fonte
import java.util.Iterator; import android.content.Context; import android.location.Criteria; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler;
Com a solução do Fedor, experimentei a execução múltipla do retorno de chamada
gotLocation
. Parece ser devido a uma condição de corrida noLocationListener.onLocationChanged
método substituído , quando o método gotLocation é 'longo o suficiente' . Não tenho certeza, mas acho queremoveUpdates
evita o enfileiramento de novas mensagens na fila Looper, mas não remove as que já estão na fila, mas ainda não foram consumidas. Daí a condição de corrida.Para reduzir a probabilidade desse comportamento errado, é possível chamar removeUpdates antes de disparar o evento onLocationChanged, mas ainda temos a condição de corrida.
A melhor solução que eu encontrei é substituir
requestLocationUpdates
comrequestSingleUpdate
.Esta é a minha versão, baseada na solução do Fedor, usando um manipulador para enviar uma mensagem para o thread do looper:
Eu uso essa classe de um thread de looper personalizado, como o seguinte:
where Coordinates é uma classe simples com duas propriedades: latitude e longitude.
fonte
Eu criei um pequeno aplicativo com descrição passo a passo para obter as coordenadas GPS dos locais atuais.
Exemplo de código-fonte completo no URL abaixo:
Veja como funciona :
Tudo o que precisamos fazer é adicionar essa permissão no arquivo de manifesto
e crie uma instância do LocationManager como esta
Verifique se o GPS está ativado ou não
implemente LocationListener e obtenha coordenadas
aqui está o código de exemplo para fazer
fonte
Você sempre pode usar LocationManager.getLastKnownLocation (), mas, como ele diz, pode estar desatualizado.
E uma maneira simples de obter uma localização geral pode ser o registro na rede (geralmente muito rápido).
e depois fazendo
no
onLocationChanged()
método do ouvinte.fonte
Escrevi um tutorial detalhado sobre a localização atual aqui em demonuts.com . Você pode encontrar mais descrições aqui e também pode baixar o código-fonte completo da demo para entender melhor.
Já existem muitas respostas, mas quero mostrar a maneira mais recente de obter localização usando a API do Google, para que novos programadores possam usar o novo método:
Primeiro, coloque isso no arquivo gradle
depois implemente as interfaces necessárias
declarar instâncias
coloque isso
onCreate()
Por fim, substitua os métodos necessários
Não se esqueça de iniciar o GPS no seu dispositivo antes de executar o aplicativo.
fonte
Atualmente, podemos usar os dois provedores (GPS e REDE). E eles simplesmente compartilham um ouvinte público:
Isso é necessário porque o
OnLocationChanged()
método sempre precisa ser chamado a tempo.fonte
Não sei se os serviços baseados em localização podem obter a localização de outras infraestruturas que não o GPS, mas, de acordo com esse artigo, parece possível:
fonte
Use o código abaixo, ele fornecerá o melhor provedor disponível:
fonte
A maneira recomendada de fazer isso é usar
LocationClient
:Primeiro, defina os valores do intervalo de atualização do local. Ajuste isso para suas necessidades.
Ter o seu
Activity
implementarGooglePlayServicesClient.ConnectionCallbacks
,GooglePlayServicesClient.OnConnectionFailedListener
eLocationListener
.Em seguida, configure a
LocationClient
noonCreate()
método do seuActivity
:Adicione os métodos necessários ao seu
Activity
;onConnected()
é o método que é chamado quando oLocationClient
conecta.onLocationChanged()
é onde você recuperará o local mais atualizado.Certifique-se de conectar / desconectar o dispositivo,
LocationClient
para que ele use apenas bateria extra quando for absolutamente necessário e para que o GPS não funcione indefinidamente. OLocationClient
deve estar conectado para obter dados dele.Obter a localização do usuário. Primeiro tente usar o
LocationClient
; se isso falhar, volte para oLocationManager
.fonte
Mesmo que a resposta já seja dada aqui. Eu só queria compartilhar isso com o mundo, caso encontrasse esse cenário.
Minha exigência era que eu precisasse obter a localização atual de um usuário dentro de 30 a 35 segundos no máximo, e aqui está a solução que eu fiz seguindo a Resposta de Nirav Ranpara .
1. Eu criei a classe MyLocationManager.java que lida com todo o material de GPS e de rede
2. Fiz um Interface (retorno de chamada) OnLocationDetectectionListener.java para comunicar os resultados de volta ao fragmento ou atividade de chamada
3. Então eu criei uma atividade MainAppActivty.java que implementa a
OnLocationDetectectionListener
interface e aqui está como eu recebo minha localização nela4. Adicione as seguintes permissões ao seu arquivo de manifesto
Espero que isso seja útil para os outros :)
fonte
Nos últimos mais de um ano, eu estava usando a combinação de GPS_PROVIDER e NETWORK_PROVIDER para obter a localização atual e estava funcionando bem, mas nos últimos meses estou obtendo localização após um longo atraso, então mudei para a API mais recente FusedLocationProviderClient e está funcionando muito bem.
Aqui está a classe que escrevi para obter a localização atual usando FusedLocationProviderClient. No código abaixo, usei um temporizador para aguardar um tempo para obter a localização atual, agendei o temporizador com 15 segundos de atraso, você pode alterá-lo de acordo com você.
E chamou isso de atividade, aqui está o código
Adicione as seguintes entradas no AndroidManifest.xml
fonte
fonte
Este é o código que fornece a localização atual do usuário
crie o Google Maps Activty:
main.xml:
e defina a seguinte permissão no manifesto:
fonte
É assim que estou solicitando permissões de usuário.
Fora da tag do aplicativo no AndroidManifest.xml, adicione essas solicitações de permissão.
Em seguida, adicione as dependências de localização do Google no arquivo App Gradle.
Agora declare algumas variáveis globais.
No método OnCreate da sua atividade (não foi possível formatar o código corretamente, desculpe-me por isso)
Agora crie as duas funções.
Segundo método
Para Constant.kt
fonte
Melhorias na solução da @ Fedor. Em vez de solicitar o local com intervalo de tempo '0' e distância '0', podemos usar o método requestSingleUpdate do gerente de localizações . Código atualizado (versão kotlin)
Para obter a localização, basta chamar o método getLocation como -
Nota: Antes de chamar o método getLocation, a permissão de localização necessária deve ser concedida.
fonte
Para obter e mostrar a localização atual do usuário, você também pode usar
MyLocationOverlay
. Suponha que você tenha ummapView
campo em sua atividade. Tudo o que você precisa fazer para mostrar a localização do usuário é o seguinte:Isso obtém a localização atual do GPS ou da rede. Se ambos falharem,
enableMyLocation()
retornaráfalse
.Quanto à localização das coisas ao redor da área, um
ItemizedOverlay
deve fazer o truque.Espero não ter entendido mal sua pergunta. Boa sorte.
fonte
EDIT: atualizado com a API do serviço de localização mais recente da biblioteca do Google Play Services (julho de 2014)
Eu recomendo que você use a nova API do serviço de localização , disponível na biblioteca do Google Play Services, que fornece uma estrutura de alto nível mais poderosa que automatiza tarefas como a escolha do provedor de localização e o gerenciamento de energia. De acordo com a documentação oficial: "... A API de localização facilita a criação de aplicativos com reconhecimento de localização, sem a necessidade de focar nos detalhes da tecnologia de localização subjacente. Eles também permitem minimizar o consumo de energia usando todos os recursos do hardware do dispositivo ".
Para mais informações, visite: Tornando seu aplicativo consciente da localização
Para ver um exemplo completo usando a última API da API do Serviço de Localização, a classe Android LocationClient foi descontinuada, mas usada na documentação
fonte
Maneira simples e melhor para localização geográfica.
fonte
Um pouco tarde aqui, mas o que eu faria em tal situação é usar a API do Google Maps e marcar os locais próximos usando a API lat e long do Google Maps. Além disso, a experiência do usuário é melhor se você puder mostrar sua localização em um mapa. Não há necessidade de se preocupar com a atualização da localização do usuário ou com a API do Android. Deixe o google maps lidar com os internos para você.
O @emmby pode ter resolvido o problema em seu aplicativo, mas para referência futura, consulte a API do Google Maps para obter informações específicas sobre o local.
Edit: Link para exibir a localização do usuário no google maps
fonte
Requer muitas coisas para obter atualizações de localização no Android, requer muito código de bolierplate.
Você precisa cuidar de
Eu criei o Android-EasyLocation (pequena biblioteca Android) que cuidará de tudo isso e você poderá se concentrar na lógica de negócios.
Tudo que você precisa é estender o EasyLocationActivity e isso
ou
Aplicativo de exemplo do Google Checkout e etapas necessárias aqui em https://github.com/akhgupta/Android-EasyLocation
fonte
Aqui está o que eu faço:
mFinalLocation
).onDestroy()
método de serviço, para de aguardar atualizações de local para cada provedor.Abaixo está o código de serviço. Você pode executá-lo com base na frequência da atualização do local necessária.
fonte
Versão Kotlin da resposta de @Fedor Greate :
uso da classe:
MyLocation
Classe :fonte
Na classe de atividade, cria um método personalizado:
Crie um nome de classe UserDefined LocationGetter: -
fonte
Usando FusedLocationProviderApi, que é a API mais recente e a melhor entre as possibilidades disponíveis para obter localização no Android. adicione isso no arquivo build.gradle
você pode obter o código fonte completo por este URL http://javapapers.com/android/android-location-fused-provider/
fonte
Recentemente refatorado para obter a localização do código, aprender algumas boas idéias e finalmente obter uma biblioteca e uma demonstração relativamente perfeitas.
Código completo: https://github.com/bingerz/FastLocation/blob/master/fastlocationlib/src/main/java/cn/bingerz/fastlocation/FastLocation.java
* A cada solicitação para concluir a localização, é melhor remover Atualizações, caso contrário, a barra de status do telefone sempre exibirá o ícone de posicionamento.
fonte
Depois de ver todas as respostas e perguntas (mais simples e robustas ). Eu fui clicado apenas na biblioteca Android-ReactiveLocation .
Quando criei um aplicativo de rastreamento de localização. Então eu percebi que é muito típico lidar com o rastreamento de localização otimizado com bateria.
Então, eu quero dizer aos novatos e também aos desenvolvedores que não querem manter seu código de localização com otimizações futuras. Use esta biblioteca.
Dependências a serem inseridas no nível do aplicativo build.gradle
Prós para usar esta lib:
fonte