the tracker now collects locations / waypoints

master
y20k 2016-08-30 15:22:19 +02:00
parent e21879756b
commit 7dc5efb372
7 changed files with 193 additions and 52 deletions

View File

@ -17,7 +17,10 @@
package org.y20k.trackbook; package org.y20k.trackbook;
import android.app.Activity; import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.location.Location; import android.location.Location;
import android.location.LocationListener; import android.location.LocationListener;
@ -25,6 +28,7 @@ import android.location.LocationManager;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -58,6 +62,8 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
/* Main class variables */ /* Main class variables */
private Activity mActivity; private Activity mActivity;
private boolean mFirstStart;
private BroadcastReceiver mWayPointReceiver;
private MapView mMapView; private MapView mMapView;
private IMapController mController; private IMapController mController;
private LocationManager mLocationManager; private LocationManager mLocationManager;
@ -82,6 +88,17 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
// action bar has options menu // action bar has options menu
setHasOptionsMenu(true); setHasOptionsMenu(true);
// restore first start state
mFirstStart = true;
if (savedInstanceState != null) {
mFirstStart = savedInstanceState.getBoolean(INSTANCE_FIRST_START, true);
}
// register broadcast receiver for new WayPoints
mWayPointReceiver = createNewWayPointReceiver();
IntentFilter newWayPointReceiverIntentFilter = new IntentFilter(ACTION_WAYPOINT_ADDED);
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mWayPointReceiver, newWayPointReceiverIntentFilter);
// acquire reference to Location Manager // acquire reference to Location Manager
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE); mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
@ -180,11 +197,23 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
public void onDestroyView(){ public void onDestroyView(){
super.onDestroyView(); super.onDestroyView();
// unregister broadcast receiver
LocalBroadcastManager.getInstance(mActivity).unregisterReceiver(mWayPointReceiver);
// deactivate map // deactivate map
mMapView.onDetach(); mMapView.onDetach();
} }
@Override
public void onDestroy() {
// reset first start state
mFirstStart = true;
super.onDestroy();
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
@ -233,6 +262,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
// save map position // save map position
outState.putBoolean(INSTANCE_FIRST_START, mFirstStart);
outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude()); outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude());
outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude()); outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude());
outState.putInt(INSTANCE_ZOOM_LEVEL, mMapView.getZoomLevel()); outState.putInt(INSTANCE_ZOOM_LEVEL, mMapView.getZoomLevel());
@ -249,7 +279,10 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
mNetworkListener = createLocationListener(); mNetworkListener = createLocationListener();
// inform user that Trackbook is getting location updates // inform user that Trackbook is getting location updates
if (mFirstStart) {
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_acquiring_location), Toast.LENGTH_LONG).show(); Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_acquiring_location), Toast.LENGTH_LONG).show();
mFirstStart = false;
}
// start listener // start listener
List locationProviders = mLocationManager.getProviders(true); List locationProviders = mLocationManager.getProviders(true);
@ -333,6 +366,20 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
} }
/* Creates receiver for new WayPoints */
private BroadcastReceiver createNewWayPointReceiver () {
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.hasExtra(EXTRA_WAYPOINT_LOCATION) && intent.hasExtra(EXTRA_WAYPOINT_IS_STOPOVER)) {
// TODO draw location on map
Toast.makeText(mActivity, "New WayPoint: " + intent.getParcelableExtra(EXTRA_WAYPOINT_LOCATION).toString(), Toast.LENGTH_LONG).show(); // TODO Remove
}
}
};
}
/* Saves state of map */ /* Saves state of map */
private void saveMaoState(Context context) { private void saveMaoState(Context context) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);

View File

