Android服务不更新位置

我需要每1分钟和每5米位移更新融合位置(我知道它的不良做法,但为了测试和显示在日志中)我开始服务按钮按下按钮按下我在logcat中获得位置但是只有一次。 根据服务类onLocationChanged应该每隔1分钟调用一次,但它几乎不会再次调用,即使我的GPS几乎每分钟都开启,然后在关闭之后关闭,但Logcat中仍然没有位置更新。我需要服务类来保持更新位置而不影响UI或主线程

这是logcat,它只显示一次位置更新

09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service onConnected Calling 09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Start Location Update is Calling 09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service OnLocationChanged Calling 09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Here is Updated Locations: Latitude 28.5XXXXX Longitude 77.2XXXXX 09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Sending Location Starting Accuracy is: 37.5 

这是我的服务类

 public class Location_Service_background extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { public static final String TAG = "===Location Service==="; GoogleApiClient apiClient; Location mCurrentLocation; LocationRequest locationRequest; @Override public int onStartCommand(Intent intent, int flags, int startId) { GoogleApiSetup(); RequestLocationUpdates(); Log.d(TAG,"OnStartCommand Is Calling "); return START_STICKY; } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); if (apiClient.isConnected()){ Log.d(TAG,"Service On Destroy Calling and apiClient is Connected"); StopLocationUpdates(); apiClient.disconnect(); } } @Override public void onLowMemory() { super.onLowMemory(); } @Override public void onConnected(@Nullable Bundle bundle) { Log.d(TAG,"Service onConnected Calling"); if (mCurrentLocation != null) { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient); } else { Log.d(TAG,"Start Location Update is Calling"); StartLocationUpdate(); } } @Override public void onConnectionSuspended(int i) { Log.d(TAG,"Service OnConnectionSuspended Calling"); apiClient.connect(); } @Override public void onLocationChanged(Location location) { Log.d(TAG,"Service OnLocationChanged Calling"); mCurrentLocation=location; Log.d(TAG,"Here is Updated Locations: Latitude "+mCurrentLocation.getLatitude()+"Longitude "+mCurrentLocation.getLongitude()); String Latitude= String.valueOf(mCurrentLocation.getLatitude()); String Longitude=String.valueOf(mCurrentLocation.getLongitude()); String Accuracy=String.valueOf(mCurrentLocation.getAccuracy()); Log.d(TAG,"Sending Location Starting"+" "+" Accuracy is: "+mCurrentLocation.getAccuracy()); } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { Log.d(TAG,"Connection Failed Called "+connectionResult); } private synchronized void GoogleApiSetup() { apiClient = new GoogleApiClient.Builder(this) .addApi(LocationServices.API) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .build(); apiClient.connect(); } private void RequestLocationUpdates() { locationRequest = new LocationRequest(); //1 Min = 60 seconds AND 1000 milliseconds in 1 second locationRequest.setInterval(60 * 1000);//5 Min 300 x 1000=300000 locationRequest.setFastestInterval(60 * 1000);//2 Min locationRequest.setSmallestDisplacement(5); locationRequest.setMaxWaitTime(60*1000); locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); } private void StopLocationUpdates() { LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this); } private void StartLocationUpdate() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return; } if (apiClient.isConnected()) { LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this); } else { Log.d(TAG,"GoogleApiClient is not connected yet.Please Try Again"); apiClient.connect(); } } } 

希望这有助于拯救某人在这个问题上遇到的挫败感。 我正在使用FusedLocationAPI来请求位置更新和GoogleApiClient。 我也从服务中做到这一点。

您没有在定时间隔获得任何位置更新,因为setSmallestDisplacement()优先于其他参数。 所以,即使你有

 locationRequestTimeInterval = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval(1) .setFastestInterval(1) .setMaxWaitTime(1) .setSmallestDisplacement(5); 

这将永远不会被触发,直到满足smallestDisplacement参数。

对此的解决方案是创建两个单独的LocationRequests …一个仅关注距离,一个仅关注时间,并使用您的单个GoogleApiClient创建2个requestLocationUpdates命令,一个使用Time LocationRequest,以及其他使用距离LocationRequest。

所以你的2个LocationRequests看起来像这样:

 locationRequestDistanceInterval = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setFastestInterval(0) // This MUST be set, otherwise no updates .setSmallestDisplacement(LOCATION_REQUEST_MIN_DISTNACE); locationRequestTimeInterval = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) .setInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL) .setFastestInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL); 
  • 请注意,必须在距离请求上设置setFastestInterval()值,否则不会触发距离请求。 它不必是0,但必须设置此字段。

然后在您的GoogleApiClients onConnected()中,您可以添加两个requestLocationUpdates()调用。

 LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, locationRequestDistanceInterval, new LocationListener() { @Override public void onLocationChanged(Location location) { // Handle your Distance based updates }); LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, locationRequestTimeInterval, new LocationListener() { @Override public void onLocationChanged(Location location) { // Handle your Time based updates } }); 

您可以使用相同或单独的LocationListeners来处理每个请求的响应。 希望这可以帮助。

假设您实际上将设备移动到预期更新之间超过5米 ,我认为LocationRequest类可能存在问题,其中setSmallestDisplacement()方法无法正常工作…或者至少它没有按预期工作。 (我在其他post上看到了这些问题)。

您可以通过删除setSmallestDisplacement()来自行检查距离,而是执行以下操作:

 onLocationChanged(){ double distance = // [ calculate distance between current lat/long and previous lat/long ] if (distance > 5 meters) { // do your normal onLocationChanged() code here } } 

还有可能由于某种原因,FusedLocationProvider无法访问您的GPS而是使用wifi或手机信号塔……在这种情况下,5米距离太小而无法指定。 你的日志说准确度是37.5米,所以看起来不够准确,无法测量5米。 那么……也许你的清单中没有设置FINE访问权限?

也可能是运行时权限未正确完成的问题? 您可以暂时将目标SDK设置为22以进行检查。