Trackbook should now (more or less) gracefully handle changes to the Location setting in System Settings (#3).
This commit is contained in:
parent
81b8219b93
commit
3256d97bb6
8 changed files with 315 additions and 117 deletions
|
@ -43,16 +43,19 @@ To stop your recording press the big blue button again or use the stop button in
|
|||
### Distance and duration
|
||||
Peek into Trackbook's notification to see the distance and duration of your current recording.
|
||||
|
||||
### How do you measure the distance?
|
||||
Trackbook calculates the distance between markers and adds them up.
|
||||
|
||||
### Clear the map
|
||||
You can clear the map by either long-pressing the big blue button or dismissing the notification.
|
||||
|
||||
Which Permissions does Trackbook need?
|
||||
--------------------------------------
|
||||
### Permission "INTERNET"
|
||||
Trackbook needs to download map data from Open Street Map servers and therefore needs access to the internet.
|
||||
Trackbook needs to download map data from OpenStreetMap servers and therefore needs access to the internet.
|
||||
|
||||
### Permission "ACCESS_NETWORK_STATE" and "ACCESS_WIFI_STATE"
|
||||
Trackbook uses [osmdroid](https://github.com/osmdroid/osmdroid/) to draw its main map. osmdroid needs to know the current state of your device’s connectivity - see [Prerequisites](https://github.com/osmdroid/osmdroid/wiki/Prerequisites). I am not sure why though. On the other hand: These permissions are not harmful in any way.
|
||||
Trackbook uses [osmdroid](https://github.com/osmdroid/osmdroid/) to draw its maps. osmdroid needs to know the current state of your device’s connectivity - see [Prerequisites](https://github.com/osmdroid/osmdroid/wiki/Prerequisites).
|
||||
|
||||
### Permission "ACCESS_COARSE_LOCATION" and "ACCESS_FINE_LOCATION"
|
||||
Trackbook needs accurate GPS location data to be able to record your movements. If the GPS data is not available or not accurate enough Trackbook uses location data from cell tower and WiFi triangulation.
|
||||
|
|
|
@ -22,12 +22,15 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.ContentObserver;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -65,7 +68,9 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
private Activity mActivity;
|
||||
private Track mTrack;
|
||||
private boolean mFirstStart;
|
||||
private Snackbar mLocationOffBar;
|
||||
private BroadcastReceiver mTrackUpdatedReceiver;
|
||||
private SettingsContentObserver mSettingsContentObserver;
|
||||
private MapView mMapView;
|
||||
private IMapController mController;
|
||||
private LocationManager mLocationManager;
|
||||
|
@ -76,6 +81,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
private Location mCurrentBestLocation;
|
||||
private boolean mTrackerServiceRunning;
|
||||
private boolean mLocalTrackerRunning;
|
||||
private boolean mLocationSystemSetting;
|
||||
private boolean mFragmentVisible;
|
||||
|
||||
|
||||
|
@ -109,12 +115,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
// acquire reference to Location Manager
|
||||
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
||||
|
||||
// check if location services are available
|
||||
if (mLocationManager.getProviders(true).size() == 0) {
|
||||
// ask user to turn on location services
|
||||
promptUserForLocation();
|
||||
}
|
||||
|
||||
// CASE 1: get saved location if possible
|
||||
if (savedInstanceState != null) {
|
||||
Location savedLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
||||
|
@ -131,11 +131,23 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||
}
|
||||
|
||||
// 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());
|
||||
|
||||
// register broadcast receiver for new WayPoints
|
||||
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
||||
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
||||
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -157,7 +169,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
// initiate map state
|
||||
if (savedInstanceState != null) {
|
||||
// restore saved instance of map
|
||||
GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE));
|
||||
GeoPoint position = new GeoPoint(savedInstanceState.getDouble(INSTANCE_LATITUDE, DEFAULT_LATITUDE), savedInstanceState.getDouble(INSTANCE_LONGITUDE, DEFAULT_LONGITUDE));
|
||||
mController.setCenter(position);
|
||||
mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL, 16));
|
||||
// restore current location
|
||||
|
@ -198,7 +210,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -206,11 +217,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
// set visibility
|
||||
mFragmentVisible = true;
|
||||
|
||||
// start preliminary tracking - if no TrackerService is running
|
||||
if (!mTrackerServiceRunning && mFragmentVisible) {
|
||||
startPreliminaryTracking();
|
||||
}
|
||||
|
||||
// center map on current position - if TrackerService is running
|
||||
if (mTrackerServiceRunning) {
|
||||
mController.setCenter(convertToGeoPoint(mCurrentBestLocation));
|
||||
|
@ -221,6 +227,16 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
drawTrackOverlay(mTrack);
|
||||
}
|
||||
|
||||
// show/hide the location off notification bar
|
||||
toggleLocationOffBar();
|
||||
|
||||
// start preliminary tracking - if no TrackerService is running
|
||||
if (!mTrackerServiceRunning && mFragmentVisible) {
|
||||
startPreliminaryTracking();
|
||||
}
|
||||
|
||||
// register content observer for changes in System Settings
|
||||
mActivity.getContentResolver().registerContentObserver(android.provider.Settings.Secure.CONTENT_URI, true, mSettingsContentObserver );
|
||||
}
|
||||
|
||||
|
||||
|
@ -233,6 +249,9 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
|
||||
// disable preliminary location listeners
|
||||
stopPreliminaryTracking();
|
||||
|
||||
// disable content observer for changes in System Settings
|
||||
mActivity.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,11 +287,10 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
// CASE MY LOCATION
|
||||
case R.id.action_bar_my_location:
|
||||
|
||||
|
||||
if (mLocationManager.getProviders(true).size() == 0) {
|
||||
// location services are off - ask user to turn them on
|
||||
promptUserForLocation();
|
||||
return true;
|
||||
// do nothing if location setting is off
|
||||
if (toggleLocationOffBar()) {
|
||||
stopPreliminaryTracking();
|
||||
return false;
|
||||
}
|
||||
|
||||
// get current position
|
||||
|
@ -310,7 +328,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
// save map position
|
||||
outState.putBoolean(INSTANCE_FIRST_START, mFirstStart);
|
||||
outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude());
|
||||
outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude());
|
||||
|
@ -366,26 +383,32 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
|
||||
/* Start preliminary tracking for map */
|
||||
private void startPreliminaryTracking() {
|
||||
mLocalTrackerRunning = true;
|
||||
// create location listeners
|
||||
List locationProviders = mLocationManager.getProviders(true);
|
||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||||
mGPSListener = createLocationListener();
|
||||
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.");
|
||||
}
|
||||
if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||||
mNetworkListener = createLocationListener();
|
||||
}
|
||||
|
||||
// register listeners
|
||||
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
}
|
||||
|
||||
|
||||
/* Removes gps and network location listeners */
|
||||
private void stopPreliminaryTracking() {
|
||||
mLocalTrackerRunning = false;
|
||||
// remove listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
if (mLocalTrackerRunning) {
|
||||
mLocalTrackerRunning = false;
|
||||
// remove listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
LogHelper.v(LOG_TAG, "Stopping preliminary tracking.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,7 +426,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
}
|
||||
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
// TODO do something
|
||||
LogHelper.v(LOG_TAG, "Location provider status change: " + provider + " | " + status);
|
||||
}
|
||||
|
||||
public void onProviderEnabled(String provider) {
|
||||
|
@ -436,10 +459,28 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
/* Prompts user to turn on location */
|
||||
private void promptUserForLocation() {
|
||||
// TODO prompt user to turn on location
|
||||
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_location_offline), Toast.LENGTH_LONG).show();
|
||||
/* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -465,7 +506,11 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
|
||||
/* Converts Location to GeoPoint */
|
||||
private GeoPoint convertToGeoPoint (Location location) {
|
||||
return new GeoPoint(location.getLatitude(), location.getLongitude());
|
||||
if (location != null) {
|
||||
return new GeoPoint(location.getLatitude(), location.getLongitude());
|
||||
} else {
|
||||
return new GeoPoint(DEFAULT_LATITUDE, DEFAULT_LONGITUDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -484,4 +529,43 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
|||
int zoom = settings.getInt(PREFS_ZOOM_LEVEL, 16);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class: SettingsContentObserver is a custom ContentObserver for changes in Android Settings
|
||||
*/
|
||||
public class SettingsContentObserver extends ContentObserver {
|
||||
|
||||
public SettingsContentObserver(Handler handler) {
|
||||
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();
|
||||
}
|
||||
|
||||
// start / stop perliminary tracking
|
||||
if (!mLocationSystemSetting) {
|
||||
stopPreliminaryTracking();
|
||||
} else if (!mTrackerServiceRunning && mFragmentVisible) {
|
||||
startPreliminaryTracking();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -19,6 +19,7 @@ package org.y20k.trackbook;
|
|||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.ContentObserver;
|
||||
import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
|
@ -28,9 +29,11 @@ import android.location.LocationListener;
|
|||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.y20k.trackbook.core.Track;
|
||||
import org.y20k.trackbook.core.WayPoint;
|
||||
|
@ -39,6 +42,7 @@ import org.y20k.trackbook.helpers.LogHelper;
|
|||
import org.y20k.trackbook.helpers.NotificationHelper;
|
||||
import org.y20k.trackbook.helpers.TrackbookKeys;
|
||||
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
@ -59,7 +63,10 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
private float mStepCountOffset;
|
||||
private LocationListener mGPSListener = null;
|
||||
private LocationListener mNetworkListener = null;
|
||||
private SettingsContentObserver mSettingsContentObserver;
|
||||
private Location mCurrentBestLocation;
|
||||
private boolean mTrackerServiceRunning;
|
||||
private boolean mLocationSystemSetting;
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
@ -70,82 +77,35 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
// acquire reference to Sensor Manager
|
||||
mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
|
||||
|
||||
// get state of location system setting
|
||||
mLocationSystemSetting = LocationHelper.checkLocationSystemSetting(getApplicationContext());
|
||||
|
||||
// create content observer for changes in System Settings
|
||||
mSettingsContentObserver = new SettingsContentObserver( new Handler());
|
||||
|
||||
// checking for empty intent
|
||||
if (intent == null) {
|
||||
LogHelper.v(LOG_TAG, "Null-Intent received. Stopping self.");
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
// ACTION START
|
||||
else if (intent.getAction().equals(ACTION_START)) {
|
||||
LogHelper.v(LOG_TAG, "Service received command: START");
|
||||
|
||||
// create a new track
|
||||
mTrack = new Track();
|
||||
|
||||
// get last location
|
||||
if (intent.hasExtra(EXTRA_LAST_LOCATION)) {
|
||||
mCurrentBestLocation = intent.getParcelableExtra(EXTRA_LAST_LOCATION);
|
||||
}
|
||||
// get last location - fallback
|
||||
if (mCurrentBestLocation == null) {
|
||||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||
}
|
||||
|
||||
// add last location as WayPoint to track
|
||||
addWayPointToTrack();
|
||||
|
||||
// set timer to retrieve new locations and to prevent endless tracking
|
||||
mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) {
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
// update track duration
|
||||
mTrack.setDuration(EIGHT_HOURS_IN_MILLISECONDS - millisUntilFinished);
|
||||
// try to add WayPoint to Track
|
||||
addWayPointToTrack();
|
||||
// update notification
|
||||
NotificationHelper.update(mTrack, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
// remove listeners
|
||||
stopFindingLocation();
|
||||
}
|
||||
};
|
||||
mTimer.start();
|
||||
|
||||
// initialize step counter
|
||||
mStepCountOffset = 0;
|
||||
Sensor stepCounter = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
|
||||
if (stepCounter != null) {
|
||||
mSensorManager.registerListener(this, stepCounter, SensorManager.SENSOR_DELAY_UI);
|
||||
} else {
|
||||
LogHelper.v(LOG_TAG, "Pedometer Sensor not available");
|
||||
mTrack.setStepCount(-1);
|
||||
}
|
||||
|
||||
// put up notification
|
||||
NotificationHelper.show(this,mTrack);
|
||||
|
||||
// create gps and network location listeners
|
||||
startFindingLocation();
|
||||
|
||||
// check if user did turn off location in device settings
|
||||
if (!mLocationSystemSetting) {
|
||||
LogHelper.v(LOG_TAG, "Location Setting is turned off.");
|
||||
Toast.makeText(getApplicationContext(), R.string.toast_message_location_offline, Toast.LENGTH_LONG).show();
|
||||
stopTracking();
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
|
||||
// ACTION START
|
||||
else if (intent.getAction().equals(ACTION_START) && mLocationSystemSetting) {
|
||||
startTracking(intent);
|
||||
}
|
||||
|
||||
// ACTION STOP
|
||||
else if (intent.getAction().equals(ACTION_STOP)) {
|
||||
LogHelper.v(LOG_TAG, "Service received command: STOP");
|
||||
|
||||
// stop timer
|
||||
mTimer.cancel();
|
||||
|
||||
// change notification
|
||||
NotificationHelper.update(mTrack, false);
|
||||
|
||||
// remove listeners
|
||||
stopFindingLocation();
|
||||
mSensorManager.unregisterListener(this);
|
||||
else if (intent.getAction().equals(ACTION_STOP) || !mLocationSystemSetting) {
|
||||
stopTracking();
|
||||
}
|
||||
|
||||
// START_STICKY is used for services that are explicitly started and stopped as needed
|
||||
|
@ -196,6 +156,86 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
}
|
||||
|
||||
|
||||
private void startTracking(Intent intent) {
|
||||
LogHelper.v(LOG_TAG, "Service received command: START");
|
||||
|
||||
// create a new track
|
||||
mTrack = new Track();
|
||||
|
||||
// get last location
|
||||
if (intent.hasExtra(EXTRA_LAST_LOCATION)) {
|
||||
mCurrentBestLocation = intent.getParcelableExtra(EXTRA_LAST_LOCATION);
|
||||
}
|
||||
// get last location - fallback
|
||||
if (mCurrentBestLocation == null) {
|
||||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||
}
|
||||
|
||||
// add last location as WayPoint to track
|
||||
addWayPointToTrack();
|
||||
|
||||
// set timer to retrieve new locations and to prevent endless tracking
|
||||
mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) {
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
// update track duration
|
||||
mTrack.setDuration(EIGHT_HOURS_IN_MILLISECONDS - millisUntilFinished);
|
||||
// try to add WayPoint to Track
|
||||
addWayPointToTrack();
|
||||
// update notification
|
||||
NotificationHelper.update(mTrack, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
// remove listeners
|
||||
stopFindingLocation();
|
||||
}
|
||||
};
|
||||
mTimer.start();
|
||||
|
||||
// initialize step counter
|
||||
mStepCountOffset = 0;
|
||||
Sensor stepCounter = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
|
||||
if (stepCounter != null) {
|
||||
mSensorManager.registerListener(this, stepCounter, SensorManager.SENSOR_DELAY_UI);
|
||||
} else {
|
||||
LogHelper.v(LOG_TAG, "Pedometer Sensor not available");
|
||||
mTrack.setStepCount(-1);
|
||||
}
|
||||
|
||||
// put up notification
|
||||
NotificationHelper.show(this,mTrack);
|
||||
|
||||
// create gps and network location listeners
|
||||
startFindingLocation();
|
||||
|
||||
// register content observer for changes in System Settings
|
||||
this.getContentResolver().registerContentObserver(android.provider.Settings.Secure.CONTENT_URI, true, mSettingsContentObserver );
|
||||
}
|
||||
|
||||
|
||||
private void stopTracking() {
|
||||
LogHelper.v(LOG_TAG, "Service received command: STOP");
|
||||
|
||||
// store current date and time
|
||||
mTrack.setRecordingEnd(GregorianCalendar.getInstance().getTime());
|
||||
|
||||
// stop timer
|
||||
mTimer.cancel();
|
||||
|
||||
// change notification
|
||||
NotificationHelper.update(mTrack, false);
|
||||
|
||||
// remove listeners
|
||||
stopFindingLocation();
|
||||
mSensorManager.unregisterListener(this);
|
||||
|
||||
// disable content observer for changes in System Settings
|
||||
this.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
|
||||
}
|
||||
|
||||
|
||||
/* Adds a new WayPoint to current track */
|
||||
private void addWayPointToTrack() {
|
||||
|
||||
|
@ -242,7 +282,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
}
|
||||
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
// TODO do something
|
||||
LogHelper.v(LOG_TAG, "Location provider status change: " + provider + " | " + status);
|
||||
}
|
||||
|
||||
public void onProviderEnabled(String provider) {
|
||||
|
@ -260,13 +300,14 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
private void startFindingLocation() {
|
||||
|
||||
// register location listeners and request updates
|
||||
List locationProviders = mLocationManager.getProviders(true);
|
||||
List locationProviders = mLocationManager.getAllProviders();
|
||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||||
mGPSListener = createLocationListener();
|
||||
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||||
mNetworkListener = createLocationListener();
|
||||
}
|
||||
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
mTrackerServiceRunning = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -274,6 +315,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
private void stopFindingLocation() {
|
||||
// remove listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
mTrackerServiceRunning = false;
|
||||
|
||||
// notify MainActivityMapFragment
|
||||
Intent i = new Intent();
|
||||
|
@ -281,7 +323,40 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
|||
i.putExtra(EXTRA_TRACK, mTrack);
|
||||
i.putExtra(EXTRA_LAST_LOCATION, mCurrentBestLocation);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class: SettingsContentObserver is a custom ContentObserver for changes in Android Settings
|
||||
*/
|
||||
public class SettingsContentObserver extends ContentObserver {
|
||||
|
||||
public SettingsContentObserver(Handler handler) {
|
||||
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(getApplicationContext());
|
||||
if (previousLocationSystemSetting != mLocationSystemSetting && !mLocationSystemSetting && mTrackerServiceRunning) {
|
||||
LogHelper.v(LOG_TAG, "Location Setting turned off while tracking service running.");
|
||||
stopTracking();
|
||||
stopForeground(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import org.y20k.trackbook.helpers.TrackbookKeys;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -45,6 +47,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
private long mDuration;
|
||||
private float mStepCount;
|
||||
private int mUnitSystem;
|
||||
private Date mRecordingStart;
|
||||
private Date mRecordingEnd;
|
||||
|
||||
|
||||
/* Constructor */
|
||||
|
@ -53,6 +57,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
mTrackLength = 0;
|
||||
mStepCount = 0;
|
||||
mUnitSystem = getUnitSystem(Locale.getDefault());
|
||||
mRecordingStart = GregorianCalendar.getInstance().getTime();
|
||||
mRecordingEnd = mRecordingStart;
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,6 +68,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
mTrackLength = in.readFloat();
|
||||
mStepCount = in.readFloat();
|
||||
mUnitSystem = in.readInt();
|
||||
mRecordingStart = new Date(in.readLong());
|
||||
mRecordingEnd = new Date(in.readLong());
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,6 +116,12 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
}
|
||||
|
||||
|
||||
/* Setter for end time and date of recording */
|
||||
public void setRecordingEnd (Date recordingEnd) {
|
||||
mRecordingEnd = recordingEnd;
|
||||
}
|
||||
|
||||
|
||||
/* Setter for duration of track */
|
||||
public void setDuration(long duration) {
|
||||
mDuration = duration;
|
||||
|
@ -119,6 +133,7 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
mStepCount = stepCount;
|
||||
}
|
||||
|
||||
|
||||
/* Getter for mWayPoints */
|
||||
public List<WayPoint> getWayPoints() {
|
||||
return mWayPoints;
|
||||
|
@ -188,6 +203,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
parcel.writeFloat(mTrackLength);
|
||||
parcel.writeFloat(mStepCount);
|
||||
parcel.writeInt(mUnitSystem);
|
||||
parcel.writeLong(mRecordingStart.getTime());
|
||||
parcel.writeLong(mRecordingEnd.getTime());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
|
||||
package org.y20k.trackbook.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -162,6 +164,7 @@ public final class LocationHelper implements TrackbookKeys {
|
|||
try {
|
||||
// register GPS location listener and request updates
|
||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsListener);
|
||||
LogHelper.v(LOG_TAG, "Registering gps listener.");
|
||||
} catch (SecurityException e) {
|
||||
// catches permission problems
|
||||
e.printStackTrace();
|
||||
|
@ -173,6 +176,7 @@ public final class LocationHelper implements TrackbookKeys {
|
|||
try {
|
||||
// register network location listener and request updates
|
||||
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener);
|
||||
LogHelper.v(LOG_TAG, "Registering network listener.");
|
||||
} catch (SecurityException e) {
|
||||
// catches permission problems
|
||||
e.printStackTrace();
|
||||
|
@ -186,13 +190,14 @@ public final class LocationHelper implements TrackbookKeys {
|
|||
LogHelper.v(LOG_TAG, "Removing location listeners.");
|
||||
|
||||
// get location providers
|
||||
List locationProviders = locationManager.getProviders(true);
|
||||
List locationProviders = locationManager.getAllProviders();
|
||||
|
||||
// got GPS location provider?
|
||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER) && gpsListener != null) {
|
||||
try {
|
||||
// remove GPS listener
|
||||
locationManager.removeUpdates(gpsListener);
|
||||
LogHelper.v(LOG_TAG, "Removing gps listener.");
|
||||
} catch (SecurityException e) {
|
||||
// catches permission problems
|
||||
e.printStackTrace();
|
||||
|
@ -204,6 +209,7 @@ public final class LocationHelper implements TrackbookKeys {
|
|||
try {
|
||||
// remove network listener
|
||||
locationManager.removeUpdates(networkListener);
|
||||
LogHelper.v(LOG_TAG, "Removing network listener.");
|
||||
} catch (SecurityException e) {
|
||||
// catches permission problems
|
||||
e.printStackTrace();
|
||||
|
@ -232,6 +238,17 @@ public final class LocationHelper implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
/* Check if any location provider is enabled */
|
||||
public static boolean checkLocationSystemSetting(Context context) {
|
||||
int locationSettingState = 0;
|
||||
try {
|
||||
locationSettingState = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
|
||||
} catch (Settings.SettingNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return locationSettingState != Settings.Secure.LOCATION_MODE_OFF;
|
||||
}
|
||||
|
||||
|
||||
/* Checks whether two location providers are the same */
|
||||
private static boolean isSameProvider(String provider1, String provider2) {
|
||||
|
|
|
@ -80,5 +80,6 @@ public interface TrackbookKeys {
|
|||
int INFOSHEET_CONTENT_ABOUT = 1;
|
||||
int METRIC = 1;
|
||||
int IMPERIAL = 2;
|
||||
|
||||
double DEFAULT_LATITUDE = 49.41667; // latitude Nordkapp, Norway
|
||||
double DEFAULT_LONGITUDE = 8.67201; // longitude Nordkapp, Norway
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Recording sterted: "
|
||||
android:text="Recording started: "
|
||||
android:textAppearance="@android:style/TextAppearance.Small.Inverse" />
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -18,18 +18,19 @@
|
|||
<string name="notification_title_trackbook_running">Trackbook running</string>
|
||||
<string name="notification_title_trackbook_not_running">Trackbook not running</string>
|
||||
<string name="notification_stop">Stop</string>
|
||||
<string name="notification_swipe_to_clear_map">… swipe to clear map.</string>
|
||||
<string name="notification_swipe_to_clear_map">SWIPE to clear map.</string>
|
||||
<string name="notification_content_duration">Duration</string>
|
||||
<string name="notification_content_distance">Distance</string>
|
||||
|
||||
<!-- snackbar messages -->
|
||||
<string name="snackbar_message_tracking_stopped">Tracking stopped</string>
|
||||
<string name="snackbar_message_tracking_started">Tracking started</string>
|
||||
<string name="snackbar_message_location_offline">Location is turned off. Trackbook will not work.</string>
|
||||
|
||||
<!-- toast messages -->
|
||||
<string name="toast_message_permissions_granted">Permissions granted.</string>
|
||||
<string name="toast_message_unable_to_start_app">Unable to start Trackbook.</string>
|
||||
<string name="toast_message_location_offline">Location is turned off.</string>
|
||||
<string name="toast_message_location_offline">Location is turned off. Trackbook will not work.</string>
|
||||
<string name="toast_message_acquiring_location">Acquiring current location.</string>
|
||||
<string name="toast_message_last_location">Last location:</string>
|
||||
<string name="toast_message_clear_map">Clearing map.</string>
|
||||
|
@ -64,7 +65,7 @@
|
|||
<string name="infosheet_about_h3_internet">Permission INTERNET</string>
|
||||
<string name="infosheet_about_p_internet">Trackbook needs to download map data from Open Street Map servers and therefore needs access to the internet.</string>
|
||||
<string name="infosheet_about_h3_network">Permission ACCESS_WIFI_STATE and ACCESS_NETWORK_STATE</string>
|
||||
<string name="infosheet_about_p_network">Trackbook uses to draw its main map. osmdroid needs to know the current state of your device’s connectivity. I am not sure why though. On the other hand: These permissions are not harmful in any way.</string>
|
||||
<string name="infosheet_about_p_network">Trackbook uses osmdroid to draw its maps. osmdroid needs to know the current state of your device’s connectivity.</string>
|
||||
<string name="infosheet_about_h3_location">Permission ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION</string>
|
||||
<string name="infosheet_about_p_location">Trackbook needs accurate GPS location data to be able to record your movements. If the GPS data is not available or not accurate enough Trackbook uses location data from cell tower and WiFi triangulation.</string>
|
||||
<string name="infosheet_about_h3_external">Permission WRITE_EXTERNAL_STORAGE</string>
|
||||
|
|
Loading…
Reference in a new issue