older locations fixes are now grey (my location) - refining the locations tracking. - some logging statements for debugging
parent
33606faac1
commit
e21879756b
|
@ -60,12 +60,11 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
private MapView mMapView;
|
private MapView mMapView;
|
||||||
private IMapController mController;
|
private IMapController mController;
|
||||||
private CompassOverlay mCompassOverlay = null;
|
|
||||||
private LocationManager mLocationManager;
|
private LocationManager mLocationManager;
|
||||||
private LocationListener mGPSListener;
|
private LocationListener mGPSListener;
|
||||||
private LocationListener mNetworkListener;
|
private LocationListener mNetworkListener;
|
||||||
private Location mCurrentBestLocation;
|
|
||||||
private ItemizedIconOverlay mMyLocationOverlay;
|
private ItemizedIconOverlay mMyLocationOverlay;
|
||||||
|
private Location mCurrentBestLocation;
|
||||||
|
|
||||||
|
|
||||||
/* Constructor (default) */
|
/* Constructor (default) */
|
||||||
|
@ -86,14 +85,28 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
// acquire reference to Location Manager
|
// acquire reference to Location Manager
|
||||||
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
|
||||||
// get last know location
|
// check if location services are available
|
||||||
List locationProviders = mLocationManager.getProviders(true);
|
if (mLocationManager.getProviders(true).size() == 0) {
|
||||||
if (locationProviders.size() > 0) {
|
// ask user to turn on location services
|
||||||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
|
||||||
} else {
|
|
||||||
promptUserForLocation();
|
promptUserForLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CASE 1: get saved location if possible
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
Location savedLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
||||||
|
// check if saved location is still current
|
||||||
|
if (LocationHelper.isNewLocation(savedLocation)) {
|
||||||
|
mCurrentBestLocation = savedLocation;
|
||||||
|
} else {
|
||||||
|
mCurrentBestLocation = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASE 2: get last known location if no saved location or saved location is too old
|
||||||
|
if (mCurrentBestLocation == null && mLocationManager.getProviders(true).size() > 0) {
|
||||||
|
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,13 +144,13 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add compass to map
|
// add compass to map
|
||||||
mCompassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView);
|
CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView);
|
||||||
mCompassOverlay.enableCompass();
|
compassOverlay.enableCompass();
|
||||||
mMapView.getOverlays().add(mCompassOverlay);
|
mMapView.getOverlays().add(compassOverlay);
|
||||||
|
|
||||||
// mark user's location on map
|
// mark user's location on map
|
||||||
if (mCurrentBestLocation != null) {
|
if (mCurrentBestLocation != null) {
|
||||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation);
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
||||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +218,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
// mark user's new location on map and remove last marker
|
// mark user's new location on map and remove last marker
|
||||||
mMapView.getOverlays().remove(mMyLocationOverlay);
|
mMapView.getOverlays().remove(mMyLocationOverlay);
|
||||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation);
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
||||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -232,8 +245,11 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
private void startFindingLocation() {
|
private void startFindingLocation() {
|
||||||
|
|
||||||
// listener that responds to location updates
|
// listener that responds to location updates
|
||||||
mGPSListener = createLocationsListener();
|
mGPSListener = createLocationListener();
|
||||||
mNetworkListener = createLocationsListener();
|
mNetworkListener = createLocationListener();
|
||||||
|
|
||||||
|
// inform user that Trackbook is getting location updates
|
||||||
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_acquiring_location), Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
// start listener
|
// start listener
|
||||||
List locationProviders = mLocationManager.getProviders(true);
|
List locationProviders = mLocationManager.getProviders(true);
|
||||||
|
@ -280,17 +296,17 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
|
|
||||||
/* Creates listener for changes in location status */
|
/* Creates listener for changes in location status */
|
||||||
private LocationListener createLocationsListener() {
|
private LocationListener createLocationListener() {
|
||||||
return new LocationListener() {
|
return new LocationListener() {
|
||||||
public void onLocationChanged(Location location) {
|
public void onLocationChanged(Location location) {
|
||||||
// check if the new location is better
|
// check if the new location is better
|
||||||
if (LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
if (LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
||||||
// save location
|
// save location
|
||||||
mCurrentBestLocation = location;
|
mCurrentBestLocation = location;
|
||||||
|
LogHelper.v(LOG_TAG, "Location isBetterLocation(!): " + location.getProvider()); // TODO remove
|
||||||
// mark user's new location on map and remove last marker
|
// mark user's new location on map and remove last marker
|
||||||
mMapView.getOverlays().remove(mMyLocationOverlay);
|
mMapView.getOverlays().remove(mMyLocationOverlay);
|
||||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation);
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
||||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,6 @@ import org.y20k.trackbook.helpers.TrackbookKeys;
|
||||||
*/
|
*/
|
||||||
public class TrackerService extends Service implements TrackbookKeys {
|
public class TrackerService extends Service implements TrackbookKeys {
|
||||||
|
|
||||||
// TODO study this https://developer.android.com/guide/topics/location/strategies.html
|
|
||||||
|
|
||||||
/* Define log tag */
|
/* Define log tag */
|
||||||
private static final String LOG_TAG = TrackerService.class.getSimpleName();
|
private static final String LOG_TAG = TrackerService.class.getSimpleName();
|
||||||
|
|
||||||
|
@ -91,10 +89,11 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
|
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
mTimer = new CountDownTimer(CONSTANT_MAXIMAL_DURATION, CONSTANT_TRACKING_INTERVAL) {
|
mTimer = new CountDownTimer(CONSTANT_MAXIMAL_DURATION, CONSTANT_TRACKING_INTERVAL) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,7 +112,11 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
// ACTION STOP
|
// ACTION STOP
|
||||||
else if (intent.getAction().equals(ACTION_STOP)) {
|
else if (intent.getAction().equals(ACTION_STOP)) {
|
||||||
// Remove the listener you previously added
|
// Remove the listener you previously added
|
||||||
|
try {
|
||||||
mLocationManager.removeUpdates(mLocationListener);
|
mLocationManager.removeUpdates(mLocationListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
Log.v(LOG_TAG, "Service received command: STOP");
|
Log.v(LOG_TAG, "Service received command: STOP");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +139,11 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
Log.v(LOG_TAG, "onDestroy called.");
|
Log.v(LOG_TAG, "onDestroy called.");
|
||||||
|
|
||||||
// Remove the listener you previously added
|
// Remove the listener you previously added
|
||||||
|
try {
|
||||||
mLocationManager.removeUpdates(mLocationListener);
|
mLocationManager.removeUpdates(mLocationListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
// cancel notification
|
// cancel notification
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.y20k.trackbook.helpers;
|
||||||
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -27,8 +28,13 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public final class LocationHelper {
|
public final class LocationHelper {
|
||||||
|
|
||||||
|
/* Define log tag */
|
||||||
|
private static final String LOG_TAG = LocationHelper.class.getSimpleName();
|
||||||
|
|
||||||
|
|
||||||
/* Main class variables */
|
/* Main class variables */
|
||||||
private static final int TWO_MINUTES = 1000 * 60 * 2;
|
// private static final int TWO_MINUTES = 1000 * 1000 * 60 * 2;
|
||||||
|
private static final long TWO_MINUTES = 2L * 60000000000L; // 5 minutes
|
||||||
|
|
||||||
|
|
||||||
/* Determines last known location */
|
/* Determines last known location */
|
||||||
|
@ -64,12 +70,13 @@ public final class LocationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// return best estimate location
|
// return best estimate location
|
||||||
if (isBetterLocation(gpsLocation, networkLocation)) {
|
if (isBetterLocation(networkLocation, gpsLocation)) {
|
||||||
return gpsLocation;
|
LogHelper.v(LOG_TAG, "Best last known location came from: " + networkLocation.getProvider()); // TODO remove
|
||||||
} else {
|
|
||||||
return networkLocation;
|
return networkLocation;
|
||||||
|
} else {
|
||||||
|
LogHelper.v(LOG_TAG, "Best last known location came from: " + gpsLocation.getProvider()); // TODO remove
|
||||||
|
return gpsLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -83,15 +90,17 @@ public final class LocationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether the new location fix is newer or older
|
// check whether the new location fix is newer or older
|
||||||
long timeDelta = location.getTime() - currentBestLocation.getTime();
|
long timeDelta = location.getElapsedRealtimeNanos() - currentBestLocation.getElapsedRealtimeNanos();
|
||||||
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
|
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
|
||||||
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
|
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
|
||||||
boolean isNewer = timeDelta > 0;
|
boolean isNewer = timeDelta > 0;
|
||||||
|
|
||||||
// if it's been more than two minutes since the current location, use the new location because the user has likely moved
|
// if it's been more than two minutes since the current location, use the new location because the user has likely moved
|
||||||
if (isSignificantlyNewer) {
|
if (isSignificantlyNewer) {
|
||||||
|
LogHelper.v(LOG_TAG, "Location isSignificantlyNewer: " + location.getProvider()); // TODO remove
|
||||||
return true;
|
return true;
|
||||||
} else if (isSignificantlyOlder) {
|
} else if (isSignificantlyOlder) {
|
||||||
|
LogHelper.v(LOG_TAG, "Location isSignificantlyOlder: " + location.getProvider()); // TODO remove
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,21 +111,35 @@ public final class LocationHelper {
|
||||||
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
|
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
|
||||||
|
|
||||||
// check if the old and new location are from the same provider
|
// check if the old and new location are from the same provider
|
||||||
boolean isFromSameProvider = isSameProvider(location.getProvider(),
|
boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());
|
||||||
currentBestLocation.getProvider());
|
|
||||||
|
|
||||||
// determine location quality using a combination of timeliness and accuracy
|
// determine location quality using a combination of timeliness and accuracy
|
||||||
if (isMoreAccurate) {
|
if (isMoreAccurate) {
|
||||||
|
LogHelper.v(LOG_TAG, "Location isMoreAccurate: " + location.getProvider()); // TODO remove
|
||||||
return true;
|
return true;
|
||||||
} else if (isNewer && !isLessAccurate) {
|
} else if (isNewer && !isLessAccurate) {
|
||||||
|
LogHelper.v(LOG_TAG, "Location isNewer && !isLessAccurate: " + location.getProvider()); // TODO remove
|
||||||
return true;
|
return true;
|
||||||
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
|
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
|
||||||
|
LogHelper.v(LOG_TAG, "Location isNewer && !isSignificantlyLessAccurate && isFromSameProvider: " + location.getProvider()); // TODO remove
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
LogHelper.v(LOG_TAG, "Location is not better: " + location.getProvider()); // TODO remove
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Checks if given location is newer than two minutes */
|
||||||
|
public static boolean isNewLocation(Location location) {
|
||||||
|
if (location == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
long locationTime = SystemClock.elapsedRealtimeNanos() - location.getElapsedRealtimeNanos();
|
||||||
|
return locationTime < TWO_MINUTES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Checks whether two location providers are the same */
|
/* Checks whether two location providers are the same */
|
||||||
private static boolean isSameProvider(String provider1, String provider2) {
|
private static boolean isSameProvider(String provider1, String provider2) {
|
||||||
// credit: the isSameProvider method was sample code from: https://developer.android.com/guide/topics/location/strategies.html
|
// credit: the isSameProvider method was sample code from: https://developer.android.com/guide/topics/location/strategies.html
|
||||||
|
|
|
@ -39,13 +39,19 @@ public final class MapHelper {
|
||||||
|
|
||||||
|
|
||||||
/* Creates icon overlay for current position */
|
/* Creates icon overlay for current position */
|
||||||
public static ItemizedIconOverlay createMyLocationOverlay(Context context, Location currentBestLocation) {
|
public static ItemizedIconOverlay createMyLocationOverlay(Context context, Location currentBestLocation, boolean locationIsNew) {
|
||||||
|
|
||||||
final GeoPoint position = new GeoPoint(currentBestLocation.getLatitude(), currentBestLocation.getLongitude());
|
final GeoPoint position = new GeoPoint(currentBestLocation.getLatitude(), currentBestLocation.getLongitude());
|
||||||
final ArrayList<OverlayItem> overlayItems = new ArrayList<>();
|
final ArrayList<OverlayItem> overlayItems = new ArrayList<>();
|
||||||
|
LogHelper.v(LOG_TAG, "Location is new? " + locationIsNew + " Provider: " + currentBestLocation.getProvider()); // TODO remove
|
||||||
|
|
||||||
// create marker
|
// create marker
|
||||||
Drawable newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_loacation_dot_blue_24dp);
|
Drawable newMarker;
|
||||||
|
if (locationIsNew) {
|
||||||
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_blue_24dp);
|
||||||
|
} else {
|
||||||
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_grey_24dp);
|
||||||
|
}
|
||||||
OverlayItem overlayItem = new OverlayItem(context.getString(R.string.marker_my_location_title), context.getString(R.string.marker_my_location_description), position);
|
OverlayItem overlayItem = new OverlayItem(context.getString(R.string.marker_my_location_title), context.getString(R.string.marker_my_location_description), position);
|
||||||
overlayItem.setMarker(newMarker);
|
overlayItem.setMarker(newMarker);
|
||||||
overlayItems.add(overlayItem);
|
overlayItems.add(overlayItem);
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<vector android:height="24dp" android:viewportHeight="96.0"
|
|
||||||
android:viewportWidth="96.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillAlpha="0.33" android:fillColor="#2095F2" android:pathData="M48,48m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"/>
|
|
||||||
<path android:fillColor="#2095F2" android:pathData="M48,48m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"/>
|
|
||||||
</vector>
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
|
android:viewportWidth="96.0"
|
||||||
|
android:width="24dp">
|
||||||
|
<path
|
||||||
|
android:fillAlpha="0.33"
|
||||||
|
android:fillColor="@color/trackbook_blue"
|
||||||
|
android:pathData="M48,48m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/trackbook_blue"
|
||||||
|
android:pathData="M48,48m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"/>
|
||||||
|
</vector>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
|
android:viewportWidth="96.0"
|
||||||
|
android:width="24dp">
|
||||||
|
<path
|
||||||
|
android:fillAlpha="0.33"
|
||||||
|
android:fillColor="@color/trackbook_blue"
|
||||||
|
android:pathData="M48,48m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"/>
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/trackbook_grey_light"
|
||||||
|
android:pathData="M48,48m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"/>
|
||||||
|
</vector>
|
|
@ -9,4 +9,8 @@
|
||||||
|
|
||||||
<color name="trackbook_white">#FFFFFFFF</color>
|
<color name="trackbook_white">#FFFFFFFF</color>
|
||||||
|
|
||||||
|
<color name="trackbook_grey_light">#FF607d8b</color>
|
||||||
|
|
||||||
|
<color name="trackbook_grey">#FF455a64</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
<string name="toast_message_permissions_granted">Permissions granted.</string>
|
<string name="toast_message_permissions_granted">Permissions granted.</string>
|
||||||
<string name="toast_message_unable_to_start_app">Unable to start Trackbook.</string>
|
<string name="toast_message_unable_to_start_app">Unable to start Trackbook.</string>
|
||||||
<string name="toast_message_location_offline">Location is turned off.</string>
|
<string name="toast_message_location_offline">Location is turned off.</string>
|
||||||
|
<string name="toast_message_acquiring_location">Acquiring current location.</string>
|
||||||
<string name="toast_message_my_location">My Location.</string>
|
<string name="toast_message_my_location">My Location.</string>
|
||||||
|
|
||||||
<!-- map markers -->
|
<!-- map markers -->
|
||||||
|
|
Loading…
Reference in New Issue