2016-09-15 118 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來處理每個請求的響應。 希望這有助於。