From 9bae6e554fb0f72bdc629dfc9a3490a705b30e15 Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sat, 8 Apr 2017 17:36:12 +1200 Subject: [PATCH] Implement reporting by distance and angle --- .../traccar/client/DistanceCalculator.java | 33 +++++++++++++++++++ .../java/org/traccar/client/MainActivity.java | 4 +++ .../traccar/client/MixedPositionProvider.java | 8 ++--- .../org/traccar/client/PositionProvider.java | 33 ++++++++++++++----- .../client/SimplePositionProvider.java | 2 +- app/src/main/res/values/strings.xml | 6 +++- app/src/main/res/xml-v14/preferences.xml | 14 ++++++++ app/src/main/res/xml/preferences.xml | 14 ++++++++ 8 files changed, 99 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/org/traccar/client/DistanceCalculator.java diff --git a/app/src/main/java/org/traccar/client/DistanceCalculator.java b/app/src/main/java/org/traccar/client/DistanceCalculator.java new file mode 100644 index 0000000..f0c7146 --- /dev/null +++ b/app/src/main/java/org/traccar/client/DistanceCalculator.java @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Anton Tananaev (anton@traccar.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.traccar.client; + +public final class DistanceCalculator { + + private static final double EQUATORIAL_EARTH_RADIUS = 6378.1370; + private static final double DEG_TO_RAD = Math.PI / 180; + + public static double distance(double lat1, double lon1, double lat2, double lon2) { + double dlong = (lon2 - lon1) * DEG_TO_RAD; + double dlat = (lat2 - lat1) * DEG_TO_RAD; + double a = Math.pow(Math.sin(dlat / 2), 2) + + Math.cos(lat1 * DEG_TO_RAD) * Math.cos(lat2 * DEG_TO_RAD) * Math.pow(Math.sin(dlong / 2), 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + double d = EQUATORIAL_EARTH_RADIUS * c; + return d * 1000; + } + +} diff --git a/app/src/main/java/org/traccar/client/MainActivity.java b/app/src/main/java/org/traccar/client/MainActivity.java index d587792..75f269d 100644 --- a/app/src/main/java/org/traccar/client/MainActivity.java +++ b/app/src/main/java/org/traccar/client/MainActivity.java @@ -50,6 +50,8 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen public static final String KEY_PORT = "port"; public static final String KEY_SECURE = "secure"; public static final String KEY_INTERVAL = "interval"; + public static final String KEY_DISTANCE = "distance"; + public static final String KEY_ANGLE = "angle"; public static final String KEY_PROVIDER = "provider"; public static final String KEY_STATUS = "status"; @@ -179,6 +181,8 @@ public class MainActivity extends PreferenceActivity implements OnSharedPreferen findPreference(KEY_PORT).setEnabled(enabled); findPreference(KEY_SECURE).setEnabled(enabled); findPreference(KEY_INTERVAL).setEnabled(enabled); + findPreference(KEY_DISTANCE).setEnabled(enabled); + findPreference(KEY_ANGLE).setEnabled(enabled); findPreference(KEY_PROVIDER).setEnabled(enabled); } diff --git a/app/src/main/java/org/traccar/client/MixedPositionProvider.java b/app/src/main/java/org/traccar/client/MixedPositionProvider.java index 5637fc9..67f807d 100644 --- a/app/src/main/java/org/traccar/client/MixedPositionProvider.java +++ b/app/src/main/java/org/traccar/client/MixedPositionProvider.java @@ -26,7 +26,7 @@ import android.util.Log; @SuppressWarnings("MissingPermission") public class MixedPositionProvider extends PositionProvider implements LocationListener, GpsStatus.Listener { - private static int FIX_TIMEOUT = 30 * 1000; + private static final int FIX_TIMEOUT = 30 * 1000; private LocationListener backupListener; private long lastFixTime; @@ -39,7 +39,7 @@ public class MixedPositionProvider extends PositionProvider implements LocationL lastFixTime = System.currentTimeMillis(); locationManager.addGpsStatusListener(this); try { - locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, period, 0, this); + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, requestInterval, 0, this); } catch (IllegalArgumentException e) { Log.w(TAG, e); } @@ -76,7 +76,7 @@ public class MixedPositionProvider extends PositionProvider implements LocationL }; locationManager.requestLocationUpdates( - LocationManager.NETWORK_PROVIDER, period, 0, backupListener); + LocationManager.NETWORK_PROVIDER, requestInterval, 0, backupListener); } } @@ -114,7 +114,7 @@ public class MixedPositionProvider extends PositionProvider implements LocationL @Override public void onGpsStatusChanged(int event) { - if (backupListener == null && System.currentTimeMillis() - (lastFixTime + period) > FIX_TIMEOUT) { + if (backupListener == null && System.currentTimeMillis() - lastFixTime - requestInterval > FIX_TIMEOUT) { startBackupProvider(); } } diff --git a/app/src/main/java/org/traccar/client/PositionProvider.java b/app/src/main/java/org/traccar/client/PositionProvider.java index 90ad583..7c44c79 100644 --- a/app/src/main/java/org/traccar/client/PositionProvider.java +++ b/app/src/main/java/org/traccar/client/PositionProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 - 2015 Anton Tananaev (anton.tananaev@gmail.com) + * Copyright 2013 - 2017 Anton Tananaev (anton.tananaev@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,8 @@ public abstract class PositionProvider { protected static final String TAG = PositionProvider.class.getSimpleName(); + private static final int MINIMUM_INTERVAL = 1000; + public interface PositionListener { void onPositionUpdate(Position position); } @@ -38,24 +40,34 @@ public abstract class PositionProvider { private final PositionListener listener; private final Context context; - private final SharedPreferences preferences; protected final LocationManager locationManager; private String deviceId; protected String type; - protected final long period; + protected long requestInterval; + protected long interval; + protected double distance; + protected double angle; - private long lastUpdateTime; + private Location lastLocation; public PositionProvider(Context context, PositionListener listener) { this.context = context; this.listener = listener; - preferences = PreferenceManager.getDefaultSharedPreferences(context); + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); deviceId = preferences.getString(MainActivity.KEY_DEVICE, null); - period = Long.parseLong(preferences.getString(MainActivity.KEY_INTERVAL, null)) * 1000; + interval = Long.parseLong(preferences.getString(MainActivity.KEY_INTERVAL, null)) * 1000; + distance = Integer.parseInt(preferences.getString(MainActivity.KEY_DISTANCE, null)); + angle = Integer.parseInt(preferences.getString(MainActivity.KEY_ANGLE, null)); + + if (distance > 0 || angle > 0) { + requestInterval = MINIMUM_INTERVAL; + } else { + requestInterval = interval; + } type = preferences.getString(MainActivity.KEY_PROVIDER, "gps"); } @@ -65,12 +77,15 @@ public abstract class PositionProvider { public abstract void stopUpdates(); protected void updateLocation(Location location) { - if (location != null && location.getTime() - lastUpdateTime >= period) { + if (location != null && (lastLocation == null + || location.getTime() - lastLocation.getTime() >= interval + || distance > 0 && DistanceCalculator.distance(location.getLatitude(), location.getLongitude(), lastLocation.getLatitude(), location.getLongitude()) >= distance + || angle > 0 && Math.abs(location.getBearing() - lastLocation.getBearing()) >= angle)) { Log.i(TAG, "location new"); - lastUpdateTime = location.getTime(); + lastLocation = location; listener.onPositionUpdate(new Position(deviceId, location, getBatteryLevel(context))); } else { - Log.i(TAG, location != null ? "location old" : "location nil"); + Log.i(TAG, location != null ? "location ignored" : "location nil"); } } diff --git a/app/src/main/java/org/traccar/client/SimplePositionProvider.java b/app/src/main/java/org/traccar/client/SimplePositionProvider.java index 32a346f..3062ba7 100644 --- a/app/src/main/java/org/traccar/client/SimplePositionProvider.java +++ b/app/src/main/java/org/traccar/client/SimplePositionProvider.java @@ -34,7 +34,7 @@ public class SimplePositionProvider extends PositionProvider implements Location public void startUpdates() { try { - locationManager.requestLocationUpdates(type, period, 0, this); + locationManager.requestLocationUpdates(type, requestInterval, 0, this); } catch (IllegalArgumentException e) { Log.w(TAG, e); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4e71662..8dd54aa 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -11,7 +11,11 @@ Server port Tracking server TCP port Frequency - Messages interval in seconds + Reporting interval in seconds + Distance + Reporting distance in meters + Angle + Reporting angle in degrees Service status Start Stop diff --git a/app/src/main/res/xml-v14/preferences.xml b/app/src/main/res/xml-v14/preferences.xml index 39fe353..a402b81 100644 --- a/app/src/main/res/xml-v14/preferences.xml +++ b/app/src/main/res/xml-v14/preferences.xml @@ -43,6 +43,20 @@ android:summary="@string/settings_interval_summary" android:title="@string/settings_interval_title" /> + + + + + + + +