Como desenvolvedor do SpeedView: velocímetro GPS para Android, devo ter tentado todas as soluções possíveis para esse problema, todas com o mesmo resultado negativo. Vamos reiterar o que não funciona:
- onStatusChanged () não está sendo chamado no Eclair e no Froyo.
- Simplesmente contar todos os satélites disponíveis é, obviamente, inútil.
- Verificar se algum dos satélites retorna verdadeiro para usedInFix () também não é muito útil. O sistema claramente perde a correção, mas continua relatando que ainda há vários sats usados nele.
Portanto, aqui está a única solução funcional que encontrei e aquela que realmente uso em meu aplicativo. Digamos que temos esta classe simples que implementa o GpsStatus.Listener:
private class MyGPSListener implements GpsStatus.Listener {
public void onGpsStatusChanged(int event) {
switch (event) {
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
if (mLastLocation != null)
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
if (isGPSFix) { // A fix has been acquired.
// Do something.
} else { // The fix has been lost.
// Do something.
}
break;
case GpsStatus.GPS_EVENT_FIRST_FIX:
// Do something.
isGPSFix = true;
break;
}
}
}
OK, agora em onLocationChanged () adicionamos o seguinte:
@Override
public void onLocationChanged(Location location) {
if (location == null) return;
mLastLocationMillis = SystemClock.elapsedRealtime();
// Do something.
mLastLocation = location;
}
E é isso. Basicamente, esta é a linha que faz tudo:
isGPSFix = (SystemClock.elapsedRealtime() - mLastLocationMillis) < 3000;
Você pode ajustar o valor em milis, é claro, mas sugiro defini-lo em torno de 3-5 segundos.
Isso realmente funciona e, embora eu não tenha olhado para o código-fonte que desenha o ícone do GPS nativo, ele está perto de replicar seu comportamento. Espero que isso ajude alguém.
mLastLocationMillis
foi definido por uma fonte diferente do GPS? O sistema então alegaria que issoisGPSFix
é verdade, mas na realidade é qualquer conserto (talvez um da rede telefônica)O ícone do GPS parece mudar de estado de acordo com as intenções de transmissão recebidas. Você mesmo pode alterar seu estado com os seguintes exemplos de código:
Notifique que o GPS foi ativado:
Notifique que o GPS está recebendo correções:
Notifique que o GPS não está mais recebendo correções:
Notifique que o GPS foi desativado:
Código de exemplo para registrar o receptor nas intents:
Ao receber essas intenções de transmissão, você pode notar as mudanças no status do GPS. No entanto, você será notificado apenas quando o estado mudar. Portanto, não é possível determinar o estado atual usando essas intents.
fonte
novo membro, então infelizmente não posso comentar ou votar, no entanto, a postagem de Stephen Daye acima foi a solução perfeita para exatamente o mesmo problema para o qual estou procurando ajuda.
uma pequena alteração na seguinte linha:
para:
Basicamente, como estou construindo um jogo de ritmo lento e meu intervalo de atualização já está definido para 5 segundos, uma vez que o sinal gps sai por mais de 10 segundos, esse é o momento certo para acionar algo.
saúde amigo, passei cerca de 10 horas tentando resolver essa solução antes de encontrar sua postagem :)
fonte
Ok, então vamos tentar uma combinação de todas as respostas e atualizações até agora e fazer algo assim:
ACCESS_FINE_LOCATION
permissão ao seu manifestoLocationManager
GpsStatus.Listener
que reaja aGPS_EVENT_SATELLITE_STATUS
LocationManager
comaddGpsStatusListener
O ouvinte de GPS pode ser algo assim:
As APIs não são claras sobre quando e quais informações de GPS e satélite são fornecidas, mas acho que uma ideia seria olhar quantos satélites estão disponíveis. Se estiver abaixo de três, você não pode ter uma correção. Se for mais, então você deve ter uma correção.
Tentativa e erro é provavelmente o caminho a percorrer para determinar a frequência com que o Android relata informações de satélite e quais informações cada
GpsSatellite
objeto contém.fonte
GpsSatellite
objeto.LocationManager.requestLocationUpdates
com as configurações de tempo e distância definidas para 0? Isso deve enviar a você pontos de GPS assim que eles acontecerem. Se você não está recebendo nada, provavelmente não tem uma solução. Você pode combinar isso com o listener de status acima, se desejar.Depois de alguns anos trabalhando com GPS no windows mobile, percebi que o conceito de "perder" um ponto de GPS pode ser subjetivo. Para simplesmente ouvir o que o GPS lhe diz, adicionar um NMEAListener e analisar a sentença dirá se a correção foi "válida" ou não. Consulte http://www.gpsinformation.org/dale/nmea.htm#GGA . Infelizmente, com alguns GPSes, este valor irá flutuar para frente e para trás, mesmo durante o curso normal de operação em uma área de "boa posição".
Assim, a outra solução é comparar a hora UTC da localização GPS com a hora do telefone (convertida para UTC). Se estiverem com uma certa diferença de tempo, você pode presumir que perdeu a posição GPS.
fonte
entrar em um problema semelhante ao trabalhar em meu projeto de MSc, parece que a resposta de Daye relatou erroneamente "nenhuma correção" enquanto o dispositivo permanece em um local estático. Modifiquei um pouco a solução, o que parece funcionar bem para mim em um local estático. Não sei como isso afetaria a bateria, pois não é minha principal preocupação, mas aqui está como fiz isso, solicitando novamente as atualizações de localização quando uma correção expirou.
fonte
Bem, reunir todas as abordagens de trabalho resultará nisso (também lidando com obsoletos
GpsStatus.Listener
):Nota: esta resposta é uma combinação das respostas acima.
fonte
Se você só precisa saber se há uma correção, verifique a última localização conhecida fornecida pelo receptor GPS e verifique o valor .getTime () para saber quantos anos ele tem. Se for recente o suficiente (como ... alguns segundos), você tem uma correção.
... e, finalmente, compare com a data e hora atual (em UTC!). Se for recente o suficiente, você tem uma correção.
Eu faço isso no meu aplicativo e até agora tudo bem.
fonte
Você pode tentar usar LocationManager.addGpsStatusListener para se atualizar quando o status do GPS mudar. Parece que GPS_EVENT_STARTED e GPS_EVENT_STOPPED podem ser o que você está procurando.
fonte
GPS_EVENT_FIRST_FIX
parece um ajuste mais próximo.Posso estar errado, mas parece que as pessoas estão saindo do assunto por
Isso é facilmente feito com
Para ver se você tem uma solução sólida, as coisas ficam um pouco mais complicadas:
Agora sempre que quiser ver se tem conserto?
Se você quiser ser sofisticado, você sempre pode ter um tempo limite usando System.currentTimeMillis () e loc.getTime ()
Funciona de forma confiável, pelo menos em um N1 desde 2.1.
fonte
Com LocationManager, você pode getLastKnownLocation () depois de getBestProvider (). Isso fornece um objeto Location, que tem os métodos getAccuracy () em metros e getTime () em milissegundos UTC
Isso fornece informações suficientes?
Ou talvez você possa iterar nos LocationProviders e descobrir se cada um atende aos Critérios (ACCURACY_COARSE)
fonte
tantos posts ...
adicionar este código, com addGpsListener ... showMessageDialog ... apenas mostra uma janela de diálogo padrão com a string
fez o trabalho perfeitamente para mim :) muito obrigado: =) (sry para este post, ainda não posso votar)
fonte
Se você não precisa de uma atualização no mesmo instante em que a correção é perdida, você pode modificar a solução de Stephen Daye dessa forma, para que tenha um método que verifica se a correção ainda está presente.
Portanto, você pode apenas verificar sempre que precisar de alguns dados de GPS e não precisar desse GpsStatus.Listener.
As variáveis "globais" são:
Este é o método que é chamado em "onLocationChanged ()" para lembrar a hora de atualização e a localização atual. Além de atualizar "isGpsFix":
Esse método é chamado sempre que preciso saber se há um ponto de GPS:
Em minha implementação, primeiro executo checkGpsFix () e, se o resultado for verdadeiro, uso a variável "lastKnownLocation" como minha posição atual.
fonte
Eu sei que é um pouco tarde. No entanto, por que não usar o NMEAListener se você quiser saber se há uma correção. Pelo que li, o NMEAListener fornecerá as sentenças NMEA e, a partir daí, você escolherá a sentença correta.
A sentença RMC contém o status de correção que é A para OK ou V para aviso. A frase GGA contém a qualidade fixa (0 inválido, 1 GPS ou 2 DGPS)
Não posso oferecer nenhum código java porque estou apenas começando com o Android, mas fiz uma biblioteca GPS em C # para aplicativos do Windows, que pretendo usar com o Xamarin. Eu só encontrei este tópico porque estava procurando informações sobre o provedor.
Pelo que li até agora sobre o objeto Location, não estou muito confortável com métodos como getAccuracy () e hasAccuracy (). Estou acostumado a extrair das sentenças NMEA valores HDOP e VDOP para determinar o quão precisas são minhas correções. É bastante comum ter uma correção, mas ter um HDOP ruim, o que significa que sua precisão horizontal não é muito boa. Por exemplo, sentado em sua mesa depurando com um dispositivo GPS Bluetooth externo contra uma janela, é bem provável que você consiga uma correção, mas HDOP e VDOP muito ruins. Coloque seu dispositivo GPS em um vaso de flores externo ou algo semelhante ou adicione uma antena externa ao GPS e imediatamente você obterá bons valores de HDOP e VDOP.
fonte
Talvez seja a melhor possibilidade criar um TimerTask que defina o local recebido para um determinado valor (nulo?) Regularmente. Se um novo valor for recebido pelo GPSListener, ele atualizará a localização com os dados atuais.
Acho que seria uma solução de trabalho.
fonte
Você diz que já tentou onStatusChanged (), mas isso funciona para mim.
Este é o método que uso (deixo a própria classe lidar com onStatusChanged):
E eu lido com onStatusChanged da seguinte maneira:
Observe que os métodos onProvider {Dis, En} abled () são para habilitar e desabilitar o rastreamento GPS pelo usuário; não é o que você está procurando.
fonte
Definir o intervalo de tempo para verificar se há correção não é uma boa escolha .. percebi que onLocationChanged não é chamado se você não estiver se movendo .. o que é compreensível, já que a localização não está mudando :)
A melhor maneira seria, por exemplo:
fonte