From 63d82be36c1665b7a92981463e749b869a61a628 Mon Sep 17 00:00:00 2001 From: y20k Date: Fri, 30 Sep 2016 17:32:54 +0200 Subject: [PATCH] display a previously saved track in the last tracks tab (see #2) (work in progress) --- app/build.gradle | 2 +- .../java/org/y20k/trackbook/MainActivity.java | 40 ++++- .../trackbook/MainActivityMapFragment.java | 34 ++--- .../trackbook/MainActivityTrackFragment.java | 141 ++++++++++++++++-- .../org/y20k/trackbook/helpers/MapHelper.java | 4 +- .../y20k/trackbook/helpers/TrackbookKeys.java | 16 +- .../main/res/layout/fragment_main_track.xml | 2 +- app/src/main/res/values/colors.xml | 1 + 8 files changed, 192 insertions(+), 48 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1bd011c..ff8f9d9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 24 - buildToolsVersion "24.0.1" + buildToolsVersion "24.0.3" defaultConfig { applicationId "org.y20k.trackbook" diff --git a/app/src/main/java/org/y20k/trackbook/MainActivity.java b/app/src/main/java/org/y20k/trackbook/MainActivity.java index 325e049..f8b031d 100644 --- a/app/src/main/java/org/y20k/trackbook/MainActivity.java +++ b/app/src/main/java/org/y20k/trackbook/MainActivity.java @@ -72,16 +72,18 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di private FloatingActionButton mFloatingActionButton; private MainActivityMapFragment mMainActivityMapFragment; private BroadcastReceiver mTrackingStoppedReceiver; + private int mSelectedTab; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // set state of tracking + // get state of tracking and get selected tab mTrackerServiceRunning = false; if (savedInstanceState != null) { mTrackerServiceRunning = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false); + mSelectedTab = savedInstanceState.getInt(INSTANCE_SELECTED_TAB, 0); } // check permissions on Android 6 and higher @@ -144,6 +146,7 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di @Override protected void onSaveInstanceState(Bundle outState) { outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning); + outState.putInt(INSTANCE_SELECTED_TAB, mSelectedTab); super.onSaveInstanceState(outState); } @@ -301,11 +304,38 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. - ViewPager viewPager = (ViewPager) findViewById(R.id.container); - viewPager.setAdapter(sectionsPagerAdapter); + ViewPager mViewPager = (ViewPager) findViewById(R.id.container); + mViewPager.setAdapter(sectionsPagerAdapter); + mViewPager.setCurrentItem(mSelectedTab); TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); - tabLayout.setupWithViewPager(viewPager); + tabLayout.setupWithViewPager(mViewPager); + tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { + @Override + public void onTabSelected(TabLayout.Tab tab) { + switch (tab.getPosition()) { + case 0: + mFloatingActionButton.show(); + break; + case 1: + mFloatingActionButton.hide(); + break; + default: + mFloatingActionButton.show(); + break; + } + } + + @Override + public void onTabUnselected(TabLayout.Tab tab) { + + } + + @Override + public void onTabReselected(TabLayout.Tab tab) { + + } + }); /* END NEW STUFF */ // get reference to fragment @@ -479,7 +509,6 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di } - /** * Inner class: SectionsPagerAdapter that returns a fragment corresponding to one of the tabs. * see also: https://developer.android.com/reference/android/support/v4/app/FragmentPagerAdapter.html @@ -526,6 +555,7 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys, Di } return null; } + } /** * End of inner class diff --git a/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java b/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java index f17c9ca..2050f92 100644 --- a/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java +++ b/app/src/main/java/org/y20k/trackbook/MainActivityMapFragment.java @@ -168,12 +168,17 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { // add multi-touch capability mMapView.setMultiTouchControls(true); + // add compass to map + CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView); + compassOverlay.enableCompass(); + mMapView.getOverlays().add(compassOverlay); + // initiate map state if (savedInstanceState != null) { // restore saved instance of map - GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE, DEFAULT_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE, DEFAULT_LONGITUDE)); + GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE_MAIN_MAP, DEFAULT_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE_MAIN_MAP, DEFAULT_LONGITUDE)); mController.setCenter(position); - mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL, 16)); + mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL_MAIN_MAP, 16)); // restore current location mCurrentBestLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION); } else if (mCurrentBestLocation != null) { @@ -191,17 +196,12 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { // restore track if (savedInstanceState != null) { - mTrack = savedInstanceState.getParcelable(INSTANCE_TRACK); + mTrack = savedInstanceState.getParcelable(INSTANCE_TRACK_MAIN_MAP); } if (mTrack != null) { drawTrackOverlay(mTrack); } - // add compass to map - CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView); - compassOverlay.enableCompass(); - mMapView.getOverlays().add(compassOverlay); - // mark user's location on map if (mCurrentBestLocation != null && !mTrackerServiceRunning) { mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation)); @@ -297,12 +297,15 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { // get current position GeoPoint position; - if (mCurrentBestLocation == null) { + + if (mTrackerServiceRunning) { + // get current Location from tracker service + mCurrentBestLocation = mTrack.getWayPointLocation(mTrack.getSize()); + } else if (mCurrentBestLocation == null) { // app does not have any location fix mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager); } - // check if really got a position if (mCurrentBestLocation != null) { position = convertToGeoPoint(mCurrentBestLocation); @@ -328,9 +331,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { return false; } - - - // CASE DEFAULT default: return super.onOptionsItemSelected(item); @@ -341,12 +341,12 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys { @Override public void onSaveInstanceState(Bundle outState) { outState.putBoolean(INSTANCE_FIRST_START, mFirstStart); - outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude()); - outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude()); - outState.putInt(INSTANCE_ZOOM_LEVEL, mMapView.getZoomLevel()); outState.putParcelable(INSTANCE_CURRENT_LOCATION, mCurrentBestLocation); - outState.putParcelable(INSTANCE_TRACK, mTrack); outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning); + outState.putDouble(INSTANCE_LATITUDE_MAIN_MAP, mMapView.getMapCenter().getLatitude()); + outState.putDouble(INSTANCE_LONGITUDE_MAIN_MAP, mMapView.getMapCenter().getLongitude()); + outState.putInt(INSTANCE_ZOOM_LEVEL_MAIN_MAP, mMapView.getZoomLevel()); + outState.putParcelable(INSTANCE_TRACK_MAIN_MAP, mTrack); super.onSaveInstanceState(outState); } diff --git a/app/src/main/java/org/y20k/trackbook/MainActivityTrackFragment.java b/app/src/main/java/org/y20k/trackbook/MainActivityTrackFragment.java index b2e0658..9b959bd 100644 --- a/app/src/main/java/org/y20k/trackbook/MainActivityTrackFragment.java +++ b/app/src/main/java/org/y20k/trackbook/MainActivityTrackFragment.java @@ -17,6 +17,8 @@ package org.y20k.trackbook; import android.app.Activity; +import android.location.Location; +import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.BottomSheetBehavior; @@ -26,14 +28,24 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import org.osmdroid.api.IMapController; +import org.osmdroid.tileprovider.tilesource.TileSourceFactory; +import org.osmdroid.util.GeoPoint; +import org.osmdroid.views.MapView; +import org.osmdroid.views.overlay.ItemizedIconOverlay; +import org.osmdroid.views.overlay.compass.CompassOverlay; +import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider; import org.y20k.trackbook.core.Track; +import org.y20k.trackbook.helpers.LogHelper; +import org.y20k.trackbook.helpers.MapHelper; import org.y20k.trackbook.helpers.StorageHelper; +import org.y20k.trackbook.helpers.TrackbookKeys; /** * MainActivityTrackFragment class */ -public class MainActivityTrackFragment extends Fragment { +public class MainActivityTrackFragment extends Fragment implements TrackbookKeys { /* Define log tag */ private static final String LOG_TAG = MainActivityTrackFragment.class.getSimpleName(); @@ -42,6 +54,9 @@ public class MainActivityTrackFragment extends Fragment { /* Main class variables */ private Activity mActivity; private View mRootView; + private MapView mMapView; + private IMapController mController; + private ItemizedIconOverlay mTrackOverlay; private TextView mDistanceView; private TextView mStepsView; private TextView mWaypointsView; @@ -73,6 +88,35 @@ public class MainActivityTrackFragment extends Fragment { // inflate root view from xml mRootView = inflater.inflate(R.layout.fragment_main_track, container, false); + // create basic map + mMapView = (MapView) mRootView.findViewById(R.id.track_map); + + // get map controller + mController = mMapView.getController(); + + // basic map setup + mMapView.setTileSource(TileSourceFactory.MAPNIK); + mMapView.setTilesScaledToDpi(true); + + // add multi-touch capability + mMapView.setMultiTouchControls(true); + + // add compass to map + CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView); + compassOverlay.enableCompass(); + mMapView.getOverlays().add(compassOverlay); + + // initiate map state + if (savedInstanceState != null) { + // restore saved instance of map + GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE_TRACK_MAP, DEFAULT_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE_TRACK_MAP, DEFAULT_LONGITUDE)); + mController.setCenter(position); + mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL_MAIN_MAP, 16)); + } else { + mController.setZoom(16); + } + + // get views mDistanceView = (TextView) mRootView.findViewById(R.id.statistics_data_distance); mStepsView = (TextView) mRootView.findViewById(R.id.statistics_data_steps); @@ -91,37 +135,102 @@ public class MainActivityTrackFragment extends Fragment { @Override public void onResume() { super.onResume(); + LogHelper.v(LOG_TAG, "TrackFragment: onResume called."); - // get most current track from storage - StorageHelper storageHelper = new StorageHelper(mActivity); - mTrack = storageHelper.loadTrack(storageHelper.getMostCurrentTrack()); - - // populate views - if (mTrack != null) { - mDistanceView.setText(mTrack.getTrackDistance()); - mStepsView.setText(String.valueOf(mTrack.getStepCount())); - mWaypointsView.setText(String.valueOf(mTrack.getWayPoints().size())); - mDurationView.setText(mTrack.getTrackDuration()); - mRecordingStartView.setText(mTrack.getRecordingStart().toString()); - mRecordingStopView.setText(mTrack.getRecordingStop().toString()); - } + // load track and display map and statistics + LoadTrackAsyncHelper loadTrackAsyncHelper = new LoadTrackAsyncHelper(); + loadTrackAsyncHelper.execute(); mStatisticsSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); - } @Override public void onPause() { super.onPause(); + LogHelper.v(LOG_TAG, "TrackFragment: onPause called."); } @Override - public void onDestroyView() { + public void onDestroyView(){ super.onDestroyView(); + + // deactivate map + mMapView.onDetach(); } + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putDouble(INSTANCE_LATITUDE_TRACK_MAP, mMapView.getMapCenter().getLatitude()); + outState.putDouble(INSTANCE_LONGITUDE_TRACK_MAP, mMapView.getMapCenter().getLongitude()); + outState.putInt(INSTANCE_ZOOM_LEVEL_TRACK_MAP, mMapView.getZoomLevel()); + outState.putParcelable(INSTANCE_TRACK_TRACK_MAP, mTrack); + super.onSaveInstanceState(outState); + } + + + /* Displays map and statistics for track */ + private void displayTrack() { + GeoPoint position; + + if (mTrack != null) { + // set end of track as position + Location lastLocation = mTrack.getWayPointLocation(mTrack.getSize() -1); + position = new GeoPoint(lastLocation.getLatitude(), lastLocation.getLongitude()); + + // populate views + mDistanceView.setText(mTrack.getTrackDistance()); + mStepsView.setText(String.valueOf(Math.round(mTrack.getStepCount()))); + mWaypointsView.setText(String.valueOf(mTrack.getWayPoints().size())); + mDurationView.setText(mTrack.getTrackDuration()); + mRecordingStartView.setText(mTrack.getRecordingStart().toString()); + mRecordingStopView.setText(mTrack.getRecordingStop().toString()); + + // draw track on map + drawTrackOverlay(mTrack); + } else { + position = new GeoPoint(DEFAULT_LATITUDE, DEFAULT_LONGITUDE); + } + + // center map over position + mController.setCenter(position); + + + + } + + + /* Draws track onto overlay */ + private void drawTrackOverlay(Track track) { + mMapView.getOverlays().remove(mTrackOverlay); + mTrackOverlay = MapHelper.createTrackOverlay(mActivity, track, false); + mMapView.getOverlays().add(mTrackOverlay); + } + + /** + * Inner class: Loads track from external storage using AsyncTask + */ + private class LoadTrackAsyncHelper extends AsyncTask { + + @Override + protected Void doInBackground(Void... voids) { + LogHelper.v(LOG_TAG, "Loading track object in background."); + // save track object + StorageHelper storageHelper = new StorageHelper(mActivity); + mTrack = storageHelper.loadTrack(storageHelper.getMostCurrentTrack()); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + // clear track object + LogHelper.v(LOG_TAG, "Display map and statistics of track."); + displayTrack(); + } + } + } \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/helpers/MapHelper.java b/app/src/main/java/org/y20k/trackbook/helpers/MapHelper.java index 08df5a2..b1f14ac 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/MapHelper.java +++ b/app/src/main/java/org/y20k/trackbook/helpers/MapHelper.java @@ -150,13 +150,13 @@ public final class MapHelper { @Override public boolean onItemSingleTapUp(final int index, final OverlayItem item) { Toast.makeText(context, item.getTitle() + " | " + item.getSnippet(), Toast.LENGTH_LONG).show(); - LogHelper.v(LOG_TAG, "Tap on a track crumb icon detected. Measured distance: " + item.getTitle()); + LogHelper.v(LOG_TAG, "Tap on waypoint. " + 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()); + LogHelper.v(LOG_TAG, "Long press on waypoint. " + item.getSnippet()); return true; } diff --git a/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java b/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java index 9809708..ce4b2fd 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java +++ b/app/src/main/java/org/y20k/trackbook/helpers/TrackbookKeys.java @@ -57,12 +57,17 @@ public interface TrackbookKeys { /* INSTANCE STATE */ String INSTANCE_FIRST_START = "firstStart"; - String INSTANCE_LATITUDE = "latitude"; - String INSTANCE_LONGITUDE = "longitude"; - String INSTANCE_ZOOM_LEVEL = "zoomLevel"; - String INSTANCE_CURRENT_LOCATION = "currentLocation"; String INSTANCE_TRACKING_STATE = "trackingState"; - String INSTANCE_TRACK = "track"; + String INSTANCE_SELECTED_TAB = "selectedTab"; + String INSTANCE_TRACK_MAIN_MAP = "trackMainMap"; + String INSTANCE_LATITUDE_MAIN_MAP = "latitudeMainMap"; + String INSTANCE_LONGITUDE_MAIN_MAP = "longitudeMainMap"; + String INSTANCE_ZOOM_LEVEL_MAIN_MAP = "zoomLevelMainMap"; + String INSTANCE_TRACK_TRACK_MAP = "trackTrackMap"; + String INSTANCE_LATITUDE_TRACK_MAP = "latitudeTrackMap"; + String INSTANCE_LONGITUDE_TRACK_MAP = "longitudeTrackMap"; + String INSTANCE_ZOOM_LEVEL_TRACK_MAP = "zoomLevelTrackMap"; + String INSTANCE_CURRENT_LOCATION = "currentLocation"; /* RESULTS */ @@ -73,7 +78,6 @@ public interface TrackbookKeys { long FIVE_MINUTES_IN_NANOSECONDS = 5L * 60000000000L; // determines a stop over long TWO_MINUTES_IN_NANOSECONDS = 2L * 60000000000L; // defines an old location - /* MISC */ int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124; int TRACKER_SERVICE_NOTIFICATION_ID = 1; diff --git a/app/src/main/res/layout/fragment_main_track.xml b/app/src/main/res/layout/fragment_main_track.xml index e296a98..4e2f26f 100644 --- a/app/src/main/res/layout/fragment_main_track.xml +++ b/app/src/main/res/layout/fragment_main_track.xml @@ -21,7 +21,7 @@ android:layout_width="match_parent" android:layout_height="350dp" android:clipToPadding="true" - android:background="@color/trackbook_grey" + android:background="@color/trackbook_grey_85percent" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> #FF607d8b #FF455a64 + #D9455a64