2016-10-06 3 views
1

사용자가 & 오프 위치 추적을 설정 할 수있는 응용 프로그램을 빌드하려면 내 목표중포 기지의 onComplete은 백그라운드 프로세스

에 호출되지 않습니다. 추적 기능이 켜지면 사용자의 위치 데이터를 Firebase에 전송하려고합니다.

나의 시도 솔루션

내가 PendingIntent 및 Google 백그라운드에서 위치를 추적하는 서비스 FusedLocationAPI 재생 사용합니다. 모든 위치 업데이트 (30 초 구두 점)에서 PendingIntent는 WakefulBroadcastReceiver에 인 텐트 (가능한 경우 위치 업데이트가 있음)를 발동합니다. WakefulBroadcastReceiver는 위치 데이터를 Firebase에 저장해야합니다. 여기

는 WakefulBroadcastReceiver의 모습입니다 : (! 일부 장치에) 일부 휴대 전화에

public class LocationProcessingReceiver extends WakefulBroadcastReceiver { 

    private static final String TAG = "LocationProcessingRcv"; 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (LocationResult.hasResult(intent)) { 
      Log.i(this.TAG, "Received location result"); 

      // Extract location from result and push to server 
      Location location = LocationResult.extractResult(intent).getLastLocation(); 
      this.pushLocationToServer(location, intent.getStringExtra("userId")); 
     } 
     else { 
      Log.i(TAG, "No location result"); 
     } 
    } 

    /** 
    * Pushes location to Firebase server 
    * @param location 
    */ 
    private void pushLocationToServer(Location location, String userId) { 

     FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(); 

     // Data to update the latest status of the user 
     Map<String, Object> statusMap = new HashMap<String, Object>(); 
     // ... various statusMap.put(...) calls go here 

     // Get reference to Firebase as well as key at which to update reference 
     DatabaseReference dbRef = FirebaseDatabase.getInstance().getReference(); 

     dbRef.child(DB_LOC_HISTORY_REFERENCE).push().updateChildren(historyMap, new DatabaseReference.CompletionListener() { 
      @Override 
      public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { 
       if (databaseError == null) { 
        Log.i(TAG, "Successfully pushed to server"); 
       } 
       else { 
        Log.i(TAG, "Server push failed: " + databaseError.toString()); 
       } 
      } 
     }); 
    } 
} 

문제

의의 onComplete 콜백이 호출되지 않습니다. 왜 이것이 작동하지 않는지도 모르겠다 ... 어떤 장치에서는 콜백이 예상대로 작동한다. 다른 사람들에게는 콜백이 수신되지 않으며 Firebase에서 업데이트 된 데이터를 보지 못합니다.

로그는 위치 업데이트가 정상적으로 작동하고 WakefulBroadcastReceiver의 onReceive() 메소드가 예상대로 주기적으로 호출됨을 보여줍니다.

나는 oncomplete가 호출 될 것으로 예상했지만, 연결 문제가있을 경우 오류를 표시합니다. 그러나 그것은 결코 일어나지 않으며, 나는 왜 이해해야하는지 고심하고 있습니다.

경고 : 이러한 장치 중 많은 장치가 3G에서 실행됩니다. 내 앱이 배경에있을 때 Firebase가 3G 연결이 너무 느리기 때문에 일을 끝내기 전에 BroadcastReceiver가 죽을 수 있습니까?

+0

해결 방법을 찾으셨습니까? – andygeers

답변

1

이 문제는 BroadcastReceiver의 수명주기와 관련이있을 수 있습니다.

브로드 캐스트 리시버 오브젝트가 onReceive 호출 기간 (문맥, 의도)에 대해서만 유효합니다 :

문서는 것을 설명한다. 이 함수에서 코드가 반환되면 시스템은 객체가 완료된 것으로 간주하고 더 이상 을 활성화하지 않습니다.

이것은 당신이 onReceive (문맥, 의도) 구현에 무엇을 할 수 있는지에 중요한 영향이있다 : 당신이 비동기를 처리하는 기능에서 반환해야하므로 비동기 작업을 필요로 아무것도, 사용할 수 없습니다 그러나 그 시점에서 에서 BroadcastReceiver가 더 이상 활성 상태가 아니므로 시스템은 비동기 작업 이 완료되기 전에 해당 프로세스를 죽일 수 있습니다..FirebaseDatabase 작업이 백그라운드 스레드에서 비동기 적으로 수행되기 때문에 DB 작업이 수행되기 전에

, 시스템은 어떤 경우에, 당신의 LocationProcessingReceiver 인스턴스를 파괴 할 것이다.

WakefulBroadcastReceiver을 사용하면 리시버 개체가 너무 일찍 소멸되는 것을 방지 할 수 있다고 생각할 수도 있지만 그렇지 않습니다. WakefulBroadcastReceiver은 여기서 수행하지 않는 서비스를 안전하게 시작하기위한 것입니다. 아무런 유익이 없습니다. 대신 BroadcastReceiver을 사용하십시오.

DB 조작이 완료되도록하려면 WakelockpushLocationToServer() (안전을 위해 시간 초과가 있음)으로 묻고 onComplete() 콜백에서 해제하십시오.

+0

정보 주셔서 감사합니다. Firebase가 작업을 완료 할 때까지 BroadcastReceiver를 활성 상태로 유지할 수있는 방법이 있습니까? 또는 일반적으로 * FirebaseDatabase 작업이 중단되지 않도록 보장하는 방법은 무엇입니까? –

+0

Wakelock을 사용할 제안을 추가하기 위해 원래 게시물을 편집했습니다. –

+0

감사합니다. 나는 그것을 줄 것이다. 그래도 조금 해킹 된 것 같아요. Firebase 연결이 항상 백그라운드에서 실행되고, BroadcastReceiver가 단순히이 참조에서 "pushToServer"를 호출하는 것이 더 낫습니다. 어떻게 구현할지 모르지만 개념적으로 무엇을 만드나요? –

관련 문제