Trackbook should now (more or less) gracefully handle changes to the Location setting in System Settings (#3).
parent
81b8219b93
commit
3256d97bb6
|
@ -43,16 +43,19 @@ To stop your recording press the big blue button again or use the stop button in
|
||||||
### Distance and duration
|
### Distance and duration
|
||||||
Peek into Trackbook's notification to see the distance and duration of your current recording.
|
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
|
### Clear the map
|
||||||
You can clear the map by either long-pressing the big blue button or dismissing the notification.
|
You can clear the map by either long-pressing the big blue button or dismissing the notification.
|
||||||
|
|
||||||
Which Permissions does Trackbook need?
|
Which Permissions does Trackbook need?
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
### Permission "INTERNET"
|
### 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"
|
### 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"
|
### 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.
|
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.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
import android.database.ContentObserver;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -65,7 +68,9 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
private Activity mActivity;
|
private Activity mActivity;
|
||||||
private Track mTrack;
|
private Track mTrack;
|
||||||
private boolean mFirstStart;
|
private boolean mFirstStart;
|
||||||
|
private Snackbar mLocationOffBar;
|
||||||
private BroadcastReceiver mTrackUpdatedReceiver;
|
private BroadcastReceiver mTrackUpdatedReceiver;
|
||||||
|
private SettingsContentObserver mSettingsContentObserver;
|
||||||
private MapView mMapView;
|
private MapView mMapView;
|
||||||
private IMapController mController;
|
private IMapController mController;
|
||||||
private LocationManager mLocationManager;
|
private LocationManager mLocationManager;
|
||||||
|
@ -76,6 +81,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
private Location mCurrentBestLocation;
|
private Location mCurrentBestLocation;
|
||||||
private boolean mTrackerServiceRunning;
|
private boolean mTrackerServiceRunning;
|
||||||
private boolean mLocalTrackerRunning;
|
private boolean mLocalTrackerRunning;
|
||||||
|
private boolean mLocationSystemSetting;
|
||||||
private boolean mFragmentVisible;
|
private boolean mFragmentVisible;
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,12 +115,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
// acquire reference to Location Manager
|
// acquire reference to Location Manager
|
||||||
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
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
|
// CASE 1: get saved location if possible
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
Location savedLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
Location savedLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
||||||
|
@ -131,11 +131,23 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
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
|
// register broadcast receiver for new WayPoints
|
||||||
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
||||||
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
||||||
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +169,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
// initiate map state
|
// initiate map state
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
// restore saved instance of map
|
// 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.setCenter(position);
|
||||||
mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL, 16));
|
mController.setZoom(savedInstanceState.getInt(INSTANCE_ZOOM_LEVEL, 16));
|
||||||
// restore current location
|
// restore current location
|
||||||
|
@ -198,7 +210,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
@ -206,11 +217,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
// set visibility
|
// set visibility
|
||||||
mFragmentVisible = true;
|
mFragmentVisible = true;
|
||||||
|
|
||||||
// start preliminary tracking - if no TrackerService is running
|
|
||||||
if (!mTrackerServiceRunning && mFragmentVisible) {
|
|
||||||
startPreliminaryTracking();
|
|
||||||
}
|
|
||||||
|
|
||||||
// center map on current position - if TrackerService is running
|
// center map on current position - if TrackerService is running
|
||||||
if (mTrackerServiceRunning) {
|
if (mTrackerServiceRunning) {
|
||||||
mController.setCenter(convertToGeoPoint(mCurrentBestLocation));
|
mController.setCenter(convertToGeoPoint(mCurrentBestLocation));
|
||||||
|
@ -221,6 +227,16 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
drawTrackOverlay(mTrack);
|
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
|
// disable preliminary location listeners
|
||||||
stopPreliminaryTracking();
|
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 MY LOCATION
|
||||||
case R.id.action_bar_my_location:
|
case R.id.action_bar_my_location:
|
||||||
|
|
||||||
|
// do nothing if location setting is off
|
||||||
if (mLocationManager.getProviders(true).size() == 0) {
|
if (toggleLocationOffBar()) {
|
||||||
// location services are off - ask user to turn them on
|
stopPreliminaryTracking();
|
||||||
promptUserForLocation();
|
return false;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get current position
|
// get current position
|
||||||
|
@ -310,7 +328,6 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
// save map position
|
|
||||||
outState.putBoolean(INSTANCE_FIRST_START, mFirstStart);
|
outState.putBoolean(INSTANCE_FIRST_START, mFirstStart);
|
||||||
outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude());
|
outState.putDouble(INSTANCE_LATITUDE, mMapView.getMapCenter().getLatitude());
|
||||||
outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude());
|
outState.putDouble(INSTANCE_LONGITUDE, mMapView.getMapCenter().getLongitude());
|
||||||
|
@ -366,26 +383,32 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
|
|
||||||
/* Start preliminary tracking for map */
|
/* Start preliminary tracking for map */
|
||||||
private void startPreliminaryTracking() {
|
private void startPreliminaryTracking() {
|
||||||
mLocalTrackerRunning = true;
|
if (mLocationSystemSetting && !mLocalTrackerRunning) {
|
||||||
// create location listeners
|
// create location listeners
|
||||||
List locationProviders = mLocationManager.getProviders(true);
|
List locationProviders = mLocationManager.getAllProviders();
|
||||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||||||
mGPSListener = createLocationListener();
|
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 */
|
/* Removes gps and network location listeners */
|
||||||
private void stopPreliminaryTracking() {
|
private void stopPreliminaryTracking() {
|
||||||
mLocalTrackerRunning = false;
|
if (mLocalTrackerRunning) {
|
||||||
// remove listeners
|
mLocalTrackerRunning = false;
|
||||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
// 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) {
|
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) {
|
public void onProviderEnabled(String provider) {
|
||||||
|
@ -436,10 +459,28 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Prompts user to turn on location */
|
/* Toggles snackbar indicating that location setting is off */
|
||||||
private void promptUserForLocation() {
|
private boolean toggleLocationOffBar() {
|
||||||
// TODO prompt user to turn on location
|
// create snackbar indicator for location setting off
|
||||||
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_location_offline), Toast.LENGTH_LONG).show();
|
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 */
|
/* Converts Location to GeoPoint */
|
||||||
private GeoPoint convertToGeoPoint (Location location) {
|
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);
|
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.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.database.ContentObserver;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
|
@ -28,9 +29,11 @@ import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CountDownTimer;
|
import android.os.CountDownTimer;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.y20k.trackbook.core.Track;
|
import org.y20k.trackbook.core.Track;
|
||||||
import org.y20k.trackbook.core.WayPoint;
|
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.NotificationHelper;
|
||||||
import org.y20k.trackbook.helpers.TrackbookKeys;
|
import org.y20k.trackbook.helpers.TrackbookKeys;
|
||||||
|
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +63,10 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
private float mStepCountOffset;
|
private float mStepCountOffset;
|
||||||
private LocationListener mGPSListener = null;
|
private LocationListener mGPSListener = null;
|
||||||
private LocationListener mNetworkListener = null;
|
private LocationListener mNetworkListener = null;
|
||||||
|
private SettingsContentObserver mSettingsContentObserver;
|
||||||
private Location mCurrentBestLocation;
|
private Location mCurrentBestLocation;
|
||||||
|
private boolean mTrackerServiceRunning;
|
||||||
|
private boolean mLocationSystemSetting;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
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
|
// acquire reference to Sensor Manager
|
||||||
mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
|
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
|
// checking for empty intent
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
LogHelper.v(LOG_TAG, "Null-Intent received. Stopping self.");
|
LogHelper.v(LOG_TAG, "Null-Intent received. Stopping self.");
|
||||||
stopSelf();
|
stopSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ACTION START
|
// check if user did turn off location in device settings
|
||||||
else if (intent.getAction().equals(ACTION_START)) {
|
if (!mLocationSystemSetting) {
|
||||||
LogHelper.v(LOG_TAG, "Service received command: START");
|
LogHelper.v(LOG_TAG, "Location Setting is turned off.");
|
||||||
|
Toast.makeText(getApplicationContext(), R.string.toast_message_location_offline, Toast.LENGTH_LONG).show();
|
||||||
// create a new track
|
stopTracking();
|
||||||
mTrack = new Track();
|
return START_STICKY;
|
||||||
|
|
||||||
// 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();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ACTION START
|
||||||
|
else if (intent.getAction().equals(ACTION_START) && mLocationSystemSetting) {
|
||||||
|
startTracking(intent);
|
||||||
|
}
|
||||||
|
|
||||||
// ACTION STOP
|
// ACTION STOP
|
||||||
else if (intent.getAction().equals(ACTION_STOP)) {
|
else if (intent.getAction().equals(ACTION_STOP) || !mLocationSystemSetting) {
|
||||||
LogHelper.v(LOG_TAG, "Service received command: STOP");
|
stopTracking();
|
||||||
|
|
||||||
// stop timer
|
|
||||||
mTimer.cancel();
|
|
||||||
|
|
||||||
// change notification
|
|
||||||
NotificationHelper.update(mTrack, false);
|
|
||||||
|
|
||||||
// remove listeners
|
|
||||||
stopFindingLocation();
|
|
||||||
mSensorManager.unregisterListener(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -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 */
|
/* Adds a new WayPoint to current track */
|
||||||
private void addWayPointToTrack() {
|
private void addWayPointToTrack() {
|
||||||
|
|
||||||
|
@ -242,7 +282,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
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) {
|
public void onProviderEnabled(String provider) {
|
||||||
|
@ -260,13 +300,14 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
private void startFindingLocation() {
|
private void startFindingLocation() {
|
||||||
|
|
||||||
// register location listeners and request updates
|
// register location listeners and request updates
|
||||||
List locationProviders = mLocationManager.getProviders(true);
|
List locationProviders = mLocationManager.getAllProviders();
|
||||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
||||||
mGPSListener = createLocationListener();
|
mGPSListener = createLocationListener();
|
||||||
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||||||
mNetworkListener = createLocationListener();
|
mNetworkListener = createLocationListener();
|
||||||
}
|
}
|
||||||
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
|
mTrackerServiceRunning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,6 +315,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
private void stopFindingLocation() {
|
private void stopFindingLocation() {
|
||||||
// remove listeners
|
// remove listeners
|
||||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
|
mTrackerServiceRunning = false;
|
||||||
|
|
||||||
// notify MainActivityMapFragment
|
// notify MainActivityMapFragment
|
||||||
Intent i = new Intent();
|
Intent i = new Intent();
|
||||||
|
@ -281,7 +323,40 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
i.putExtra(EXTRA_TRACK, mTrack);
|
i.putExtra(EXTRA_TRACK, mTrack);
|
||||||
i.putExtra(EXTRA_LAST_LOCATION, mCurrentBestLocation);
|
i.putExtra(EXTRA_LAST_LOCATION, mCurrentBestLocation);
|
||||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
|
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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@ -45,6 +47,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
private long mDuration;
|
private long mDuration;
|
||||||
private float mStepCount;
|
private float mStepCount;
|
||||||
private int mUnitSystem;
|
private int mUnitSystem;
|
||||||
|
private Date mRecordingStart;
|
||||||
|
private Date mRecordingEnd;
|
||||||
|
|
||||||
|
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
|
@ -53,6 +57,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
mTrackLength = 0;
|
mTrackLength = 0;
|
||||||
mStepCount = 0;
|
mStepCount = 0;
|
||||||
mUnitSystem = getUnitSystem(Locale.getDefault());
|
mUnitSystem = getUnitSystem(Locale.getDefault());
|
||||||
|
mRecordingStart = GregorianCalendar.getInstance().getTime();
|
||||||
|
mRecordingEnd = mRecordingStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,6 +68,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
mTrackLength = in.readFloat();
|
mTrackLength = in.readFloat();
|
||||||
mStepCount = in.readFloat();
|
mStepCount = in.readFloat();
|
||||||
mUnitSystem = in.readInt();
|
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 */
|
/* Setter for duration of track */
|
||||||
public void setDuration(long duration) {
|
public void setDuration(long duration) {
|
||||||
mDuration = duration;
|
mDuration = duration;
|
||||||
|
@ -119,6 +133,7 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
mStepCount = stepCount;
|
mStepCount = stepCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Getter for mWayPoints */
|
/* Getter for mWayPoints */
|
||||||
public List<WayPoint> getWayPoints() {
|
public List<WayPoint> getWayPoints() {
|
||||||
return mWayPoints;
|
return mWayPoints;
|
||||||
|
@ -188,6 +203,8 @@ public class Track implements TrackbookKeys, Parcelable {
|
||||||
parcel.writeFloat(mTrackLength);
|
parcel.writeFloat(mTrackLength);
|
||||||
parcel.writeFloat(mStepCount);
|
parcel.writeFloat(mStepCount);
|
||||||
parcel.writeInt(mUnitSystem);
|
parcel.writeInt(mUnitSystem);
|
||||||
|
parcel.writeLong(mRecordingStart.getTime());
|
||||||
|
parcel.writeLong(mRecordingEnd.getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,12 @@
|
||||||
|
|
||||||
package org.y20k.trackbook.helpers;
|
package org.y20k.trackbook.helpers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -162,6 +164,7 @@ public final class LocationHelper implements TrackbookKeys {
|
||||||
try {
|
try {
|
||||||
// register GPS location listener and request updates
|
// register GPS location listener and request updates
|
||||||
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsListener);
|
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, gpsListener);
|
||||||
|
LogHelper.v(LOG_TAG, "Registering gps listener.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// catches permission problems
|
// catches permission problems
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -173,6 +176,7 @@ public final class LocationHelper implements TrackbookKeys {
|
||||||
try {
|
try {
|
||||||
// register network location listener and request updates
|
// register network location listener and request updates
|
||||||
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener);
|
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, networkListener);
|
||||||
|
LogHelper.v(LOG_TAG, "Registering network listener.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// catches permission problems
|
// catches permission problems
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -186,13 +190,14 @@ public final class LocationHelper implements TrackbookKeys {
|
||||||
LogHelper.v(LOG_TAG, "Removing location listeners.");
|
LogHelper.v(LOG_TAG, "Removing location listeners.");
|
||||||
|
|
||||||
// get location providers
|
// get location providers
|
||||||
List locationProviders = locationManager.getProviders(true);
|
List locationProviders = locationManager.getAllProviders();
|
||||||
|
|
||||||
// got GPS location provider?
|
// got GPS location provider?
|
||||||
if (locationProviders.contains(LocationManager.GPS_PROVIDER) && gpsListener != null) {
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER) && gpsListener != null) {
|
||||||
try {
|
try {
|
||||||
// remove GPS listener
|
// remove GPS listener
|
||||||
locationManager.removeUpdates(gpsListener);
|
locationManager.removeUpdates(gpsListener);
|
||||||
|
LogHelper.v(LOG_TAG, "Removing gps listener.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// catches permission problems
|
// catches permission problems
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -204,6 +209,7 @@ public final class LocationHelper implements TrackbookKeys {
|
||||||
try {
|
try {
|
||||||
// remove network listener
|
// remove network listener
|
||||||
locationManager.removeUpdates(networkListener);
|
locationManager.removeUpdates(networkListener);
|
||||||
|
LogHelper.v(LOG_TAG, "Removing network listener.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
// catches permission problems
|
// catches permission problems
|
||||||
e.printStackTrace();
|
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 */
|
/* Checks whether two location providers are the same */
|
||||||
private static boolean isSameProvider(String provider1, String provider2) {
|
private static boolean isSameProvider(String provider1, String provider2) {
|
||||||
|
|
|
@ -80,5 +80,6 @@ public interface TrackbookKeys {
|
||||||
int INFOSHEET_CONTENT_ABOUT = 1;
|
int INFOSHEET_CONTENT_ABOUT = 1;
|
||||||
int METRIC = 1;
|
int METRIC = 1;
|
||||||
int IMPERIAL = 2;
|
int IMPERIAL = 2;
|
||||||
|
double DEFAULT_LATITUDE = 49.41667; // latitude Nordkapp, Norway
|
||||||
|
double DEFAULT_LONGITUDE = 8.67201; // longitude Nordkapp, Norway
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Recording sterted: "
|
android:text="Recording started: "
|
||||||
android:textAppearance="@android:style/TextAppearance.Small.Inverse" />
|
android:textAppearance="@android:style/TextAppearance.Small.Inverse" />
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -18,18 +18,19 @@
|
||||||
<string name="notification_title_trackbook_running">Trackbook running</string>
|
<string name="notification_title_trackbook_running">Trackbook running</string>
|
||||||
<string name="notification_title_trackbook_not_running">Trackbook not running</string>
|
<string name="notification_title_trackbook_not_running">Trackbook not running</string>
|
||||||
<string name="notification_stop">Stop</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_duration">Duration</string>
|
||||||
<string name="notification_content_distance">Distance</string>
|
<string name="notification_content_distance">Distance</string>
|
||||||
|
|
||||||
<!-- snackbar messages -->
|
<!-- snackbar messages -->
|
||||||
<string name="snackbar_message_tracking_stopped">Tracking stopped</string>
|
<string name="snackbar_message_tracking_stopped">Tracking stopped</string>
|
||||||
<string name="snackbar_message_tracking_started">Tracking started</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 -->
|
<!-- toast messages -->
|
||||||
<string name="toast_message_permissions_granted">Permissions granted.</string>
|
<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_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_acquiring_location">Acquiring current location.</string>
|
||||||
<string name="toast_message_last_location">Last location:</string>
|
<string name="toast_message_last_location">Last location:</string>
|
||||||
<string name="toast_message_clear_map">Clearing map.</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_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_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_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_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_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>
|
<string name="infosheet_about_h3_external">Permission WRITE_EXTERNAL_STORAGE</string>
|
||||||
|
|
Loading…
Reference in New Issue