2016-09-15 122 views
0

我需要每1分钟更新一次融合位置和每个5米位移(我知道它的不好的做法,但为了测试和在日志中显示),我开始按钮按钮服务尽快按钮按下我在logcat中的位置,但只有一次。根据服务等级onLocationChanged应该每隔1分钟调用一次,但它永远不会再打电话,即使我的GPS几乎每分钟打开一次,然后在关闭之后关闭,但Logcat中仍然没有位置更新。我需要服务类保留而不会影响用户界面或主线程Android服务没有更新位置

这里更新位置是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(); 
     } 
    } 


} 
+0

尝试不使用setsmallestdplacementment,看看会发生什么 –

+0

它显示调用'onLocationUpdate'没有'setsmallestdisplacement'但我如何使用常规更新与setsmallestdisplacement。感谢您的帮助 – androidXP

回答

0

。假定你其实移动设备预计更新之间超过5米,我觉得可能是与LocationRequest类,其中setSmallestDisplacement()方法只是无法正常工作的问题..或者至少它不能按预期工作。 (我在other posts上看到过这些问题)。

你总是可以通过删除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米。所以......也许你没有在清单中设置精确的访问权限?

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

+0

我在室内检查这就是为什么准确度高,我有良好的位置权限,这就是为什么GPS打开,粗略的位置无法访问GPS.If我设置我的位置更新为5米,这是不应该停止位置每1分钟更新一次。它像每1分钟或每5米更新位置。如果5米没有穿过,则必须每隔1分钟更新一次,但是当我使用“最小位移”并且如你所建议的计算距离在2点之间是不可能的 – androidXP

+0

在实际情况下,我必须设置间隔长达10分钟或15分钟,如果用户在这段时间内移动了几英里,那么我失去了他在这段时间之间旅行的位置,所以我需要坚持API方法发送位置之后x米 – androidXP

+0

不幸的是,我没有意识到这是你对setdisplacement方法如何工作的理解。根据我的理解,该方法意味着:如果用户自上一次被激发后至少走过了X米,则只会触发onLocationChanged方法。这并不意味着:每5米触发一次,因为这需要手机进行恒定的位置监测/计算,您试图通过创建间隔时间来节省电池电量。 –

2

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

由于setSmallestDisplacement()的绝对优先级高于其他参数,因此您没有在您的定时间隔获取任何位置更新。所以即使你有

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

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

解决方案是创建两个单独的LocationRequests ......一个只关注距离,另一个只关注时间,并使用单个GoogleApiClient创建2个requestLocationUpdates命令,一个使用Time LocationRequest,另一个使用Distance 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来处理每个请求的响应。 希望这有助于。