2016-08-29 12:50:41 +00:00
|
|
|
/**
|
2016-09-16 15:45:10 +00:00
|
|
|
* MainActivityMapFragment.java
|
2016-09-20 11:51:17 +00:00
|
|
|
* Implements the map fragment used in the map tab of the main activity
|
2016-08-29 12:50:41 +00:00
|
|
|
* This fragment displays a map using osmdroid
|
|
|
|
*
|
|
|
|
* This file is part of
|
|
|
|
* TRACKBOOK - Movement Recorder for Android
|
|
|
|
*
|
2017-01-19 12:36:49 +00:00
|
|
|
* Copyright (c) 2016-17 - Y20K.org
|
2016-08-29 12:50:41 +00:00
|
|
|
* 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;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
2016-08-30 13:22:19 +00:00
|
|
|
import android.content.BroadcastReceiver;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.content.Context;
|
2016-08-30 13:22:19 +00:00
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.IntentFilter;
|
2017-01-11 20:52:45 +00:00
|
|
|
import android.content.SharedPreferences;
|
2016-09-19 16:46:25 +00:00
|
|
|
import android.database.ContentObserver;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.location.Location;
|
|
|
|
import android.location.LocationListener;
|
|
|
|
import android.location.LocationManager;
|
2016-09-27 15:02:23 +00:00
|
|
|
import android.os.AsyncTask;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.os.Bundle;
|
2016-09-19 16:46:25 +00:00
|
|
|
import android.os.Handler;
|
2016-09-09 20:28:12 +00:00
|
|
|
import android.os.SystemClock;
|
2017-01-11 20:52:45 +00:00
|
|
|
import android.preference.PreferenceManager;
|
2016-09-19 16:46:25 +00:00
|
|
|
import android.support.design.widget.Snackbar;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.support.v4.app.Fragment;
|
2016-08-30 13:22:19 +00:00
|
|
|
import android.support.v4.content.LocalBroadcastManager;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.MenuItem;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
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;
|
2016-09-01 11:45:46 +00:00
|
|
|
import org.y20k.trackbook.core.Track;
|
2016-08-29 12:50:41 +00:00
|
|
|
import org.y20k.trackbook.helpers.LocationHelper;
|
|
|
|
import org.y20k.trackbook.helpers.LogHelper;
|
|
|
|
import org.y20k.trackbook.helpers.MapHelper;
|
2016-09-27 14:50:37 +00:00
|
|
|
import org.y20k.trackbook.helpers.StorageHelper;
|
2016-08-29 12:50:41 +00:00
|
|
|
import org.y20k.trackbook.helpers.TrackbookKeys;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2016-09-16 15:45:10 +00:00
|
|
|
* MainActivityMapFragment class
|
2016-08-29 12:50:41 +00:00
|
|
|
*/
|
2016-09-16 15:45:10 +00:00
|
|
|
public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
/* Define log tag */
|
2016-09-16 15:45:10 +00:00
|
|
|
private static final String LOG_TAG = MainActivityMapFragment.class.getSimpleName();
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Main class variables */
|
|
|
|
private Activity mActivity;
|
2016-09-01 11:45:46 +00:00
|
|
|
private Track mTrack;
|
2016-08-30 13:22:19 +00:00
|
|
|
private boolean mFirstStart;
|
2016-09-19 16:46:25 +00:00
|
|
|
private Snackbar mLocationOffBar;
|
2016-09-01 11:45:46 +00:00
|
|
|
private BroadcastReceiver mTrackUpdatedReceiver;
|
2016-09-19 16:46:25 +00:00
|
|
|
private SettingsContentObserver mSettingsContentObserver;
|
2016-08-29 12:50:41 +00:00
|
|
|
private MapView mMapView;
|
|
|
|
private IMapController mController;
|
2017-01-19 12:36:49 +00:00
|
|
|
private StorageHelper mStorageHelper;
|
2016-08-29 12:50:41 +00:00
|
|
|
private LocationManager mLocationManager;
|
|
|
|
private LocationListener mGPSListener;
|
|
|
|
private LocationListener mNetworkListener;
|
|
|
|
private ItemizedIconOverlay mMyLocationOverlay;
|
2016-09-01 11:45:46 +00:00
|
|
|
private ItemizedIconOverlay mTrackOverlay;
|
2016-08-29 19:43:49 +00:00
|
|
|
private Location mCurrentBestLocation;
|
2016-09-06 15:27:04 +00:00
|
|
|
private boolean mTrackerServiceRunning;
|
|
|
|
private boolean mLocalTrackerRunning;
|
2016-09-19 16:46:25 +00:00
|
|
|
private boolean mLocationSystemSetting;
|
2016-09-12 12:31:37 +00:00
|
|
|
private boolean mFragmentVisible;
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Constructor (default) */
|
2016-09-16 15:45:10 +00:00
|
|
|
public MainActivityMapFragment() {
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
|
|
|
// get activity
|
|
|
|
mActivity = getActivity();
|
|
|
|
|
|
|
|
// action bar has options menu
|
|
|
|
setHasOptionsMenu(true);
|
|
|
|
|
2016-12-16 21:12:43 +00:00
|
|
|
// restore first start state and tracking state
|
2016-08-30 13:22:19 +00:00
|
|
|
mFirstStart = true;
|
2016-09-06 15:27:04 +00:00
|
|
|
mTrackerServiceRunning = false;
|
2017-01-11 20:52:45 +00:00
|
|
|
loadTrackerServiceState(mActivity);
|
2016-09-01 11:45:46 +00:00
|
|
|
if (savedInstanceState != null) {
|
2016-12-16 21:12:43 +00:00
|
|
|
mFirstStart = savedInstanceState.getBoolean(INSTANCE_FIRST_START, true);
|
2016-09-01 11:45:46 +00:00
|
|
|
}
|
|
|
|
|
2017-01-19 12:36:49 +00:00
|
|
|
// create storage helper
|
|
|
|
mStorageHelper = new StorageHelper(mActivity);
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// acquire reference to Location Manager
|
|
|
|
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
|
|
|
|
2016-08-29 19:43:49 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2016-09-19 16:46:25 +00:00
|
|
|
// CASE 3: location services are available but unable to get location - this should not happen
|
|
|
|
if (mCurrentBestLocation == null) {
|
|
|
|
mCurrentBestLocation = new Location(LocationManager.NETWORK_PROVIDER);
|
|
|
|
mCurrentBestLocation.setLatitude(DEFAULT_LATITUDE);
|
|
|
|
mCurrentBestLocation.setLongitude(DEFAULT_LONGITUDE);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get state of location system setting
|
|
|
|
mLocationSystemSetting = LocationHelper.checkLocationSystemSetting(mActivity);
|
|
|
|
|
|
|
|
// create content observer for changes in System Settings
|
|
|
|
mSettingsContentObserver = new SettingsContentObserver( new Handler());
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
// register broadcast receiver for new WayPoints
|
|
|
|
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
|
|
|
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
|
|
|
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
|
|
|
// create basic map
|
|
|
|
mMapView = new MapView(inflater.getContext());
|
|
|
|
|
|
|
|
// get map controller
|
|
|
|
mController = mMapView.getController();
|
|
|
|
|
|
|
|
// basic map setup
|
|
|
|
mMapView.setTileSource(TileSourceFactory.MAPNIK);
|
|
|
|
mMapView.setTilesScaledToDpi(true);
|
|
|
|
|
|
|
|
// add multi-touch capability
|
|
|
|
mMapView.setMultiTouchControls(true);
|
|
|
|
|
2016-09-30 15:32:54 +00:00
|
|
|
// add compass to map
|
|
|
|
CompassOverlay compassOverlay = new CompassOverlay(mActivity, new InternalCompassOrientationProvider(mActivity), mMapView);
|
|
|
|
compassOverlay.enableCompass();
|
|
|
|
mMapView.getOverlays().add(compassOverlay);
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// initiate map state
|
|
|
|
if (savedInstanceState != null) {
|
|
|
|
// restore saved instance of map
|
2016-09-30 15:32:54 +00:00
|
|
|
GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE_MAIN_MAP, DEFAULT_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE_MAIN_MAP, DEFAULT_LONGITUDE));
|
2016-08-29 12:50:41 +00:00
|
|
|
mController.setCenter(position);
|
2016-09-30 15:32:54 +00:00
|
|
|
mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL_MAIN_MAP, 16));
|
2016-08-29 12:50:41 +00:00
|
|
|
// restore current location
|
|
|
|
mCurrentBestLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
|
|
|
} else if (mCurrentBestLocation != null) {
|
|
|
|
// fallback or first run: set map to current position
|
2016-09-06 15:27:04 +00:00
|
|
|
GeoPoint position = convertToGeoPoint(mCurrentBestLocation);
|
2016-08-29 12:50:41 +00:00
|
|
|
mController.setCenter(position);
|
|
|
|
mController.setZoom(16);
|
|
|
|
}
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
// inform user that new/better location is on its way
|
|
|
|
if (mFirstStart && !mTrackerServiceRunning) {
|
|
|
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_acquiring_location), Toast.LENGTH_LONG).show();
|
|
|
|
mFirstStart = false;
|
|
|
|
}
|
|
|
|
|
2017-01-19 12:36:49 +00:00
|
|
|
// load track from saved instance
|
|
|
|
if (savedInstanceState != null) {
|
2016-09-30 15:32:54 +00:00
|
|
|
mTrack = savedInstanceState.getParcelable(INSTANCE_TRACK_MAIN_MAP);
|
2016-09-01 11:45:46 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// mark user's location on map
|
2016-09-06 15:27:04 +00:00
|
|
|
if (mCurrentBestLocation != null && !mTrackerServiceRunning) {
|
|
|
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
2016-08-29 12:50:41 +00:00
|
|
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
|
|
|
}
|
|
|
|
|
|
|
|
return mMapView;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onResume() {
|
|
|
|
super.onResume();
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
// set visibility
|
|
|
|
mFragmentVisible = true;
|
|
|
|
|
2017-01-11 20:52:45 +00:00
|
|
|
// load state of tracker service - see if anything changed
|
|
|
|
loadTrackerServiceState(mActivity);
|
2016-12-16 21:12:43 +00:00
|
|
|
|
2017-01-19 12:36:49 +00:00
|
|
|
// CASE 1: recording active
|
2016-09-06 15:27:04 +00:00
|
|
|
if (mTrackerServiceRunning) {
|
2017-01-19 12:36:49 +00:00
|
|
|
// request an updated track recording from service
|
2017-01-17 15:27:43 +00:00
|
|
|
Intent i = new Intent();
|
|
|
|
i.setAction(ACTION_TRACK_REQUEST);
|
|
|
|
LocalBroadcastManager.getInstance(mActivity).sendBroadcast(i);
|
2016-09-06 15:27:04 +00:00
|
|
|
}
|
|
|
|
|
2017-01-19 12:36:49 +00:00
|
|
|
// CASE 2: recording stopped - temp file exists
|
|
|
|
else if (mStorageHelper.tempFileExists()) {
|
|
|
|
// load track from temp file if it exists
|
|
|
|
LoadTempTrackAsyncHelper loadTempTrackAsyncHelper = new LoadTempTrackAsyncHelper();
|
|
|
|
loadTempTrackAsyncHelper.execute();
|
|
|
|
|
|
|
|
// CASE 3: not recording and no temp file
|
|
|
|
} else if (mTrack != null) {
|
2017-01-25 13:19:50 +00:00
|
|
|
// just draw existing track data (from saved instance)
|
2016-09-06 15:27:04 +00:00
|
|
|
drawTrackOverlay(mTrack);
|
|
|
|
}
|
|
|
|
|
2016-09-19 16:46:25 +00:00
|
|
|
// show/hide the location off notification bar
|
|
|
|
toggleLocationOffBar();
|
|
|
|
|
2017-01-25 13:19:50 +00:00
|
|
|
// start preliminary tracking - if no TrackerService is running
|
2016-09-19 16:46:25 +00:00
|
|
|
if (!mTrackerServiceRunning && mFragmentVisible) {
|
|
|
|
startPreliminaryTracking();
|
|
|
|
}
|
|
|
|
|
|
|
|
// register content observer for changes in System Settings
|
|
|
|
mActivity.getContentResolver().registerContentObserver(android.provider.Settings.Secure.CONTENT_URI, true, mSettingsContentObserver );
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onPause() {
|
|
|
|
super.onPause();
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
// set visibility
|
|
|
|
mFragmentVisible = false;
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
// disable preliminary location listeners
|
|
|
|
stopPreliminaryTracking();
|
2016-09-19 16:46:25 +00:00
|
|
|
|
|
|
|
// disable content observer for changes in System Settings
|
|
|
|
mActivity.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroyView(){
|
|
|
|
super.onDestroyView();
|
|
|
|
|
|
|
|
// deactivate map
|
|
|
|
mMapView.onDetach();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
2016-09-16 15:45:10 +00:00
|
|
|
LogHelper.v(LOG_TAG, "onDestroy called.");
|
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
// reset first start state
|
|
|
|
mFirstStart = true;
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
// disable broadcast receivers
|
|
|
|
LocalBroadcastManager.getInstance(mActivity).unregisterReceiver(mTrackUpdatedReceiver);
|
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
super.onDestroy();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
|
|
|
|
// handle action bar options menu selection
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
|
|
|
|
// CASE MY LOCATION
|
2016-09-06 15:27:04 +00:00
|
|
|
case R.id.action_bar_my_location:
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-09-19 16:46:25 +00:00
|
|
|
// do nothing if location setting is off
|
|
|
|
if (toggleLocationOffBar()) {
|
|
|
|
stopPreliminaryTracking();
|
|
|
|
return false;
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// get current position
|
|
|
|
GeoPoint position;
|
2016-09-30 15:32:54 +00:00
|
|
|
|
2017-01-17 12:35:19 +00:00
|
|
|
if (mTrackerServiceRunning && mTrack != null) {
|
2016-09-30 15:32:54 +00:00
|
|
|
// get current Location from tracker service
|
2016-10-04 08:45:51 +00:00
|
|
|
mCurrentBestLocation = mTrack.getWayPointLocation(mTrack.getSize() - 1);
|
2016-09-30 15:32:54 +00:00
|
|
|
} else if (mCurrentBestLocation == null) {
|
2016-08-29 12:50:41 +00:00
|
|
|
// app does not have any location fix
|
|
|
|
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
|
|
|
}
|
|
|
|
|
2016-09-26 11:43:26 +00:00
|
|
|
// check if really got a position
|
|
|
|
if (mCurrentBestLocation != null) {
|
|
|
|
position = convertToGeoPoint(mCurrentBestLocation);
|
|
|
|
|
|
|
|
// center map on current position
|
|
|
|
mController.setCenter(position);
|
|
|
|
|
|
|
|
// mark user's new location on map and remove last marker
|
|
|
|
updateMyLocationMarker();
|
|
|
|
|
|
|
|
// inform user about location quality
|
|
|
|
String locationInfo;
|
|
|
|
long locationAge = (SystemClock.elapsedRealtimeNanos() - mCurrentBestLocation.getElapsedRealtimeNanos()) / 1000000;
|
|
|
|
String locationAgeString = LocationHelper.convertToReadableTime(locationAge, false);
|
|
|
|
if (locationAgeString == null) {
|
|
|
|
locationAgeString = mActivity.getString(R.string.toast_message_last_location_age_one_hour);
|
|
|
|
}
|
|
|
|
locationInfo = " " + locationAgeString + " | " + mCurrentBestLocation.getProvider();
|
|
|
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_last_location) + locationInfo, Toast.LENGTH_LONG).show();
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show();
|
|
|
|
return false;
|
2016-09-09 20:28:12 +00:00
|
|
|
}
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// CASE DEFAULT
|
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onSaveInstanceState(Bundle outState) {
|
2016-08-30 13:22:19 +00:00
|
|
|
outState.putBoolean(INSTANCE_FIRST_START, mFirstStart);
|
2016-09-06 15:27:04 +00:00
|
|
|
outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning);
|
2016-12-16 21:12:43 +00:00
|
|
|
outState.putParcelable(INSTANCE_CURRENT_LOCATION, mCurrentBestLocation);
|
2016-09-30 15:32:54 +00:00
|
|
|
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);
|
2016-08-29 12:50:41 +00:00
|
|
|
super.onSaveInstanceState(outState);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
/* Setter for tracking state */
|
2016-09-13 09:54:13 +00:00
|
|
|
public void setTrackingState(boolean trackingState) {
|
2016-09-06 15:27:04 +00:00
|
|
|
mTrackerServiceRunning = trackingState;
|
|
|
|
|
|
|
|
// turn on/off tracking for MainActivity Fragment - prevent double tracking
|
|
|
|
if (mTrackerServiceRunning) {
|
|
|
|
stopPreliminaryTracking();
|
2016-09-13 09:54:13 +00:00
|
|
|
} else if (!mLocalTrackerRunning && mFragmentVisible) {
|
2016-09-06 15:27:04 +00:00
|
|
|
startPreliminaryTracking();
|
2016-09-07 10:30:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (mTrack != null) {
|
2017-01-21 10:32:51 +00:00
|
|
|
drawTrackOverlay(mTrack); // TODO check if redundant
|
2016-09-06 15:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// update marker
|
2016-09-01 11:45:46 +00:00
|
|
|
updateMyLocationMarker();
|
2016-09-06 15:27:04 +00:00
|
|
|
LogHelper.v(LOG_TAG, "TrackingState: " + trackingState);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Getter for current best location */
|
|
|
|
public Location getCurrentBestLocation() {
|
|
|
|
return mCurrentBestLocation;
|
2016-09-01 11:45:46 +00:00
|
|
|
}
|
2016-08-29 19:43:49 +00:00
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
/* Removes track crumbs from map */
|
2016-12-12 17:52:01 +00:00
|
|
|
public void clearMap(boolean saveTrack) {
|
2016-10-25 14:38:27 +00:00
|
|
|
|
2016-09-26 12:43:01 +00:00
|
|
|
// clear map
|
2016-09-12 12:31:37 +00:00
|
|
|
if (mTrackOverlay != null) {
|
|
|
|
mMapView.getOverlays().remove(mTrackOverlay);
|
2016-12-16 21:12:43 +00:00
|
|
|
mTrackOverlay = null;
|
2016-09-12 12:31:37 +00:00
|
|
|
}
|
2016-09-27 14:50:37 +00:00
|
|
|
|
2016-12-12 17:52:01 +00:00
|
|
|
if (saveTrack) {
|
2016-12-16 21:12:43 +00:00
|
|
|
// save track object if requested
|
2016-12-12 17:52:01 +00:00
|
|
|
SaveTrackAsyncHelper saveTrackAsyncHelper = new SaveTrackAsyncHelper();
|
|
|
|
saveTrackAsyncHelper.execute();
|
|
|
|
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_save_track), Toast.LENGTH_LONG).show();
|
2016-12-16 21:12:43 +00:00
|
|
|
} else {
|
2017-01-10 14:57:03 +00:00
|
|
|
// clear track object and delete temp file
|
2016-12-16 21:12:43 +00:00
|
|
|
mTrack = null;
|
2017-01-19 12:36:49 +00:00
|
|
|
mStorageHelper.deleteTempFile();
|
2016-12-12 17:52:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
/* Start preliminary tracking for map */
|
|
|
|
private void startPreliminaryTracking() {
|
2016-09-19 16:46:25 +00:00
|
|
|
if (mLocationSystemSetting && !mLocalTrackerRunning) {
|
|
|
|
// create location listeners
|
|
|
|
List locationProviders = mLocationManager.getAllProviders();
|
|
|
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
|
|
|
mGPSListener = createLocationListener();
|
|
|
|
mLocalTrackerRunning = true;
|
|
|
|
}
|
|
|
|
if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
|
|
|
mNetworkListener = createLocationListener();
|
|
|
|
mLocalTrackerRunning = true;
|
|
|
|
}
|
|
|
|
// register listeners
|
|
|
|
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
|
|
|
LogHelper.v(LOG_TAG, "Starting preliminary tracking.");
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
/* Removes gps and network location listeners */
|
|
|
|
private void stopPreliminaryTracking() {
|
2016-09-19 16:46:25 +00:00
|
|
|
if (mLocalTrackerRunning) {
|
|
|
|
mLocalTrackerRunning = false;
|
|
|
|
// remove listeners
|
|
|
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
|
|
|
LogHelper.v(LOG_TAG, "Stopping preliminary tracking.");
|
|
|
|
}
|
2016-09-06 15:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
/* Creates listener for changes in location status */
|
2016-08-29 19:43:49 +00:00
|
|
|
private LocationListener createLocationListener() {
|
2016-08-29 12:50:41 +00:00
|
|
|
return new LocationListener() {
|
|
|
|
public void onLocationChanged(Location location) {
|
|
|
|
// check if the new location is better
|
2017-01-09 16:56:45 +00:00
|
|
|
if (mCurrentBestLocation == null || LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
2016-08-29 12:50:41 +00:00
|
|
|
// save location
|
|
|
|
mCurrentBestLocation = location;
|
|
|
|
// mark user's new location on map and remove last marker
|
2016-09-01 11:45:46 +00:00
|
|
|
updateMyLocationMarker();
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onStatusChanged(String provider, int status, Bundle extras) {
|
2016-09-19 16:46:25 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Location provider status change: " + provider + " | " + status);
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void onProviderEnabled(String provider) {
|
|
|
|
LogHelper.v(LOG_TAG, "Location provider enabled: " + provider);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onProviderDisabled(String provider) {
|
|
|
|
LogHelper.v(LOG_TAG, "Location provider disabled: " + provider);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
/* Updates marker for current user location */
|
|
|
|
private void updateMyLocationMarker() {
|
|
|
|
mMapView.getOverlays().remove(mMyLocationOverlay);
|
2016-09-06 15:27:04 +00:00
|
|
|
// only update while not tracking
|
|
|
|
if (!mTrackerServiceRunning) {
|
|
|
|
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
|
|
|
mMapView.getOverlays().add(mMyLocationOverlay);
|
|
|
|
}
|
2016-09-01 11:45:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Draws track onto overlay */
|
|
|
|
private void drawTrackOverlay(Track track) {
|
|
|
|
mMapView.getOverlays().remove(mTrackOverlay);
|
2017-01-11 20:52:45 +00:00
|
|
|
mTrackOverlay = null;
|
|
|
|
if (track != null) {
|
2017-01-25 13:19:50 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Drawing track overlay.");
|
2017-01-11 20:52:45 +00:00
|
|
|
mTrackOverlay = MapHelper.createTrackOverlay(mActivity, track, mTrackerServiceRunning);
|
|
|
|
mMapView.getOverlays().add(mTrackOverlay);
|
|
|
|
}
|
2016-09-01 11:45:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-19 16:46:25 +00:00
|
|
|
/* Toggles snackbar indicating that location setting is off */
|
|
|
|
private boolean toggleLocationOffBar() {
|
|
|
|
// create snackbar indicator for location setting off
|
|
|
|
if (mLocationOffBar == null) {
|
|
|
|
mLocationOffBar = Snackbar.make(mMapView, R.string.snackbar_message_location_offline, Snackbar.LENGTH_INDEFINITE).setAction("Action", null);
|
|
|
|
}
|
|
|
|
|
|
|
|
// get state of location system setting
|
|
|
|
mLocationSystemSetting = LocationHelper.checkLocationSystemSetting(mActivity);
|
|
|
|
|
|
|
|
// show snackbar if necessary
|
|
|
|
if (!mLocationSystemSetting) {
|
|
|
|
// show snackbar
|
|
|
|
mLocationOffBar.show();
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// hide snackbar
|
|
|
|
mLocationOffBar.dismiss();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
/* Creates receiver for new WayPoints */
|
2016-09-01 11:45:46 +00:00
|
|
|
private BroadcastReceiver createTrackUpdatedReceiver() {
|
2016-08-30 13:22:19 +00:00
|
|
|
return new BroadcastReceiver() {
|
|
|
|
@Override
|
|
|
|
public void onReceive(Context context, Intent intent) {
|
2016-09-06 15:27:04 +00:00
|
|
|
if (intent.hasExtra(EXTRA_TRACK) && intent.hasExtra(EXTRA_LAST_LOCATION)) {
|
2017-01-25 13:19:50 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Track update received.");
|
2016-09-06 15:27:04 +00:00
|
|
|
// draw track on map
|
2016-09-01 11:45:46 +00:00
|
|
|
mTrack = intent.getParcelableExtra(EXTRA_TRACK);
|
|
|
|
drawTrackOverlay(mTrack);
|
2016-09-06 15:27:04 +00:00
|
|
|
// center map over last location
|
|
|
|
mCurrentBestLocation = intent.getParcelableExtra(EXTRA_LAST_LOCATION);
|
|
|
|
mController.setCenter(convertToGeoPoint(mCurrentBestLocation));
|
|
|
|
// clear intent
|
2016-09-12 12:31:37 +00:00
|
|
|
intent.setAction(ACTION_DEFAULT);
|
2016-08-30 13:22:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
/* Converts Location to GeoPoint */
|
|
|
|
private GeoPoint convertToGeoPoint (Location location) {
|
2016-09-19 16:46:25 +00:00
|
|
|
if (location != null) {
|
|
|
|
return new GeoPoint(location.getLatitude(), location.getLongitude());
|
|
|
|
} else {
|
|
|
|
return new GeoPoint(DEFAULT_LATITUDE, DEFAULT_LONGITUDE);
|
|
|
|
}
|
2016-09-06 15:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-01-11 20:52:45 +00:00
|
|
|
/* Loads state tracker service from preferences */
|
|
|
|
private void loadTrackerServiceState(Context context) {
|
|
|
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
|
|
|
int fabState = settings.getInt(PREFS_FAB_STATE, FAB_STATE_DEFAULT);
|
2017-01-17 12:35:19 +00:00
|
|
|
mTrackerServiceRunning = fabState == FAB_STATE_RECORDING;
|
2017-01-11 20:52:45 +00:00
|
|
|
}
|
|
|
|
|
2016-09-19 16:46:25 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Inner class: SettingsContentObserver is a custom ContentObserver for changes in Android Settings
|
|
|
|
*/
|
2016-09-27 15:02:23 +00:00
|
|
|
private class SettingsContentObserver extends ContentObserver {
|
2016-09-19 16:46:25 +00:00
|
|
|
|
2016-09-27 15:02:23 +00:00
|
|
|
SettingsContentObserver(Handler handler) {
|
2016-09-19 16:46:25 +00:00
|
|
|
super(handler);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean deliverSelfNotifications() {
|
|
|
|
return super.deliverSelfNotifications();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onChange(boolean selfChange) {
|
|
|
|
super.onChange(selfChange);
|
|
|
|
LogHelper.v(LOG_TAG, "System Setting change detected.");
|
|
|
|
|
|
|
|
// check if location setting was changed
|
|
|
|
boolean previousLocationSystemSetting = mLocationSystemSetting;
|
|
|
|
mLocationSystemSetting = LocationHelper.checkLocationSystemSetting(mActivity);
|
|
|
|
if (previousLocationSystemSetting != mLocationSystemSetting) {
|
|
|
|
LogHelper.v(LOG_TAG, "Location Setting change detected.");
|
|
|
|
toggleLocationOffBar();
|
|
|
|
}
|
|
|
|
|
2016-09-20 11:51:17 +00:00
|
|
|
// start / stop preliminary tracking
|
2016-09-19 16:46:25 +00:00
|
|
|
if (!mLocationSystemSetting) {
|
|
|
|
stopPreliminaryTracking();
|
|
|
|
} else if (!mTrackerServiceRunning && mFragmentVisible) {
|
|
|
|
startPreliminaryTracking();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-27 15:02:23 +00:00
|
|
|
/**
|
2016-09-28 12:57:06 +00:00
|
|
|
* Inner class: Saves track to external storage using AsyncTask
|
2016-09-27 15:02:23 +00:00
|
|
|
*/
|
|
|
|
private class SaveTrackAsyncHelper extends AsyncTask<Void, Void, Void> {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Void doInBackground(Void... voids) {
|
|
|
|
LogHelper.v(LOG_TAG, "Saving track object in background.");
|
|
|
|
// save track object
|
2017-01-25 13:19:50 +00:00
|
|
|
mStorageHelper.saveTrack(mTrack, FILE_TYPE_TRACK);
|
2016-09-27 15:02:23 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Void aVoid) {
|
|
|
|
super.onPostExecute(aVoid);
|
|
|
|
// clear track object
|
2016-12-19 16:53:20 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Saving finished.");
|
2016-09-27 15:02:23 +00:00
|
|
|
mTrack = null;
|
2016-12-19 16:53:20 +00:00
|
|
|
|
|
|
|
// notify track fragment that save is finished
|
|
|
|
Intent i = new Intent();
|
|
|
|
i.setAction(ACTION_TRACK_SAVE);
|
|
|
|
i.putExtra(EXTRA_SAVE_FINISHED, true);
|
|
|
|
LocalBroadcastManager.getInstance(mActivity).sendBroadcast(i);
|
2016-09-27 15:02:23 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-03 20:12:13 +00:00
|
|
|
/**
|
|
|
|
* End of inner class
|
|
|
|
*/
|
2016-09-27 15:02:23 +00:00
|
|
|
|
|
|
|
|
2017-01-09 16:56:45 +00:00
|
|
|
/**
|
|
|
|
* Inner class: Loads track from external storage using AsyncTask
|
|
|
|
*/
|
|
|
|
private class LoadTempTrackAsyncHelper extends AsyncTask<Void, Void, Void> {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Void doInBackground(Void... voids) {
|
|
|
|
LogHelper.v(LOG_TAG, "Loading temporary track object in background.");
|
|
|
|
// load track object
|
2017-01-25 13:19:50 +00:00
|
|
|
mTrack = mStorageHelper.loadTrack(FILE_TYPE_TEMP);
|
2017-01-09 16:56:45 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onPostExecute(Void aVoid) {
|
|
|
|
super.onPostExecute(aVoid);
|
|
|
|
LogHelper.v(LOG_TAG, "Loading finished.");
|
|
|
|
|
|
|
|
// draw track on map
|
|
|
|
if (mTrack != null) {
|
|
|
|
drawTrackOverlay(mTrack);
|
|
|
|
}
|
|
|
|
|
|
|
|
// delete temp file
|
2017-01-19 12:36:49 +00:00
|
|
|
mStorageHelper.deleteTempFile();
|
2017-01-09 16:56:45 +00:00
|
|
|
}
|
|
|
|
}
|
2017-02-03 20:12:13 +00:00
|
|
|
/**
|
|
|
|
* End of inner class
|
|
|
|
*/
|
2017-01-09 16:56:45 +00:00
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|