2017-03-09 8 views
-1

특정 기간 동안 위치 업데이트를 수집하고 끝에 위치를 지정합니다. 나는 현재 방법 onLocationChanged에 전달 된 시간을 추적합니다.나중에 onLocationChanged 외부에서 처리하기 위해 위치 업데이트를 수집하는 방법

public class LocationProvider implements 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     LocationListener { 
    private static final String TAG = LocationProvider.class.getSimpleName(); 

    private Context mContext; 

    private GoogleApiClient mGoogleApiClient; 
    private LocationRequest mLocationRequest; 

    private long mStartTime; 
    private long mDuration; 

    List<Location> locations; 

    public LocationProvider(Context context) { 
     mContext = context; 

     GoogleApiAvailability api = GoogleApiAvailability.getInstance(); 
     if (api.isGooglePlayServicesAvailable(mContext) == ConnectionResult.SUCCESS) { 
      mGoogleApiClient = new GoogleApiClient.Builder(mContext) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } else { 
      Log.e(TAG, "Could not connect to Google Play services"); 
     } 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     LocationServices.FusedLocationApi.requestLocationUpdates(
       mGoogleApiClient, mLocationRequest, this); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.e(TAG, "onConnectionFailed: " + connectionResult.toString()); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.e(TAG, "GoogleApiClient connection has been suspended: " + String.valueOf(i)); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     locations.add(location); 

     if (System.currentTimeMillis() - mStartTime > mDuration) { 
      stopTracking(); 
      // do stuff 
     } 
    } 

    public void startTracking(long interval, long fastInterval, long duration) { 
     mDuration = duration; 
     locations = new ArrayList<>(); 

     mLocationRequest = LocationRequest.create() 
       .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) 
       .setInterval(interval) 
       .setFastestInterval(fastInterval); 

     if (!mGoogleApiClient.isConnected() || !mGoogleApiClient.isConnecting()) { 
      mGoogleApiClient.connect(); 
     } 

     mStartTime = System.currentTimeMillis(); 
    } 

    private void stopTracking() { 
     if (mGoogleApiClient.isConnected()) { 
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
      mGoogleApiClient.disconnect(); 
     } 
    } 
} 

그러나이 논리를 이혼하고 싶습니다. 내 필요에 따라 위치를 달리하고 싶기 때문에. 내 위치 수신기를 등록하기 위해 새 스레드를 만든 경우 위치 수집이 완료되어 locations 목록을 사용할 때까지 주 스레드에서 대기 할 수 있다고 생각했습니다.

  • 에 대해 호출하지만 긴
  • onLocationChanged
  • gatherUpdates 수익률에 도달 mLocationProvider.startTracking(interval, fastInterval, duration); 라인 :

    public class LocationUpdates { 
        private LocationProvider mLocationProvider; 
        private Looper mLooper; 
    
        public List<Location> gatherUpdates(final Context context, 
                 final long interval, 
                 final long fastInterval, 
                 final long duration) 
          throws InterruptedException { 
    
         long startTime = System.currentTimeMillis(); 
    
         new Thread() { 
          @Override 
          public void run() { 
           Looper.prepare(); 
           mLooper = Looper.myLooper(); 
           mLocationProvider = new LocationProvider(context); 
           mLocationProvider.startTracking(interval, fastInterval, duration); 
           Looper.loop(); 
          } 
         }.start(); 
    
         while (System.currentTimeMillis() - startTime < duration) { 
    
         } 
    
         mLooper.quit(); 
         mLooper.getThread().join(); 
    
         return mLocationProvider.locations; 
        } 
    } 
    

    대신, 내가 무엇을 관찰하는 것은 (간격 삼초, 기간 십초)이었다 처음 만 지금

그래서 전자 위치 청취자가 등록되었지만, 무언가가 명확하게 업데이트 수신을 차단합니다. 왜 내 논리가 내가 기대하는 바를하지 않는지 알 수 없다.

스레드가 없어도 많은 수의 위치 업데이트를 수집하고 컬렉션 완료 후 onLocationChanged 외부에서 작업하는 방법이 있습니까?

+0

, 나는 잠재적으로 해결 할 수있다. 이 질문에 대한 대답은 나에게 여전히 중요합니다. – Reti43

답변

0

Intent에서 BroadcastReceiver까지 위치 업데이트 요청을 작성할 수 있습니다. 그런 다음 위치 개체의 시간이 사용자의 기간을 초과하면 업데이트를 제거하십시오. 방송 수신기에서

int requestCode = 1; 
Intent intent = new Intent(this, LocationReceiver.class); // Request updates to Receiver 
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_CANCEL_CURRENT); 
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, pendingIntent); 

다음 downvoter 친절이 질문에 부족한 것을 지적 할 수 있다면

@Override 
public void onReceive(Context context, Intent intent) { 

    if(LocationResult.hasResult(intent)){ 
     LocationResult locResult = LocationResult.extractResult(intent); 
     Location location = locResult.getLocations().get(0); 
     // Check the location's time and maybe stop location updates 
    } 
} 
+0

이것이 나를 도와주지 않는 것 같습니다. 당신이 보여주는 것은 내 Location Update를 BroadcastReceiver에 전달하는 방법이며, LocationListener로 이미 할 수 있습니다. 내 문제는 물건을하는 방법을 가지고 특정 시간 동안 특정 위치 데이터를 가져와야하고 일단 완료되면 결과를 검색하고 사업을 계속 수행해야한다는 것입니다. 문제는 업데이트를 차단하지 않고 해당 메서드를 대기 상태로 만드는 방법입니다. – Reti43

+0

@ Reti43 BroadcastReceiver는 IntentServices는 물론 포 그라운드에 앱이 없어도 위치 인 텐트를 처리 할 수 ​​있기 때문에 BroadcastReceiver를 제안했습니다. 내가 말하고자하는 바는 프로세스가 끝난 곳마다 업데이트를 요청하고, 데이터베이스에 위치의 값을 저장하고, 각 업데이트의 시간을 확인하여 조건에 맞는지 확인하고, 그렇지 않은 경우 중지 할 수 있다는 것입니다 원하는 경우 데이터를 저장하고 업데이트를 제거하고 저장된 데이터를 처리 할 수 ​​있습니다. 나는 wait라고 부름으로써 그것에 접근하지 않을 것이다. 하나의 작업은 사전 처리를 수행하고 다른 작업은 사후 처리를 수행합니다. –