2012-03-14 2 views
1

주기적으로 실행되고 (네트워크 제공 업체를 사용하여) 현재 위치를 기록한 다음 서버로 전송 한 다음 다시 잠자기 상태로 전환되는 서비스의 코드는 매우 간단합니다. .Android : GPS 수신기가 캐시 된 위치 데이터를 가져옴

정기적 인 월간 요금제가있는 SGS2와 선불 SIM 카드가있는 저렴한 ZTE (데이터는 있지만 분은 10c/분)로 두 개의 다른 전화기에서이를 테스트하고 있습니다. 나는 휴대폰을 가지고 가서 드라이브를 타면 SGS2가 완벽하게 작동하지만 ZTE는 문제를 해결할 수있는 능력을 잃어 가고있는 것으로 나타났습니다.

ZTE가 깨어나고, 수신기를 설정하고, 위치 수정을 받지만, 실제 위치가 아닌 내 집 (현재 Wi-Fi 기반 픽스가있는 위치)을 가리 킵니다. 위치의 타임 스탬프는 최신이므로 위치 업데이트를 수신하면 위치가 유효한지 (SGS2에서 또는 ZTE가 집에있을 때) 또는 침대 (예 : ZTE 운전).

비슷한 문제가있는 사람이 있습니까? 선불 카드 또는 ZTE 전화 자체와 관련이 있습니까? 불행히도 SIM 카드를 교환 할 수는 없으므로 (핸드폰의 루트/잠금 해제가 필요함) 테스트 할 수는 없습니다.

아래 코드를 포함 시켰지만 SGS2에서 제대로 작동하므로 문제가 많지 않습니다.

public class LocationRecorder extends Service { 

private volatile Location lastLocation; 
private LocationManager locationManager; 
private LocationListener locationListener; 

private static volatile PowerManager.WakeLock wakeLock = null; 


private static synchronized PowerManager.WakeLock getWakeLock(Context context) { 
    if (wakeLock == null) { 
     PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); 
     wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "LocationRecorder"); 
     wakeLock.acquire(); 
    } 
    return wakeLock; 
} 


public static void startLocationRecorder(Context context, Intent service) { 
    getWakeLock(context); 
    context.startService(service); 
} 


@Override 
public void onCreate() { 
    Log.d("LocationRecorder", "Starting Location Service"); 
    locationManager = ((LocationManager)getSystemService(LOCATION_SERVICE)); 
    locationListener = new LocationListener() { 
     @Override 
     public void onLocationChanged(Location location) { 
      Log.d("Location Changed", location.toString()); 
      if (location.getExtras()!=null) { 
       String x = ""; 
       for (String key : location.getExtras().keySet()) { 
        x+=key+":"+location.getExtras().get(key).toString()+", "; 
       } 
       Log.d("Location Changed Extras", x); 
      } 
      setLocation(location); 
     } 
     public void onStatusChanged(String provider, int status, Bundle extras) { 
      Log.d("Status Changed", provider+" "+status); 
      if (extras!=null) { 
       String x = ""; 
       for (String key : extras.keySet()) { 
        x+=key+":"+extras.get(key).toString()+", "; 
       } 
       Log.d("Status Changed Extras", x); 
      } 
     } 
     public void onProviderEnabled(String provider) { 
      Log.d("Provider Enabled", provider); 
     } 
     public void onProviderDisabled(String provider) { 
      Log.d("Provider Disabled", provider); 
     } 
    }; 
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); 
    waitForLocation(); 
} 


@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    return Service.START_REDELIVER_INTENT; 
} 


@Override 
public void onDestroy() { 
    locationManager.removeUpdates(locationListener); 
    try { 
     wakeLock.release(); 
     wakeLock = null; 
    } 
    catch (Exception e) { 
     wakeLock = null; 
    } 
    Log.d("LocationRecorder", "Destroying service"); 
    super.onDestroy(); 
} 


protected void waitForLocation() { 
    new Thread() { 
     @Override 
     public void run() { 
      setLocation(null); 
      for (int i=0; i<3;i++) { 
       Log.d("LocationRecorder", "Waiting for location"); 
       try {Thread.sleep(10000);} catch(Exception e) {}; 
       if (getLocation() != null) { 
        Log.d("LocationRecorder", "Sending new location!"); 
        new Utilities(LocationRecorder.this).updateLocation(getLocation().getLatitude(), 
            getLocation().getLongitude(), getLocation().getAccuracy()); 
        break; 
       } 
      } 
      stopSelf(); 
     } 
    }.start(); 

} 


public synchronized void setLocation(Location newLocation) { 
    lastLocation = newLocation; 
} 

public synchronized Location getLocation() { 
    return lastLocation; 
} 

@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

답변

1

이것은 예상되는 동작입니다. 최신 위치를 얻으려면 위치 관리자를 삭제하기 전에 오래 기다려야 할 수 있습니다.

다음은 Google Developer Docs의 설명입니다.

+2

그건 의미가 있지만 실제로받은 수정 프로그램이 실제로 오래된 것인지 아닌지 어떻게 알 수 있습니까? 위치 타임 스탬프가 최신 상태로 표시되고 엑스트라가 "wifi"또는 "셀"에서 왔는지 여부를 나타내는 동안 위치 개체 (엑스트라 포함)를 검사하는 것으로는 알 수 없습니다. networkLocationSource 항상 "캐싱"됩니다. – Martin

+0

'Location' 객체의 시간을 추가로 가져 오지 말고 [location.getTime()] (http://developer.android.com/reference/android/location/Location.html#getTime())을 호출하십시오.). 캐시 된/오래된 경우에도 정확한 수정 시간을 얻을 수 있습니다. –

관련 문제