Trackbook now draws breadcrumbs onto map. Track and WayPoint objects are now parcelable.
This commit is contained in:
parent
7b793fc9dd
commit
c636886e90
11 changed files with 469 additions and 185 deletions
|
@ -6,13 +6,13 @@ Trackbook - Movement recorder for Android
|
||||||
|
|
||||||
**Version 0.1.x ("The Great Gig in the Sky")**
|
**Version 0.1.x ("The Great Gig in the Sky")**
|
||||||
|
|
||||||
Trackbook is a bare bones app for recording you own movements. Trackbook great for hiking, vacation or workout. Once started it displays your movements on a map. You can save your recorded tracks and share them with friends.
|
Trackbook is a bare bones app for recording your movements. Trackbook is great for hiking, vacation or workout. Once started it displays your movements on a map. You can save your recorded tracks and share them with friends.
|
||||||
|
|
||||||
Trackbook is free software. It is published under the [MIT open source license](https://opensource.org/licenses/MIT). Trackbook uses [osmdroid](https://github.com/osmdroid/osmdroid) to display the map. osmdroid is also free software. It is published under the [Apache License](https://github.com/osmdroid/osmdroid/blob/master/LICENSE). Want to help? Please check out the notes in [CONTRIBUTE.md](https://github.com/y20k/transistor/blob/master/CONTRIBUTE.md) first.
|
Trackbook is free software. It is published under the [MIT open source license](https://opensource.org/licenses/MIT). Trackbook uses [osmdroid](https://github.com/osmdroid/osmdroid) to display the map. osmdroid is also free software. It is published under the [Apache License](https://github.com/osmdroid/osmdroid/blob/master/LICENSE). Want to help? Please check out the notes in [CONTRIBUTE.md](https://github.com/y20k/transistor/blob/master/CONTRIBUTE.md) first.
|
||||||
|
|
||||||
Install Trackbook
|
Install Trackbook
|
||||||
------------------
|
------------------
|
||||||
Do not install. Trackbook does not do anythimg useful right now. See the Install Canary below? Wait until it flies.
|
Do not install Trackbook. Trackbook does not do anythimg useful right now. See the Install Canary below? Wait until it flies.
|
||||||
|
|
||||||
|
|
||||||
.---.
|
.---.
|
||||||
|
@ -33,7 +33,7 @@ tbd
|
||||||
Which Permissions does Trackbook need?
|
Which Permissions does Trackbook need?
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
### Permission "INTERNET"
|
### Permission "INTERNET"
|
||||||
tbd
|
Trackbook needs to download map data from Open Street Map servers and therefore needs access to the internet.
|
||||||
|
|
||||||
### Permission "ACCESS_NETWORK_STATE"
|
### Permission "ACCESS_NETWORK_STATE"
|
||||||
tbd
|
tbd
|
||||||
|
@ -48,4 +48,4 @@ tbd
|
||||||
tbd
|
tbd
|
||||||
|
|
||||||
### Permission "WRITE_EXTERNAL_STORAGE"
|
### Permission "WRITE_EXTERNAL_STORAGE"
|
||||||
tbd
|
Trackbook uses [osmdroid](https://github.com/osmdroid/osmdroid), which caches map tiles on Android's external storage. You can find the map cache in the `osmdroid` folder on the top level of the user-facing file system.
|
||||||
|
|
|
@ -48,7 +48,7 @@ import java.util.Map;
|
||||||
public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
|
|
||||||
/* Define log tag */
|
/* Define log tag */
|
||||||
private static final String LOG_TAG = MainActivityFragment.class.getSimpleName();
|
private static final String LOG_TAG = MainActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
|
||||||
/* Main class variables */
|
/* Main class variables */
|
||||||
|
@ -56,6 +56,7 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
private boolean mPermissionsGranted;
|
private boolean mPermissionsGranted;
|
||||||
private List<String> mMissingPermissions;
|
private List<String> mMissingPermissions;
|
||||||
private FloatingActionButton mFloatingActionButton;
|
private FloatingActionButton mFloatingActionButton;
|
||||||
|
private MainActivityFragment mMainActivityFragment;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,9 +125,11 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
// set state of FloatingActionButton
|
// if not in onboarding mode: set state of FloatingActionButton
|
||||||
|
if (mFloatingActionButton != null) {
|
||||||
setFloatingActionButtonState();
|
setFloatingActionButtonState();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -172,6 +175,9 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
// get reference to fragment
|
||||||
|
mMainActivityFragment = (MainActivityFragment)getSupportFragmentManager().findFragmentById(R.id.content_main);
|
||||||
|
|
||||||
// show the record button and attach listener
|
// show the record button and attach listener
|
||||||
mFloatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
|
mFloatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
|
||||||
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
|
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@ -227,14 +233,15 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
mFloatingActionButton.setImageResource(R.drawable.ic_fiber_manual_record_red_24dp);
|
mFloatingActionButton.setImageResource(R.drawable.ic_fiber_manual_record_red_24dp);
|
||||||
mTracking = true;
|
mTracking = true;
|
||||||
|
|
||||||
// TODO putParcelable lastLocation
|
|
||||||
|
|
||||||
// start tracker service
|
// start tracker service
|
||||||
Intent intent = new Intent(this, TrackerService.class);
|
Intent intent = new Intent(this, TrackerService.class);
|
||||||
intent.setAction(ACTION_START);
|
intent.setAction(ACTION_START);
|
||||||
startService(intent);
|
startService(intent);
|
||||||
LogHelper.v(LOG_TAG, "Starting tracker service.");
|
LogHelper.v(LOG_TAG, "Starting tracker service.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update tracking state in MainActivityFragment
|
||||||
|
mMainActivityFragment.setTrackingState(mTracking);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ import org.osmdroid.views.MapView;
|
||||||
import org.osmdroid.views.overlay.ItemizedIconOverlay;
|
import org.osmdroid.views.overlay.ItemizedIconOverlay;
|
||||||
import org.osmdroid.views.overlay.compass.CompassOverlay;
|
import org.osmdroid.views.overlay.compass.CompassOverlay;
|
||||||
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
||||||
|
import org.y20k.trackbook.core.Track;
|
||||||
import org.y20k.trackbook.helpers.LocationHelper;
|
import org.y20k.trackbook.helpers.LocationHelper;
|
||||||
import org.y20k.trackbook.helpers.LogHelper;
|
import org.y20k.trackbook.helpers.LogHelper;
|
||||||
import org.y20k.trackbook.helpers.MapHelper;
|
import org.y20k.trackbook.helpers.MapHelper;
|
||||||
|
@ -62,15 +63,18 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
/* Main class variables */
|
/* Main class variables */
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
|
private Track mTrack;
|
||||||
private boolean mFirstStart;
|
private boolean mFirstStart;
|
||||||
private BroadcastReceiver mWayPointReceiver;
|
private BroadcastReceiver mTrackUpdatedReceiver;
|
||||||
private MapView mMapView;
|
private MapView mMapView;
|
||||||
private IMapController mController;
|
private IMapController mController;
|
||||||
private LocationManager mLocationManager;
|
private LocationManager mLocationManager;
|
||||||
private LocationListener mGPSListener;
|
private LocationListener mGPSListener;
|
||||||
private LocationListener mNetworkListener;
|
private LocationListener mNetworkListener;
|
||||||
private ItemizedIconOverlay mMyLocationOverlay;
|
private ItemizedIconOverlay mMyLocationOverlay;
|
||||||
|
private ItemizedIconOverlay mTrackOverlay;
|
||||||
private Location mCurrentBestLocation;
|
private Location mCurrentBestLocation;
|
||||||
|
private boolean mTacking;
|
||||||
|
|
||||||
|
|
||||||
/* Constructor (default) */
|
/* Constructor (default) */
|
||||||
|
@ -94,10 +98,16 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
mFirstStart = savedInstanceState.getBoolean(INSTANCE_FIRST_START, true);
|
mFirstStart = savedInstanceState.getBoolean(INSTANCE_FIRST_START, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restore tracking state
|
||||||
|
mTacking = false;
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
mTacking = savedInstanceState.getBoolean(INSTANCE_TRACKING_STARTED, false);
|
||||||
|
}
|
||||||
|
|
||||||
// register broadcast receiver for new WayPoints
|
// register broadcast receiver for new WayPoints
|
||||||
mWayPointReceiver = createNewWayPointReceiver();
|
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
||||||
IntentFilter newWayPointReceiverIntentFilter = new IntentFilter(ACTION_WAYPOINT_ADDED);
|
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
||||||
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mWayPointReceiver, newWayPointReceiverIntentFilter);
|
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
||||||
|
|
||||||
// acquire reference to Location Manager
|
// acquire reference to Location Manager
|
||||||
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
@ -160,6 +170,14 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
mController.setZoom(16);
|
mController.setZoom(16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restore track
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
mTrack = savedInstanceState.getParcelable(INSTANCE_TRACK);
|
||||||
|
}
|
||||||
|
if (mTrack != null) {
|
||||||
|
drawTrackOverlay(mTrack);
|
||||||
|
}
|
||||||
|
|
||||||
// add compass to map
|
// add compass to map
|
||||||
CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView);
|
CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView);
|
||||||
compassOverlay.enableCompass();
|
compassOverlay.enableCompass();
|
||||||
|
@ -167,7 +185,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
// mark user's location on map
|
// mark user's location on map
|
||||||
if (mCurrentBestLocation != null) {
|
if (mCurrentBestLocation != null) {
|
||||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation), mTacking);
|
||||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,8 +206,8 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
// disable location listener
|
// disable location listeners
|
||||||
stopFindingLocation();
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,7 +216,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
|
||||||
// unregister broadcast receiver
|
// unregister broadcast receiver
|
||||||
LocalBroadcastManager.getInstance(mActivity).unregisterReceiver(mWayPointReceiver);
|
LocalBroadcastManager.getInstance(mActivity).unregisterReceiver(mTrackUpdatedReceiver);
|
||||||
|
|
||||||
// deactivate map
|
// deactivate map
|
||||||
mMapView.onDetach();
|
mMapView.onDetach();
|
||||||
|
@ -246,9 +264,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
mController.setCenter(position);
|
mController.setCenter(position);
|
||||||
|
|
||||||
// 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);
|
updateMyLocationMarker();
|
||||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
|
||||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -267,64 +283,33 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
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());
|
||||||
outState.putParcelable(INSTANCE_CURRENT_LOCATION, mCurrentBestLocation);
|
outState.putParcelable(INSTANCE_CURRENT_LOCATION, mCurrentBestLocation);
|
||||||
|
outState.putParcelable(INSTANCE_TRACK, mTrack);
|
||||||
|
outState.putBoolean(INSTANCE_TRACKING_STARTED, mTacking);
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Sets tracking state */
|
||||||
|
public void setTrackingState (boolean trackingStarted) {
|
||||||
|
mTacking = trackingStarted;
|
||||||
|
updateMyLocationMarker();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Start finding location for map */
|
/* Start finding location for map */
|
||||||
private void startFindingLocation() {
|
private void startFindingLocation() {
|
||||||
|
// create location listeners
|
||||||
// listener that responds to location updates
|
List locationProviders = mLocationManager.getProviders(true);
|
||||||
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||||||
mGPSListener = createLocationListener();
|
mGPSListener = createLocationListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||||||
mNetworkListener = createLocationListener();
|
mNetworkListener = createLocationListener();
|
||||||
|
|
||||||
// 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();
|
|
||||||
mFirstStart = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start listener
|
// register listeners
|
||||||
List locationProviders = mLocationManager.getProviders(true);
|
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
|
||||||
try {
|
|
||||||
// enable location listener (gps)
|
|
||||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGPSListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
// catches permission problems
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
|
||||||
try {
|
|
||||||
// enable location listener (network)
|
|
||||||
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, mNetworkListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
// catches permission problems
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Stops finding location for map */
|
|
||||||
private void stopFindingLocation() {
|
|
||||||
// disable location listeners
|
|
||||||
List locationProviders = mLocationManager.getProviders(true);
|
|
||||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
|
||||||
try {
|
|
||||||
mLocationManager.removeUpdates(mGPSListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
// catches permission problems
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
|
||||||
try {
|
|
||||||
mLocationManager.removeUpdates(mNetworkListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
// catches permission problems
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,9 +323,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
mCurrentBestLocation = location;
|
mCurrentBestLocation = location;
|
||||||
LogHelper.v(LOG_TAG, "Location isBetterLocation(!): " + location.getProvider()); // TODO remove
|
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);
|
updateMyLocationMarker();
|
||||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
|
||||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,6 +342,22 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Updates marker for current user location */
|
||||||
|
private void updateMyLocationMarker() {
|
||||||
|
mMapView.getOverlays().remove(mMyLocationOverlay);
|
||||||
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation),mTacking);
|
||||||
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Draws track onto overlay */
|
||||||
|
private void drawTrackOverlay(Track track) {
|
||||||
|
mMapView.getOverlays().remove(mTrackOverlay);
|
||||||
|
mTrackOverlay = MapHelper.createTrackOverlay(mActivity, track);
|
||||||
|
mMapView.getOverlays().add(mTrackOverlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Prompts user to turn on location */
|
/* Prompts user to turn on location */
|
||||||
private void promptUserForLocation() {
|
private void promptUserForLocation() {
|
||||||
// TODO prompt user to turn on location
|
// TODO prompt user to turn on location
|
||||||
|
@ -367,13 +366,14 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
|
|
||||||
/* Creates receiver for new WayPoints */
|
/* Creates receiver for new WayPoints */
|
||||||
private BroadcastReceiver createNewWayPointReceiver () {
|
private BroadcastReceiver createTrackUpdatedReceiver() {
|
||||||
return new BroadcastReceiver() {
|
return new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (intent.hasExtra(EXTRA_WAYPOINT_LOCATION) && intent.hasExtra(EXTRA_WAYPOINT_IS_STOPOVER)) {
|
if (intent.hasExtra(EXTRA_TRACK)) {
|
||||||
// TODO draw location on map
|
mTrack = intent.getParcelableExtra(EXTRA_TRACK);
|
||||||
Toast.makeText(mActivity, "New WayPoint: " + intent.getParcelableExtra(EXTRA_WAYPOINT_LOCATION).toString(), Toast.LENGTH_LONG).show(); // TODO Remove
|
drawTrackOverlay(mTrack);
|
||||||
|
Toast.makeText(mActivity, "New WayPoint.", Toast.LENGTH_LONG).show(); // TODO Remove
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,12 +26,16 @@ import android.os.Bundle;
|
||||||
import android.os.CountDownTimer;
|
import android.os.CountDownTimer;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
|
||||||
import org.y20k.trackbook.core.Track;
|
import org.y20k.trackbook.core.Track;
|
||||||
|
import org.y20k.trackbook.core.WayPoint;
|
||||||
import org.y20k.trackbook.helpers.LocationHelper;
|
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.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TrackerService class
|
* TrackerService class
|
||||||
|
@ -46,8 +50,9 @@ 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 mGPSListener;
|
private LocationListener mGPSListener = null;
|
||||||
private LocationListener mNetworkListener;
|
private LocationListener mNetworkListener = null;
|
||||||
|
private Location mCurrentBestLocation;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
@ -57,25 +62,26 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
|
|
||||||
// checking for empty intent
|
// checking for empty intent
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
Log.v(LOG_TAG, "Null-Intent received. Stopping self.");
|
LogHelper.v(LOG_TAG, "Null-Intent received. Stopping self.");
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACTION START
|
// ACTION START
|
||||||
else if (intent.getAction().equals(ACTION_START)) {
|
else if (intent.getAction().equals(ACTION_START)) {
|
||||||
Log.v(LOG_TAG, "Service received command: START");
|
LogHelper.v(LOG_TAG, "Service received command: START");
|
||||||
|
|
||||||
// create a new track
|
// create a new track
|
||||||
mTrack = new Track(getApplicationContext());
|
mTrack = new Track();
|
||||||
|
|
||||||
// create gps and network location listeners
|
// add first location to track
|
||||||
createListeners();
|
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||||
|
addWayPointToTrack();
|
||||||
|
|
||||||
// set a timer to prevent endless tracking
|
// set timer to retrieve new locations and to prevent endless tracking
|
||||||
mTimer = new CountDownTimer(CONSTANT_MAXIMAL_DURATION, CONSTANT_TRACKING_INTERVAL) {
|
mTimer = new CountDownTimer(CONSTANT_MAXIMAL_DURATION, CONSTANT_TRACKING_INTERVAL) {
|
||||||
@Override
|
@Override
|
||||||
public void onTick(long l) {
|
public void onTick(long l) {
|
||||||
// TODO
|
addWayPointToTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,15 +89,22 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
mTimer.start();
|
||||||
|
|
||||||
|
// create gps and network location listeners
|
||||||
|
startFindingLocation();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACTION STOP
|
// ACTION STOP
|
||||||
else if (intent.getAction().equals(ACTION_STOP)) {
|
else if (intent.getAction().equals(ACTION_STOP)) {
|
||||||
Log.v(LOG_TAG, "Service received command: STOP");
|
LogHelper.v(LOG_TAG, "Service received command: STOP");
|
||||||
|
|
||||||
|
// stop timer
|
||||||
|
mTimer.cancel();
|
||||||
|
|
||||||
// remove listeners
|
// remove listeners
|
||||||
removeListeners();
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// START_STICKY is used for services that are explicitly started and stopped as needed
|
// START_STICKY is used for services that are explicitly started and stopped as needed
|
||||||
|
@ -108,10 +121,10 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
Log.v(LOG_TAG, "onDestroy called.");
|
LogHelper.v(LOG_TAG, "onDestroy called.");
|
||||||
|
|
||||||
// remove listeners
|
// remove listeners
|
||||||
removeListeners();
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
|
|
||||||
// cancel notification
|
// cancel notification
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
@ -120,23 +133,49 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Adds a new WayPoint to current track */
|
||||||
|
public void addWayPointToTrack() {
|
||||||
|
|
||||||
|
// create new WayPoint
|
||||||
|
WayPoint newWayPoint = null;
|
||||||
|
|
||||||
|
// get number of previously tracked WayPoints
|
||||||
|
int trackSize = mTrack.getWayPoints().size();
|
||||||
|
|
||||||
|
if (trackSize > 0) {
|
||||||
|
// get last waypoint and compare it to current location
|
||||||
|
Location lastWayPoint = mTrack.getWayPointLocation(trackSize-1);
|
||||||
|
if (LocationHelper.isNewWayPoint(lastWayPoint, mCurrentBestLocation)) {
|
||||||
|
LogHelper.v(LOG_TAG, "!!! Ding. " + mTrack.getSize());
|
||||||
|
// if new, add current best location to track
|
||||||
|
newWayPoint = mTrack.addWayPoint(mCurrentBestLocation);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// add first location to track
|
||||||
|
newWayPoint = mTrack.addWayPoint(mCurrentBestLocation);
|
||||||
|
LogHelper.v(LOG_TAG, "!!! Dong. " + mTrack.getSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
// send local broadcast if new WayPoint added
|
||||||
|
if (newWayPoint != null) {
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.setAction(ACTION_TRACK_UPDATED);
|
||||||
|
i.putExtra(EXTRA_TRACK, mTrack);
|
||||||
|
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Creates a location listener */
|
/* Creates a location listener */
|
||||||
private LocationListener createLocationListener() {
|
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
|
||||||
// get number of tracked WayPoints
|
if (LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
||||||
int trackSize = mTrack.getWayPoints().size();
|
// save location
|
||||||
|
mCurrentBestLocation = location;
|
||||||
if (trackSize >= 2) {
|
// TODO hand over mCurrentBestLocation to fragment
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,53 +195,18 @@ public class TrackerService extends Service implements TrackbookKeys {
|
||||||
|
|
||||||
|
|
||||||
/* Creates gps and network location listeners */
|
/* Creates gps and network location listeners */
|
||||||
private void createListeners() {
|
private void startFindingLocation() {
|
||||||
Log.v(LOG_TAG, "Setting up location listeners.");
|
LogHelper.v(LOG_TAG, "Setting up location listeners.");
|
||||||
|
|
||||||
// listeners that responds to location updates
|
|
||||||
mGPSListener = createLocationListener();
|
|
||||||
mNetworkListener = createLocationListener();
|
|
||||||
|
|
||||||
// register location listeners and request updates
|
// register location listeners and request updates
|
||||||
try {
|
List locationProviders = mLocationManager.getProviders(true);
|
||||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mGPSListener);
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||||||
} catch (SecurityException e) {
|
mGPSListener = createLocationListener();
|
||||||
e.printStackTrace();
|
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||||||
}
|
mNetworkListener = createLocationListener();
|
||||||
try {
|
|
||||||
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mNetworkListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Removes gps and network location listeners */
|
|
||||||
private void removeListeners() {
|
|
||||||
Log.v(LOG_TAG, "Removing location listeners.");
|
|
||||||
|
|
||||||
// remove gps listener
|
|
||||||
if (mGPSListener != null) {
|
|
||||||
Log.v(LOG_TAG, "Removing GPS location listener.");
|
|
||||||
try {
|
|
||||||
mLocationManager.removeUpdates(mGPSListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
// catches permission problems
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove network listener
|
|
||||||
if (mNetworkListener != null) {
|
|
||||||
Log.v(LOG_TAG, "Removing network location listener.");
|
|
||||||
try {
|
|
||||||
mLocationManager.removeUpdates(mNetworkListener);
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
// catches permission problems
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
package org.y20k.trackbook.core;
|
package org.y20k.trackbook.core;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
import org.y20k.trackbook.helpers.LocationHelper;
|
import org.y20k.trackbook.helpers.LocationHelper;
|
||||||
import org.y20k.trackbook.helpers.LogHelper;
|
import org.y20k.trackbook.helpers.LogHelper;
|
||||||
|
@ -32,7 +32,7 @@ import java.util.List;
|
||||||
/**
|
/**
|
||||||
* Track class
|
* Track class
|
||||||
*/
|
*/
|
||||||
public class Track implements TrackbookKeys {
|
public class Track implements TrackbookKeys, Parcelable {
|
||||||
|
|
||||||
/* Define log tag */
|
/* Define log tag */
|
||||||
private static final String LOG_TAG = Track.class.getSimpleName();
|
private static final String LOG_TAG = Track.class.getSimpleName();
|
||||||
|
@ -41,33 +41,58 @@ public class Track implements TrackbookKeys {
|
||||||
/* Main class variables */
|
/* Main class variables */
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private List<WayPoint> mWayPoints;
|
private List<WayPoint> mWayPoints;
|
||||||
|
private float mTrackLength;
|
||||||
|
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
public Track(Context context) {
|
public Track() {
|
||||||
mContext = context;
|
|
||||||
mWayPoints = new ArrayList<WayPoint>();
|
mWayPoints = new ArrayList<WayPoint>();
|
||||||
|
mTrackLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Constructor used by CREATOR */
|
||||||
|
protected Track(Parcel in) {
|
||||||
|
mWayPoints = in.createTypedArrayList(WayPoint.CREATOR);
|
||||||
|
mTrackLength = in.readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CREATOR for Track object used to do parcel related operations */
|
||||||
|
public static final Creator<Track> CREATOR = new Creator<Track>() {
|
||||||
|
@Override
|
||||||
|
public Track createFromParcel(Parcel in) {
|
||||||
|
return new Track(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Track[] newArray(int size) {
|
||||||
|
return new Track[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Set mContext needed by */
|
||||||
|
public void setContext(Context context) {
|
||||||
|
mContext = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Adds new waypoint */
|
/* Adds new waypoint */
|
||||||
public void addWayPoint(Location location) {
|
public WayPoint addWayPoint(Location location) {
|
||||||
|
// add up distance
|
||||||
|
mTrackLength = addDistanceToTrack(location);
|
||||||
|
|
||||||
// create new waypoint
|
// create new waypoint
|
||||||
WayPoint wayPoint = new WayPoint();
|
WayPoint wayPoint = new WayPoint(location, LocationHelper.isStopOver(location), mTrackLength);
|
||||||
wayPoint.location = location;
|
|
||||||
wayPoint.isStopOver = LocationHelper.isStopOver(location);
|
|
||||||
|
|
||||||
// add new waypoint to track
|
// add new waypoint to track
|
||||||
mWayPoints.add(wayPoint);
|
mWayPoints.add(wayPoint);
|
||||||
|
|
||||||
// send local broadcast: new WayPoint added
|
// TODO remove log here
|
||||||
Intent i = new Intent();
|
LogHelper.v(LOG_TAG, "Waypoint No. " + mWayPoints.indexOf(wayPoint) + " Location: " + wayPoint.getLocation().toString());
|
||||||
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
|
return wayPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,23 +102,45 @@ public class Track implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter size of Track / number of WayPoints */
|
||||||
|
public int getSize() {
|
||||||
|
return mWayPoints.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getter for location of specific WayPoint */
|
/* Getter for location of specific WayPoint */
|
||||||
public Location getWayPointLocation(int index) {
|
public Location getWayPointLocation(int index) {
|
||||||
return mWayPoints.get(index).location;
|
return mWayPoints.get(index).getLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/* Adds distance to given location to length of track */
|
||||||
* Inner class: Defines data type WayPoint
|
private float addDistanceToTrack(Location location) {
|
||||||
*/
|
// get number of previously recorded waypoints
|
||||||
private class WayPoint {
|
int wayPointCount = mWayPoints.size();
|
||||||
|
|
||||||
private Location location;
|
|
||||||
private boolean isStopOver;
|
|
||||||
|
|
||||||
|
// at least two data points are needed
|
||||||
|
if (wayPointCount >= 2) {
|
||||||
|
// add up distance
|
||||||
|
Location lastLocation = mWayPoints.get(wayPointCount-2).getLocation();
|
||||||
|
mTrackLength = mTrackLength + lastLocation.distanceTo(location);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* End of inner class
|
return mTrackLength;
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
parcel.writeTypedList(mWayPoints);
|
||||||
|
parcel.writeFloat(mTrackLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
109
app/src/main/java/org/y20k/trackbook/core/WayPoint.java
Normal file
109
app/src/main/java/org/y20k/trackbook/core/WayPoint.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/**
|
||||||
|
* WayPoint.java
|
||||||
|
* Implements the WayPoint class
|
||||||
|
* A WayPoint stores a location plus additional metadata
|
||||||
|
*
|
||||||
|
* This file is part of
|
||||||
|
* TRACKBOOK - Movement Recorder for Android
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 - Y20K.org
|
||||||
|
* Licensed under the MIT-License
|
||||||
|
* http://opensource.org/licenses/MIT
|
||||||
|
*
|
||||||
|
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
|
||||||
|
* https://github.com/osmdroid/osmdroid
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.y20k.trackbook.core;
|
||||||
|
|
||||||
|
import android.location.Location;
|
||||||
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WayPoint class
|
||||||
|
*/
|
||||||
|
public class WayPoint implements Parcelable {
|
||||||
|
|
||||||
|
private Location mLocation;
|
||||||
|
private boolean mIsStopOver;
|
||||||
|
private float mDistanceToStartingPoint;
|
||||||
|
|
||||||
|
/* Constructor */
|
||||||
|
public WayPoint(Location location, boolean isStopOver, float distanceToStartingPoint) {
|
||||||
|
mLocation = location;
|
||||||
|
mIsStopOver = isStopOver;
|
||||||
|
mDistanceToStartingPoint = distanceToStartingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Constructor used by CREATOR */
|
||||||
|
protected WayPoint(Parcel in) {
|
||||||
|
mLocation = in.readParcelable(Location.class.getClassLoader());
|
||||||
|
mIsStopOver = in.readByte() != 0;
|
||||||
|
mDistanceToStartingPoint = in.readFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* CREATOR for WayPoint object used to do parcel related operations */
|
||||||
|
public static final Creator<WayPoint> CREATOR = new Creator<WayPoint>() {
|
||||||
|
@Override
|
||||||
|
public WayPoint createFromParcel(Parcel in) {
|
||||||
|
return new WayPoint(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WayPoint[] newArray(int size) {
|
||||||
|
return new WayPoint[size];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for mIsStopOver */
|
||||||
|
public Location getLocation() {
|
||||||
|
return mLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for mIsStopOver */
|
||||||
|
public boolean getIsStopOver() {
|
||||||
|
return mIsStopOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Getter for mDistanceToStartingPoint */
|
||||||
|
public float getDistanceToStartingPoint() {
|
||||||
|
return mDistanceToStartingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for mLocation */
|
||||||
|
public void setLocation(Location location) {
|
||||||
|
mLocation = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for mIsStopOver */
|
||||||
|
public void setIsStopOver(boolean isStopOver) {
|
||||||
|
mIsStopOver = isStopOver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Setter for mDistanceToStartingPoint */
|
||||||
|
public void setDistanceToStartingPoint(float distanceToStartingPoint) {
|
||||||
|
mDistanceToStartingPoint = distanceToStartingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int describeContents() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeToParcel(Parcel parcel, int i) {
|
||||||
|
parcel.writeParcelable(mLocation, i);
|
||||||
|
parcel.writeByte((byte) (mIsStopOver ? 1 : 0));
|
||||||
|
parcel.writeFloat(mDistanceToStartingPoint);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@
|
||||||
package org.y20k.trackbook.helpers;
|
package org.y20k.trackbook.helpers;
|
||||||
|
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
@ -147,7 +148,7 @@ public final class LocationHelper {
|
||||||
long timeDifference = newLocation.getElapsedRealtimeNanos() - lastWayPoint.getElapsedRealtimeNanos();
|
long timeDifference = newLocation.getElapsedRealtimeNanos() - lastWayPoint.getElapsedRealtimeNanos();
|
||||||
|
|
||||||
// distance is bigger than 10 meters and time difference bigger than 20 seconds
|
// distance is bigger than 10 meters and time difference bigger than 20 seconds
|
||||||
return distance > 10 && timeDifference > TWENTY_SECONDS;
|
return distance > 10 && timeDifference >= TWENTY_SECONDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,6 +159,69 @@ public final class LocationHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Registers gps and network location listeners */
|
||||||
|
public static void registerLocationListeners(LocationManager locationManager, LocationListener gpsListener, LocationListener networkListener) {
|
||||||
|
LogHelper.v(LOG_TAG, "Registering location listeners.");
|
||||||
|
|
||||||
|
// get location providers
|
||||||
|
List locationProviders = locationManager.getProviders(true);
|
||||||
|
|
||||||
|
// got GPS location provider?
|
||||||
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER) && gpsListener != null) {
|
||||||
|
try {
|
||||||
|
// register GPS location listener and request updates
|
||||||
|
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// catches permission problems
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// got network location provider?
|
||||||
|
if (locationProviders.contains(LocationManager.NETWORK_PROVIDER) && networkListener != null) {
|
||||||
|
try {
|
||||||
|
// register network location listener and request updates
|
||||||
|
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// catches permission problems
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Removes gps and network location listeners */
|
||||||
|
public static void removeLocationListeners(LocationManager locationManager, LocationListener gpsListener, LocationListener networkListener) {
|
||||||
|
LogHelper.v(LOG_TAG, "Removing location listeners.");
|
||||||
|
|
||||||
|
// get location providers
|
||||||
|
List locationProviders = locationManager.getProviders(true);
|
||||||
|
|
||||||
|
// got GPS location provider?
|
||||||
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER) && gpsListener != null) {
|
||||||
|
try {
|
||||||
|
// remove GPS listener
|
||||||
|
locationManager.removeUpdates(gpsListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// catches permission problems
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// got network location provider?
|
||||||
|
if (locationProviders.contains(LocationManager.NETWORK_PROVIDER) && networkListener != null) {
|
||||||
|
try {
|
||||||
|
// remove network listener
|
||||||
|
locationManager.removeUpdates(networkListener);
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
// catches permission problems
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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
|
||||||
|
|
|
@ -20,13 +20,17 @@ import android.content.Context;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.support.v7.widget.AppCompatDrawableManager;
|
import android.support.v7.widget.AppCompatDrawableManager;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
|
||||||
import org.osmdroid.util.GeoPoint;
|
import org.osmdroid.util.GeoPoint;
|
||||||
import org.osmdroid.views.overlay.ItemizedIconOverlay;
|
import org.osmdroid.views.overlay.ItemizedIconOverlay;
|
||||||
import org.osmdroid.views.overlay.OverlayItem;
|
import org.osmdroid.views.overlay.OverlayItem;
|
||||||
import org.y20k.trackbook.R;
|
import org.y20k.trackbook.R;
|
||||||
|
import org.y20k.trackbook.core.Track;
|
||||||
|
import org.y20k.trackbook.core.WayPoint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,25 +43,29 @@ public final class MapHelper {
|
||||||
|
|
||||||
|
|
||||||
/* Creates icon overlay for current position */
|
/* Creates icon overlay for current position */
|
||||||
public static ItemizedIconOverlay createMyLocationOverlay(Context context, Location currentBestLocation, boolean locationIsNew) {
|
public static ItemizedIconOverlay createMyLocationOverlay(Context context, Location currentBestLocation, boolean locationIsNew, boolean trackingStarted) {
|
||||||
|
|
||||||
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
|
LogHelper.v(LOG_TAG, "Location is new? " + locationIsNew + " Provider: " + currentBestLocation.getProvider()); // TODO remove
|
||||||
|
|
||||||
// create marker
|
// create marker
|
||||||
Drawable newMarker;
|
Drawable newMarker;
|
||||||
if (locationIsNew) {
|
if (trackingStarted) {
|
||||||
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_red_24dp);
|
||||||
|
} else if (locationIsNew) {
|
||||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_blue_24dp);
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_blue_24dp);
|
||||||
} else {
|
} else {
|
||||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_grey_24dp);
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_grey_24dp);
|
||||||
}
|
}
|
||||||
|
final GeoPoint position = new GeoPoint(currentBestLocation.getLatitude(), currentBestLocation.getLongitude());
|
||||||
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);
|
||||||
|
|
||||||
|
// add marker to list of overlay items
|
||||||
overlayItems.add(overlayItem);
|
overlayItems.add(overlayItem);
|
||||||
|
|
||||||
// create overlay
|
// create and return overlay for current position
|
||||||
ItemizedIconOverlay myLocationOverlay = new ItemizedIconOverlay<>(overlayItems,
|
return new ItemizedIconOverlay<>(overlayItems,
|
||||||
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
|
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
|
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
|
||||||
|
@ -71,9 +79,52 @@ public final class MapHelper {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}, context);
|
}, context);
|
||||||
|
|
||||||
// return overlay for current position
|
|
||||||
return myLocationOverlay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Creates icon overlay for track */
|
||||||
|
public static ItemizedIconOverlay createTrackOverlay(Context context, Track track){
|
||||||
|
|
||||||
|
final List<WayPoint> wayPoints = track.getWayPoints();
|
||||||
|
final ArrayList<OverlayItem> overlayItems = new ArrayList<>();
|
||||||
|
|
||||||
|
for (WayPoint wayPoint : wayPoints) {
|
||||||
|
// create marker
|
||||||
|
Drawable newMarker;
|
||||||
|
if (wayPoint.getIsStopOver()) {
|
||||||
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_blue_24dp);
|
||||||
|
} else {
|
||||||
|
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_blue_24dp);
|
||||||
|
}
|
||||||
|
final String title = Float.toString(wayPoint.getDistanceToStartingPoint());
|
||||||
|
final String description = DateFormat.getDateFormat(context).format(wayPoint.getLocation().getTime());
|
||||||
|
final GeoPoint position = new GeoPoint(wayPoint.getLocation().getLatitude(), wayPoint.getLocation().getLongitude());
|
||||||
|
OverlayItem overlayItem = new OverlayItem(title, description, position);
|
||||||
|
overlayItem.setMarker(newMarker);
|
||||||
|
|
||||||
|
// add marker to list of overlay items
|
||||||
|
overlayItems.add(overlayItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return overlay for current position
|
||||||
|
return new ItemizedIconOverlay<>(overlayItems,
|
||||||
|
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
|
||||||
|
@Override
|
||||||
|
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
|
||||||
|
LogHelper.v(LOG_TAG, "Tap on a track crumb icon detected. Measured distance: " + item.getTitle());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onItemLongPress(final int index, final OverlayItem item) {
|
||||||
|
LogHelper.v(LOG_TAG, "Long press on a track crumb icon detected. Timestamp: " + item.getSnippet());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -25,11 +25,10 @@ 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";
|
public static final String ACTION_TRACK_UPDATED = "TRACK_UPDATED";
|
||||||
|
|
||||||
/* EXTRAS */
|
/* EXTRAS */
|
||||||
public static final String EXTRA_WAYPOINT_LOCATION = "WAYPOINT_LOCATION";
|
public static final String EXTRA_TRACK = "TRACK";
|
||||||
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";
|
||||||
|
@ -50,13 +49,14 @@ public interface TrackbookKeys {
|
||||||
public static final String INSTANCE_ZOOM_LEVEL = "zoomLevel";
|
public static final String INSTANCE_ZOOM_LEVEL = "zoomLevel";
|
||||||
public static final String INSTANCE_CURRENT_LOCATION = "currentLocation";
|
public static final String INSTANCE_CURRENT_LOCATION = "currentLocation";
|
||||||
public static final String INSTANCE_TRACKING_STARTED = "trackingStarted";
|
public static final String INSTANCE_TRACKING_STARTED = "trackingStarted";
|
||||||
|
public static final String INSTANCE_TRACK = "track";
|
||||||
|
|
||||||
/* RESULTS */
|
/* RESULTS */
|
||||||
|
|
||||||
/* CONSTANTS */
|
/* CONSTANTS */
|
||||||
public static final int CONSTANT_MINIMAL_STOP_TIME = 300000; // equals 5 minutes
|
public static final int CONSTANT_MINIMAL_STOP_TIME = 300000; // equals 5 minutes
|
||||||
public static final long CONSTANT_MAXIMAL_DURATION = 43200000; // equals 8 hours
|
public static final long CONSTANT_MAXIMAL_DURATION = 43200000; // equals 8 hours
|
||||||
public static final long CONSTANT_TRACKING_INTERVAL = 5000; // equals 5 seconds
|
public static final long CONSTANT_TRACKING_INTERVAL = 15000; // equals 15 seconds
|
||||||
|
|
||||||
/* MISC */
|
/* MISC */
|
||||||
public static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
|
public static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/fragment"
|
android:id="@+id/content_main"
|
||||||
android:name="org.y20k.trackbook.MainActivityFragment"
|
android:name="org.y20k.trackbook.MainActivityFragment"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/fragment_main"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
|
|
Loading…
Reference in a new issue