@ -29,6 +29,7 @@ import android.support.annotation.Nullable;
import android.util.Log; import android.util.Log;
import org.y20k.trackbook.core.Track; import org.y20k.trackbook.core.Track;
import org.y20k.trackbook.helpers.LocationHelper;
import org.y20k.trackbook.helpers.TrackbookKeys; import org.y20k.trackbook.helpers.TrackbookKeys;
@ -45,11 +46,11 @@ public class TrackerService extends Service implements TrackbookKeys {
private Track mTrack; private Track mTrack;
private CountDownTimer mTimer; private CountDownTimer mTimer;
private LocationManager mLocationManager; private LocationManager mLocationManager;
private LocationListener mLocationListener; private LocationListener mGPSListener;
private LocationListener mNetworkListener;
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
// return super.onStartCommand(intent, flags, startId);
// checking for empty intent // checking for empty intent
if (intent == null) { if (intent == null) {
@ -64,33 +65,23 @@ public class TrackerService extends Service implements TrackbookKeys {
Log.v(LOG_TAG, "Service received command: START"); Log.v(LOG_TAG, "Service received command: START");
// create a new track // create a new track
mTrack = new Track(); mTrack = new Track(getApplicationContext());
// acquire reference to Location Manager // acquire reference to Location Manager
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
// listener that responds to location updates // listeners that responds to location updates
mLocationListener = new LocationListener() { mGPSListener = createLocationListener();
public void onLocationChanged(Location location) { mNetworkListener = createLocationListener();
// add new location to track
mTrack.addWayPoint(location, false);
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO do something
}
public void onProviderEnabled(String provider) {
// TODO do something
}
public void onProviderDisabled(String provider) {
// TODO do something
}
};
// register location listeners and request updates
try { try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mLocationListener); mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGPSListener);
} catch (SecurityException e) {
e.printStackTrace();
}
try {
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mNetworkListener);
} catch (SecurityException e) { } catch (SecurityException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -111,9 +102,14 @@ 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 listeners
try { try {
mLocationManager.removeUpdates(mLocationListener); mLocationManager.removeUpdates(mGPSListener);
} catch (SecurityException e) {
e.printStackTrace();
}
try {
mLocationManager.removeUpdates(mNetworkListener);
} catch (SecurityException e) { } catch (SecurityException e) {
e.printStackTrace(); e.printStackTrace();
} }
@ -136,17 +132,56 @@ public class TrackerService extends Service implements TrackbookKeys {
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
Log.v(LOG_TAG, "onDestroy called."); // remove listeners
// Remove the listener you previously added
try { try {
mLocationManager.removeUpdates(mLocationListener); mLocationManager.removeUpdates(mGPSListener);
} catch (SecurityException e) { } catch (SecurityException e) {
e.printStackTrace(); e.printStackTrace();
} }
try {
mLocationManager.removeUpdates(mNetworkListener);
} catch (SecurityException e) {
e.printStackTrace();
}
Log.v(LOG_TAG, "onDestroy called.");
// cancel notification // cancel notification
stopForeground(true); stopForeground(true);
} }
/* Creates a location listener */
private LocationListener createLocationListener() {
return new LocationListener() {
public void onLocationChanged(Location location) {
// get number of tracked WayPoints
int trackSize = mTrack.getWayPoints().size();
if (trackSize >= 2) {
Location lastWayPoint = mTrack.getWayPointLocation(trackSize-2);
if (LocationHelper.isNewWayPoint(lastWayPoint, location)) {
// add new location to track
mTrack.addWayPoint(location);
}
} else {
// add first location to track
mTrack.addWayPoint(location);
}
}
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO do something
}
public void onProviderEnabled(String provider) {
// TODO do something
}
public void onProviderDisabled(String provider) {
// TODO do something
}
};
}
} }

View File

