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)
và alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, INTERVAL, INTERVAL, pendingIntent)
đã giải quyết được sự cố.
Loại báo thức phải là một trong các hằng số _WAKEUP, ví dụ: RTC_WAKEUP – msh
@msh Xem cập nhật 2. –
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