LocationListener NETWORK_PROVIDER включен, но onLocationChanged никогда не вызывается
Я разрабатываю приложение, которое получает позицию сотового телефона весь день в течение 6 и 6 минут в службе, оно работает нормально, но иногда метод OnLocationChanged
слушателя сетевого провайдера перестает быть вызванным, и я Не знаю почему.
По какой-то причине перестает быть вызванным, но поставщик включен, и Lister работает, когда я разрешаю или отключаю Поставщика вручную, вызывается onProviderEnabled
и onProviderDisabled
.
Это просто происходит с NETWORK_PROVIDER
, GPS_PROVIDER
работает хорошо.
СЛУШАТЕЛЬ:
LocationListener locationListenerGPS = new LocationListener() {
// @Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO locationListenerGPS onStatusChanged
Log.d(TAG, "Provedor trocado");
}
// @Override
public void onProviderEnabled(String provider) {
Log.w(TAG, "PROVEDOR " + provider + " HABILITADO!");
}
// @Override
public void onProviderDisabled(String provider) {
Log.w(TAG, "PROVEDOR " + provider + " DESABILITADO!");
}
// @Override
public void onLocationChanged(Location location) {
longitudeGPS = location.getLongitude();
latitudeGPS = location.getLatitude();
Log.d(TAG,"LocationChangedGPS LAT: "+latitudeGPS+" longi: "+longitudeGPS);
gpsComSinal = true;
}
};
LocationListener locationListenerNET = new LocationListener() {
// @Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO locationListenerNET onStatusChanged
Log.d("Contele", "Provedor foi mudado");
}
// @Override
public void onProviderEnabled(String provider) {
Log.i(TAG, "PROVEDOR " + provider + " HABILITADO!");
}
// @Override
public void onProviderDisabled(String provider) {
Log.i(TAG, "PROVEDOR " + provider + " DESABILITADO!");
}
@Override
public void onLocationChanged(Location location) {
longitudeNET = location.getLongitude();
latitudeNET = location.getLatitude();
Log.d(TAG,"LocationChangedNET LAT: "+latitudeNET+" longi: "+longitudeNET);
netComSinal = true;
}
};
код:
public void initProviders() {
localizacao = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
localizacao.removeUpdates(locationListenerNET);
localizacao.removeUpdates(locationListenerGPS);
localizacao.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
locationListenerGPS);
localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0,
0, locationListenerNET);
Log.d(TAG,"EsperaGPS");
Handler esperaGPS = new Handler() {
public void handleMessage(Message msg) {
requestGPS();
}
};
Message msgEsperaGPS = Message.obtain();
msgEsperaGPS.what = 0;
esperaGPS.sendMessageDelayed(msgEsperaGPS, 35000);
}
public void requestGPS() {
if (gpsComSinal) {
Log.d(TAG,"PEGO SINAL DE GPS");
rastreio = "GPS";
longitude = longitudeGPS;
latitude = latitudeGPS;
Log.d(TAG, "Utilizando provedor GPS.");
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
} else {
Log.d(TAG,"Sem GPS... pegar NEt");
// Setando os valores para usar network
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
localizacao
.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0, 0, locationListenerNET);
Log.d(TAG,"EsperaNET");
requestNET();
}
}
public void requestNET() {
if (netComSinal) {
Log.d(TAG,"PEGO SINAL DE NET");
rastreio = "NET";
longitude = longitudeNET;
latitude = latitudeNET;
Log.d(TAG, "Utilizando provedor NET.");
localizacao.removeUpdates(locationListenerNET);
} else {
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
Log.d(TAG,"Sem sinal");
}
}
Отчет в Samsung Galaxy S3:
![enter image description here]()
По-прежнему получая "Sem-sinal" в течение 4 дней подряд.
Эта проблема уже произошла с Galaxy Y и LG Optimus l5
Я сделал еще один тест, чтобы узнать, получили ли другие приложения позиции NET, и я обнаружил, что они передаются по той же самой проблеме, они не могут получить позицию NET только для GetLastknowLocation; чтобы проверить, что я использовал Galaxy S3 с этой проблемой, и я отключил поставщик GPS. (Протестировано в Цербере).
Я не мог найти объяснения, почему слушатель NETWORKSLOCATIONS перестает давать позиции, но может быть, потому что он не должен работать в течение 2 или 3 дней без остановки.
Я проделал некоторые тесты с другими приложениями, чтобы проверить, не возникает ли эта проблема с моим назначением, и я обнаружил, что они передаются по одной и той же проблеме, например, в Cerberus:
Я отключу GPS-провайдера в мобильном телефоне (Galaxy S3) с проблемой "Sem-sinal", посмотрите:
Мой отчет:
![enter image description here]()
И Cerberus (печать, сделанная в 14/05/2013):
![enter image description here]()
Но когда я открыл Google Maps, кажется, что он работает нормально, я попытался переместиться на дистанционное место, чтобы увидеть, будет ли отображаться GetLastknowLocation
, но нет, карты google помещают меня в нужное место в данный момент, поэтому я понял, что Google Maps использовал motionevent для перемещения меня на карту;
И также распечатайте журнал Карт Google, чтобы получить NetWorkProvider:
Обычный случай:
![enter image description here]()
Семейный случай:
![enter image description here]()
Ответы
Ответ 1
У меня возникли аналогичные проблемы с Сетевым провайдером, и только решение было принудительно перезагрузить устройство.
Хотя карта google всегда показывала правильное местоположение, потому что она также использует информацию других датчиков, кроме поставщика сетевого местоположения.
Но вот хорошая новость, а не давно. Google представил FIP-провайдера api через сервисную службу Google Play, который очень прост в использовании, чем поставщики GPS/Network Location.
Совместимость до уровня API 8, теперь, когда я получаю эту странную проблему с сетевым провайдером, в то же время Fused Location дает мне точное местоположение (без перезагрузки устройства).
Я совершил один рабочий проект тестирования FusedLocation здесь, вы можете клонировать и тестировать себя.
Ниже приведен фрагмент кода: -
package com.example.fusedLoctionTest.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationRequest;
public class FusedLocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener{
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(0)
.setFastestInterval(0)
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
public static final String LOCATION_RECEIVED = "fused.location.received";
private Long now;
private LocationClient mLocationClient;
private final Object locking = new Object();
private Runnable onFusedLocationProviderTimeout;
private Handler handler = new Handler();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
now = Long.valueOf(System.currentTimeMillis());
mLocationClient = new LocationClient(this, this, this);
mLocationClient.connect();
return START_STICKY;
}
@Override
public void onConnected(Bundle bundle) {
Log.d("FusedLocationService", "Fused Location Provider got connected successfully");
mLocationClient.requestLocationUpdates(REQUEST,this);
onFusedLocationProviderTimeout = new Runnable() {
public void run() {
Log.d("FusedLocationService", "location Timeout");
Location lastbestStaleLocation=getLastBestStaleLocation();
sendLocationUsingBroadCast(lastbestStaleLocation);
if(lastbestStaleLocation!=null)
Log.d("FusedLocationService", "Last best location returned ["+lastbestStaleLocation.getLatitude()+","+lastbestStaleLocation.getLongitude()+"] in "+(Long.valueOf(System.currentTimeMillis())-now)+" ms");
if(mLocationClient.isConnected())
mLocationClient.disconnect();
}
};
handler.postDelayed(onFusedLocationProviderTimeout, 20000);//20 sec
}
private void sendLocationUsingBroadCast(Location location) {
Intent locationBroadcast = new Intent(FusedLocationService.LOCATION_RECEIVED);
locationBroadcast.putExtra("LOCATION", location);
locationBroadcast.putExtra("TIME", Long.valueOf(System.currentTimeMillis()-now) +" ms");
LocalBroadcastManager.getInstance(this).sendBroadcast(locationBroadcast);
stopSelf();
}
@Override
public void onDisconnected() {
Log.d("FusedLocationService","Fused Location Provider got disconnected successfully");
stopSelf();
}
@Override
public void onLocationChanged(Location location) {
synchronized (locking){
Log.d("FusedLocationService", "Location received successfully ["+location.getLatitude()+","+location.getLongitude()+"] in "+(Long.valueOf(System.currentTimeMillis()-now))+" ms");
handler.removeCallbacks(onFusedLocationProviderTimeout);
if(mLocationClient.isConnected())
mLocationClient.removeLocationUpdates(this);
sendLocationUsingBroadCast(location);
if(mLocationClient.isConnected())
mLocationClient.disconnect();
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("FusedLocationService", "Error connecting to Fused Location Provider");
}
public Location getLastBestStaleLocation() {
Location bestResult = null;
LocationManager locMgr = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Location lastFusedLocation=mLocationClient.getLastLocation();
Location gpsLocation = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
Location networkLocation = locMgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (gpsLocation != null && networkLocation != null) {
if (gpsLocation.getTime() > networkLocation.getTime())
bestResult = gpsLocation;
} else if (gpsLocation != null) {
bestResult = gpsLocation;
} else if (networkLocation != null) {
bestResult = networkLocation;
}
//take Fused Location in to consideration while checking for last stale location
if (bestResult != null && lastFusedLocation != null) {
if (bestResult.getTime() < lastFusedLocation.getTime())
bestResult = lastFusedLocation;
}
return bestResult;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
Ответ 2
У меня точно такая же проблема, и единственным решением для меня является перезагрузка устройства. Что интересно, что ни одно из приложений не содержит информацию о местоположении, кроме карт Google.
Приложение Google maps как-то находит свое местоположение!..
Постскриптум используя службу LocationListener в сервисе, поэтому это определенно не проблема плохой ссылки, мертвого объекта и т.д.
Ответ 3
У меня все еще есть эта проблема. Но я все еще ищу ответ, я попытался реализовать это в слушателе NETWORK_PROVIDER:
public void onStatusChanged(final String provider, final int status, final Bundle extras) {
switch( status ) {
case LocationProvider.AVAILABLE:
// ...
break;
case LocationProvider.OUT_OF_SERVICE:
// ...
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
// ...
break;
}
}
Потому что: OUT_OF_SERVICE, если поставщик не работает, и это вряд ли изменится в ближайшем будущем; TEMPORARILY_UNAVAILABLE, если поставщик временно недоступен, но ожидается, что он будет доступен в ближайшее время; и AVAILABLE, если поставщик в настоящее время доступен. onStatusChanged
И я думал, что OUT_OF_SERVICE - моя проблема, и пока нет решения, просто перезагрузив устройство, затем я попытался сделать несколько отчетов, когда это произойдет, и когда этот ocurre я попрошу пользователя перезагрузить устройство, но несколько устройств получают этот статус.
Ответ 4
Кажется, что проблема с сетевым провайдером была обнаружена в Android Open Source Project, Issue Tracker: https://code.google.com/p/android/issues/detail?id=57707.
Короче говоря, выпуск был опубликован 17 июля 2013 г. - последний блог 7 января 2015 г., выпущенный на Android 4.1.x, появляется в самых разных устройствах: "Не разрешено в последней библиотеке службы воспроизведения", никаких обходных решений, предложенных в блоге, не существует.
Ответ 5
Я понимаю кое-что в нашем вопросе; вы вызываете метод requestGPS, а затем dicover его location.If gps включен, получил через gps. Othervise gott через NET. Когда вы вызываете requestGPS и управляющий провайдер, чем получаете lat-lang, но удаляете обновления. (Не вызывайте, потому что вы удалили триггер обновлений);
if (gpsComSinal) {
Log.d(TAG,"PEGO SINAL DE GPS");
rastreio = "GPS";
longitude = longitudeGPS;
latitude = latitudeGPS;
Log.d(TAG, "Utilizando provedor GPS.");
// if you remove update don't call onLocationChanged
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
} else {
Log.d(TAG,"Sem GPS... pegar NEt");
// Setando os valores para usar network
localizacao.removeUpdates(locationListenerGPS);
localizacao.removeUpdates(locationListenerNET);
localizacao.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
0, 0, locationListenerNET);
Log.d(TAG,"EsperaNET");
requestNET();
}
Ответ 6
NETWORK_PROVIDER не обновляется, когда телефон GPS работает и получает сигнал. Если вы отключите GPS и заставите телефон получать свое местоположение из сети, вы снова начнете получать обновления.
Ответ 7
Я думаю, это потому, что ваше приложение "убито" в фоновом режиме. Я столкнулся с этой проблемой раньше, и я решил ее, переместив создание службы LocationListener в службу. Обязательно сохраните ссылку на слушателя. Это может решить проблему.