@ -16,14 +16,19 @@
package org.y20k.trackbook.core; package org.y20k.trackbook.core;
import android.content.Context;
import android.content.Intent;
import android.location.Location; import android.location.Location;
import android.util.Log; import android.support.v4.content.LocalBroadcastManager;
import org.y20k.trackbook.helpers.LocationHelper;
import org.y20k.trackbook.helpers.LogHelper;
import org.y20k.trackbook.helpers.TrackbookKeys; import org.y20k.trackbook.helpers.TrackbookKeys;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Track class * Track class
*/ */
@ -34,49 +39,58 @@ public class Track implements TrackbookKeys {
/* Main class variables */ /* Main class variables */
private List mWayPoints; private Context mContext;
private List<WayPoint> mWayPoints;
/* Constructor */ /* Constructor */
public Track() { public Track(Context context) {
mContext = context;
mWayPoints = new ArrayList<WayPoint>(); mWayPoints = new ArrayList<WayPoint>();
} }
/* Adds new waypoint */ /* Adds new waypoint */
public void addWayPoint(Location location, boolean isStopOver) { public void addWayPoint(Location location) {
// create new waypoint // create new waypoint
WayPoint wayPoint = new WayPoint(location, isStopOver); WayPoint wayPoint = new WayPoint();
wayPoint.location = location;
// TODO check if last waypoint is a stopover wayPoint.isStopOver = LocationHelper.isStopOver(location);
if (CONSTANT_MINIMAL_STOP_TIME != CONSTANT_MINIMAL_STOP_TIME) {
wayPoint.isStopOver = true;
} else {
wayPoint.isStopOver = false;
}
// add new waypoint to track // add new waypoint to track
mWayPoints.add(wayPoint); mWayPoints.add(wayPoint);
// TODO remove debugging log // send local broadcast: new WayPoint added
Log.v(LOG_TAG, "!!! new location: " + wayPoint.location.toString()); Intent i = new Intent();
i.setAction(ACTION_WAYPOINT_ADDED);
i.putExtra(EXTRA_WAYPOINT_LOCATION, location);
i.putExtra(EXTRA_WAYPOINT_IS_STOPOVER, wayPoint.isStopOver);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(i);
LogHelper.v(LOG_TAG, "!!! Waypoint No. " + mWayPoints.indexOf(wayPoint) + " Location: " + wayPoint.location.toString()); // TODO remove
}
/* Getter for mWayPoints */
public List<WayPoint> getWayPoints() {
return mWayPoints;
}
/* Getter for location of specific WayPoint */
public Location getWayPointLocation(int index) {
return mWayPoints.get(index).location;
} }
/** /**
* Inner class: Defines data type WayPoint *** * Inner class: Defines data type WayPoint
*/ */
private class WayPoint { private class WayPoint {
private Location location; private Location location;
private boolean isStopOver; private boolean isStopOver;
/* Constructor */
public WayPoint(Location location, boolean isStopOver) {
this.location = location;
this.isStopOver = isStopOver;
}
} }
/** /**
* End of inner class * End of inner class

View File

@ -34,7 +34,8 @@ public final class LocationHelper {
/* Main class variables */ /* Main class variables */
// private static final int TWO_MINUTES = 1000 * 1000 * 60 * 2; // private static final int TWO_MINUTES = 1000 * 1000 * 60 * 2;
private static final long TWO_MINUTES = 2L * 60000000000L; // 5 minutes private static final long TWO_MINUTES = 2L * 60000000000L; // 2 minutes
private static final long TWENTY_SECONDS = 20000000000L; // 20 seconds
/* Determines last known location */ /* Determines last known location */
@ -140,6 +141,23 @@ public final class LocationHelper {
} }
/* Checks if given location is a new waypoint over */
public static boolean isNewWayPoint(Location lastWayPoint, Location newLocation) {
float distance = newLocation.distanceTo(lastWayPoint);
long timeDifference = newLocation.getElapsedRealtimeNanos() - lastWayPoint.getElapsedRealtimeNanos();
// distance is bigger than 10 meters and time difference bigger than 20 seconds
return distance > 10 && timeDifference > TWENTY_SECONDS;
}
/* Checks if given location is a stop over */
public static boolean isStopOver(Location location) {
// TODO determine, if location is stopover
return false;
}
/* 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

View File

@ -25,8 +25,11 @@ public interface TrackbookKeys {
/* ACTIONS */ /* ACTIONS */
public static final String ACTION_START = "org.y20k.transistor.action.START"; public static final String ACTION_START = "org.y20k.transistor.action.START";
public static final String ACTION_STOP = "org.y20k.transistor.action.STOP"; public static final String ACTION_STOP = "org.y20k.transistor.action.STOP";
public static final String ACTION_WAYPOINT_ADDED = "WAYPOINT_ADDED";
/* EXTRAS */ /* EXTRAS */
public static final String EXTRA_WAYPOINT_LOCATION = "WAYPOINT_LOCATION";
public static final String EXTRA_WAYPOINT_IS_STOPOVER = "WAYPOINT_IS_STOPOVER";
/* ARGS */ /* ARGS */
public static final String ARG_PERMISSIONS_GRANTED = "ArgPermissionsGranted"; public static final String ARG_PERMISSIONS_GRANTED = "ArgPermissionsGranted";
@ -41,6 +44,7 @@ public interface TrackbookKeys {
public static final String PREFS_SHOW_COMPASS = "showCompass"; public static final String PREFS_SHOW_COMPASS = "showCompass";
/* INSTANCE STATE */ /* INSTANCE STATE */
public static final String INSTANCE_FIRST_START = "firstStart";
public static final String INSTANCE_LATITUDE = "latitude"; public static final String INSTANCE_LATITUDE = "latitude";
public static final String INSTANCE_LONGITUDE = "longitude"; public static final String INSTANCE_LONGITUDE = "longitude";
public static final String INSTANCE_ZOOM_LEVEL = "zoomLevel"; public static final String INSTANCE_ZOOM_LEVEL = "zoomLevel";

View File

@ -0,0 +1,10 @@
<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:fillColor="@color/trackbook_blue"
android:pathData="M48,48m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"/>
</vector>

View File

@ -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_red"
android:pathData="M48,48m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"/>
<path
android:fillColor="@color/trackbook_red"
android:pathData="M48,48m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"/>
</vector>