问题描述
我正在开发一个应用程序,该应用程序可以在服务中的 6 分钟和 6 分钟内全天获取手机的位置,它工作正常,但有时网络提供商侦听器的方法 OnLocationChanged
停止存在打电话,我不知道为什么.
I am developing an application that gets position of the cell phone all day long in 6 and 6 minutes in a service, it works fine but sometimes the method OnLocationChanged
of the Network provider listener stop to being called, and I don't know why.
它由于某种原因停止被调用,但是提供程序已启用并且列表器正在工作,当我手动启用或禁用提供程序时,会调用 onProviderEnabled
和 onProviderDisabled
.
It for some reason stop being called, but the Provider is enable and the Lister is working, when I Enable or disable the Provider manually, onProviderEnabled
and onProviderDisabled
is called.
这只是发生在 NETWORK_PROVIDER
上,GPS_PROVIDER
运行良好.
It just happens with NETWORK_PROVIDER
, the GPS_PROVIDER
works well.
听众:
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 中的报告:
Report in a Samsung Galaxy S3:
仍然连续 4 天收到Sem sinal".
Still getting "Sem sinal" for 4 days in a row.
Galaxy Y 和 LG Optimus l5 已经出现此问题
This issue have already happened with Galaxy Y and LG Optimus l5
我进行了另一项测试,看看其他应用程序是否获得了 NET 位置,我发现它们通过了同样的问题,它们无法仅通过 GetLastknowLocation 获得 NET 位置;测试我使用 Galaxy S3 解决了这个问题,并禁用了 GPS Provider.(在 Cerberus 中测试).
I have made another test to see if other aplications got the NET positions, and I discovered that they are passing for the same problem, they can't get the NET position just the GetLastknowLocation; to test that I used a Galaxy S3 with this problem, and I disabled the GPS Provider. (Tested in Cerberus).
我找不到任何解释为什么 NETWORKSLOCATIONS 听众停止给出位置,但这可能是因为它不应该连续工作 2 或 3 天.
I couldn't find any explanation for why NETWORKSLOCATIONS listener stop giving positions, but it might be because it shouldn't work for 2 or 3 days without stop.
我已经对其他应用程序进行了一些测试,看看这个问题是否只是在我的应用程序中发生,我发现它们正在通过同样的问题,例如在 Cerberus 中:
I have done some tests with other aplications to see if this issue is just happening with my aplication, and I discovered that they are passing for same problem, like in Cerberus for example :
我在手机 (Galaxy S3) 中禁用 GPS 提供程序,出现Sem sinal"问题,看看:
I disable the GPS Provider in a cellphone (Galaxy S3) with the "Sem sinal" problem, take a look:
我的报告:
和 Cerberus(打印于 2013 年 5 月 14 日)报告:
And Cerberus(print taken in 14/05/2013) report:
但是当我打开谷歌地图时,它似乎工作正常,我试图移动到一个较远的地方,看看它是否会显示 GetLastknowLocation
,但是没有,谷歌地图把我放在正确的地方,所以我意识到谷歌地图正在使用motionevent在地图中移动我;
But When I opened the Google Maps it seems to work OK, I tried to move to a distance place to see if it going to show the GetLastknowLocation
, but no, google maps put me in the right place in the moment, so I realized that Google Maps was using motionevent to move me in the map;
同时打印 Google Maps 的 Log 以获取 NetWorkProvider:
And also print the Log of Google Maps to get NetWorkProvider:
正常情况:
句号:
推荐答案
我在 Network provider 遇到过类似的问题,唯一的解决方案是强制设备重启.尽管谷歌地图总是显示正确的位置,因为它使用了除了网络位置提供者之外的其他传感器信息.
i have experienced similar issues with Network provider and only solution was force device restart. Though google map was showing always correct location, because it uses other sensors information also apart from Network location provider.
但这是好消息,不是很久以前 Google 通过其 Google Play 服务框架,比 GPS/网络位置提供商超级好用.
But here is good news, not Long time back Google introduced Fused Location Provider api's via its Google Play Service Framework which is super easy to use than GPS / Network Location providers.
兼容 API 级别 8,现在当我遇到网络提供商这个奇怪的问题时,同时融合位置给了我准确的位置(无需重启设备).
Compatible upto API Level 8, now when i get this weird issue of Network provider, same time Fused Location gives me accurate location(without device restart).
我已经提交了一个工作FusedLocation 测试项目在这里,你可以自己克隆和测试..
I have commited one working FusedLocation Test Project here, you can clone and test yourself..
下面是代码片段:-
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;
}
}
这篇关于NETWORK_PROVIDER 的 LocationListener 已启用,但永远不会调用 onLocationChanged的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!