我正在开发一个应用程序,在服务中的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");
}
}
三星Galaxy S3报道:
连续4天仍然获得“Sem sinal”。
Galaxy Y和LG Optimus l5已经发生过这个问题
我已经做了另一个测试,看看其他aplications是否获得了NET位置,我发现他们正在为同样的问题传递,他们无法获得NET位置只是GetLastknowLocation;为了测试我使用了Galaxy S3这个问题,我禁用了GPS提供商。 (在Cerberus测试过。)
我找不到任何有关NETWORKSLOCATIONS侦听器停止提供位置的解释,但可能是因为它不应该停止工作2到3天。
我已经用其他应用程序做了一些测试,看看这个问题是否恰好发生在我的应用程序中,并且我发现它们正在传递相同的问题,例如在Cerberus中:
我在带有“Sem sinal”问题的手机(Galaxy S3)中禁用了GPS提供商,请看一下:
我的报告:
Cerberus(2013年5月14日打印)报告:
但是当我打开谷歌地图时,似乎工作正常,我试图移动到一个距离的地方,看它是否会显示GetLastknowLocation
,但不,谷歌地图让我在正确的位置那一刻,我意识到谷歌地图正在使用动作来移动我在地图中;
并打印Google地图日志以获取NetWorkProvider:
正常情况:
Sem sinal case:
答案 0 :(得分:28)
我遇到与网络提供商类似的问题,只有解决方案是强制设备重启。 虽然谷歌地图始终显示正确的位置,因为它使用除网络位置提供商之外的其他传感器信息。
但这里有好消息,而不是很久以前谷歌通过其Google Play Service Framework引入了Fused Location Provider api,这比GPS /网络位置提供商更容易使用。
兼容API级别8,现在当我遇到网络提供商的这个奇怪问题时,同时Fused Location为我提供了准确的位置(无需重启设备)。
我已经提交了一个工作FusedLocation Test Project here,你可以自己克隆和测试..
以下是代码片段: -
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;
}
}
答案 1 :(得分:4)
我有完全相同的问题,对我来说唯一的解决方案是重启设备。有趣的是,除Google地图外,所有应用都没有位置信息。
谷歌地图应用程序以某种方式找到一个位置!..
附:在服务中使用LocationListener,所以它绝对不是错误引用,死对象等问题。
答案 2 :(得分:4)
我还有这个问题。但我仍然在寻找答案,我试图在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如果提供商暂时不可用但预计很快就会提供;如果提供商目前可用,则可以使用。 onStatusChanged
我认为OUT_OF_SERVICE是我的问题,到目前为止还没有解决方案,只是重新启动设备,然后我尝试在发生这种情况时做出一些报告,当我发出这个问题时,我要求用户重新设备设备,但是很少有设备能够恢复这种状态。
答案 3 :(得分:3)
似乎是一个开放的错误,Android开源项目报告的网络提供商问题,问题跟踪器:https://code.google.com/p/android/issues/detail?id=57707。 简而言之:2013年7月17日发布的问题 - 最后一篇博客2015年1月7日,问题出现在Android 4.1.x中,出现在各种各样的设备中,&#34;未解决最新的Play服务库&#34;,没有解决方法在博客中提出。
答案 4 :(得分:2)
我在问题中理解了一些事情;你调用requestGPS方法然后切换它的位置。如果启用gps,通过gps获取。其他通过NET获得gott。当调用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();
}
答案 5 :(得分:2)
NETWORK_PROVIDER不会更新。如果您关闭GPS并强制手机从网络获取其位置,那么您将再次开始获取更新。
答案 6 :(得分:1)
我认为这是因为你的应用程序在后台被“杀死”了。我之前遇到过这个问题,我通过在服务中移动LocationListener的创建来解决它。一定要保持对监听器的引用。它可能解决了这个问题。
答案 7 :(得分:0)
我遇到了这个问题,我发现当您禁用GPS时,网络提供商无法在某些android设备中工作,因为如果未启用GPS,它们会阻止访问位置数据。
我已经在很多设备上尝试过 1. lenove k6 note(screen shot1,screen shot2) 2.小麦mi 9t screen shot1 3. Google Pixel 1和Pixel 2
因此某些设备需要启用GPS才能从LocationManager.NETWORK_PROVIDER访问位置,并且如果不启用GPS就无法获取位置数据