2013-08-15 40 views
9

Tôi cần viết một ứng dụng, mỗi 5 phút sẽ xác định vị trí hiện tại của điện thoại di động (sử dụng tất cả các nhà cung cấp vị trí có sẵn miễn phí) và gửi nó đến máy chủ.Làm cách nào để liên tục theo dõi vị trí của điện thoại di động Android?

Nếu một số nhà cung cấp vị trí không hoạt động khi bắt đầu ứng dụng, nhưng sẽ khả dụng sau này, ứng dụng cũng sẽ xử lý dữ liệu vị trí của nó.

Để thực hiện việc này, tôi đã triển khai sau lớp học. Trong một trong các hoạt động của tôi, tôi tạo một thể hiện của nó và gọi phương thức startTrackingUpdates của nó. locationChangeHandler xử lý dữ liệu vị trí.

public class LocationTracker implements ILocationTracker, LocationListener { 
    public static final long MIN_TIME_BETWEEN_UPDATES = 1000 * 60 * 5; // 5 minutes 
    public static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters 
    private ILocationManager locationManager; 
    private ILocationChangeHandler locationChangeHandler; 

    public LocationTracker(final ILocationManager aLocationManager, 
      final ILocationChangeHandler aLocationChangeHandler) { 
     this.locationManager = aLocationManager; 
     this.locationChangeHandler = aLocationChangeHandler; 
    } 

    public void startTrackingUpdates() { 
     final List<String> providers = locationManager.getAllProviders(); 

     for (final String curProviderName : providers) 
     { 
      final ILocationProvider provider = locationManager.getLocationProvider(curProviderName); 

      if (!provider.hasMonetaryCost()) 
      { 
       subscribeToLocationChanges(provider); 
      } 
     } 
    } 

    private void subscribeToLocationChanges(final ILocationProvider aProvider) { 
     locationManager.requestLocationUpdates(aProvider.getName(), MIN_TIME_BETWEEN_UPDATES, 
       (float)MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
    } 

    public void onLocationChanged(final Location aLocation) { 
     locationChangeHandler.processLocationChange(new LocationWrapper(aLocation)); 
    } 

    public void onProviderDisabled(final String aProvider) { 
    } 

    public void onProviderEnabled(final String aProvider) { 
    } 

    public void onStatusChanged(final String aProvider, final int aStatus, 
      final Bundle aExtras) { 
    } 
} 

Tôi đã tạo ứng dụng và cài đặt nó trên điện thoại di động của mình. Sau đó, vào buổi sáng tôi lấy điện thoại, đi làm, rồi về nhà. Ở nhà tôi đã kiểm tra kết quả của một công việc dài ngày của ứng dụng và chỉ tìm thấy một bản ghi trong cơ sở dữ liệu.

Với điều kiện phần còn lại của hệ thống (truyền dữ liệu vị trí đến máy chủ, lưu trong cơ sở dữ liệu) hoạt động chính xác, tôi phải gặp một số vấn đề trong mã theo dõi vị trí (onLocationChanged) vài lần).

Mã của tôi bị sai (làm cách nào để thay đổi mã, để cho số onLocationChanged được gọi bất cứ khi nào vị trí của điện thoại thay đổi hơn MIN_DISTANCE_CHANGE_FOR_UPDATES mét theo một trong các nhà cung cấp locatin)?

Cập nhật 1 (2013/08/18 13:59 MSK):

tôi đã thay đổi mã của tôi theo msh khuyến nghị. Tôi bắt đầu hẹn giờ sử dụng mã sau đây:

public void startSavingGeoData() { 
    final IAlarmManager alarmManager = activity.getAlarmManager(); 
    final IPendingIntent pendingIntent = activity.createPendingResult(
      ALARM_ID, intentFactory.createEmptyIntent(), 0); 
    alarmManager.setRepeating(INTERVAL, pendingIntent); 
} 

Trong activity Tôi đặt sau xử lý timer sự kiện:

@Override 
protected void onActivityResult(final int aRequestCode, final int aResultCode, 
     final Intent aData) { 
    geoDataSender.processOnActivityResult(aRequestCode, aResultCode, 
      new IntentWrapper(aData)); 
} 

Khi điện thoại được bật, mọi thứ hoạt động như mong đợi - onActivityResult được thực hiện một lần trong INTERVAL mili giây.

Nhưng khi tôi nhấn nút nguồn (màn hình bị tắt), onActivityResult không được viện dẫn chút nào. Khi tôi nhấn nút nguồn một lần nữa, onActivityResult được thực hiện nhiều lần, như INTERVAL đã trôi qua kể từ khi tôi tắt điện thoại. Nếu tôi tắt điện thoại cho 1 * INTERVAL mili giây, điện thoại sẽ kích hoạt một lần. Nếu tôi tắt điện thoại cho 2 * INTERVAL mili giây, nó sẽ kích hoạt hai lần, v.v.

Lưu ý: Bằng cách tắt "Tôi có nghĩa là nhấn nhanh nút nguồn (điện thoại vẫn" sống "và phản ứng với SMS đến, cho thí dụ).

Làm cách nào để sửa đổi mã startSavingGeoData để phương thức onActivityResult được thực hiện sau mỗi INTERVAL mili giây, ngay cả khi điện thoại ngủ?

Cập nhật 2 (18.08.2013 19:29 MSK): Không alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, 0, INTERVAL, pendingIntent)alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, INTERVAL, INTERVAL, pendingIntent) đã giải quyết được sự cố.

+0

Loại báo thức phải là một trong các hằng số _WAKEUP, ví dụ: RTC_WAKEUP – msh

+0

@msh Xem cập nhật 2. –

+0

Thử http://stackoverflow.com/questions/4459058/alarm-manager-example trước - nếu nó hoạt động, dựa trên nó. Lưu ý rằng nó chỉ giữ wakelock cho đến khi onReceive trả về, nếu bạn cần chạy lâu hơn - có được – msh

Trả lời

8

Mã của bạn có thể đúng, nhưng các nhà cung cấp vị trí không hoạt động khi điện thoại của bạn đang ngủ.Bạn có thể cần mua một chiếc wakelock (nếu bạn không quan tâm đến việc rút điện), hoặc sử dụng AlarmManager và lên lịch cho ứng dụng của bạn thức dậy và kiểm tra vị trí định kỳ (bạn vẫn cần phải có wakelock đang hoạt động trong khi chờ đợi cập nhật) được mua lại bởi AlamManager, hoặc của riêng bạn).

+0

của riêng bạn, tôi đã thay đổi mã (xem "Cập nhật 1"), nhưng nó vẫn không hoạt động như mong đợi. Bất kỳ ý tưởng? –

+0

Bạn có thể căn cứ mã cảnh báo của mình trên ví dụ này http://stackoverflow.com/questions/4459058/alarm-manager-example – msh

+0

Có, ví dụ đó hoạt động, ít nhất là phương pháp để có được vị trí được thực thi ngay cả khi điện thoại ngủ. –

Các vấn đề liên quan