2016-08-29 12:50:41 +00:00
|
|
|
/**
|
|
|
|
* TrackerService.java
|
|
|
|
* Implements the app's movement tracker service
|
|
|
|
* The TrackerService creates a Track object and displays a notification
|
|
|
|
*
|
|
|
|
* This file is part of
|
|
|
|
* TRACKBOOK - Movement Recorder for Android
|
|
|
|
*
|
|
|
|
* Copyright (c) 2016 - Y20K.org
|
|
|
|
* Licensed under the MIT-License
|
|
|
|
* http://opensource.org/licenses/MIT
|
|
|
|
*
|
|
|
|
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
|
|
|
|
* https://github.com/osmdroid/osmdroid
|
|
|
|
*/
|
|
|
|
|
|
|
|
package org.y20k.trackbook;
|
|
|
|
|
|
|
|
import android.app.Service;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
2016-09-15 11:38:51 +00:00
|
|
|
import android.hardware.Sensor;
|
|
|
|
import android.hardware.SensorEvent;
|
|
|
|
import android.hardware.SensorEventListener;
|
|
|
|
import android.hardware.SensorManager;
|
2016-08-29 12:50:41 +00:00
|
|
|
import android.location.Location;
|
|
|
|
import android.location.LocationListener;
|
|
|
|
import android.location.LocationManager;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.CountDownTimer;
|
|
|
|
import android.os.IBinder;
|
|
|
|
import android.support.annotation.Nullable;
|
2016-09-01 11:45:46 +00:00
|
|
|
import android.support.v4.content.LocalBroadcastManager;
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
import org.y20k.trackbook.core.Track;
|
2016-09-01 11:45:46 +00:00
|
|
|
import org.y20k.trackbook.core.WayPoint;
|
2016-08-30 13:22:19 +00:00
|
|
|
import org.y20k.trackbook.helpers.LocationHelper;
|
2016-09-01 11:45:46 +00:00
|
|
|
import org.y20k.trackbook.helpers.LogHelper;
|
2016-09-06 15:27:04 +00:00
|
|
|
import org.y20k.trackbook.helpers.NotificationHelper;
|
2016-08-29 12:50:41 +00:00
|
|
|
import org.y20k.trackbook.helpers.TrackbookKeys;
|
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
import java.util.List;
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* TrackerService class
|
|
|
|
*/
|
2016-09-15 11:38:51 +00:00
|
|
|
public class TrackerService extends Service implements TrackbookKeys, SensorEventListener {
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
/* Define log tag */
|
|
|
|
private static final String LOG_TAG = TrackerService.class.getSimpleName();
|
|
|
|
|
|
|
|
|
|
|
|
/* Main class variables */
|
|
|
|
private Track mTrack;
|
|
|
|
private CountDownTimer mTimer;
|
|
|
|
private LocationManager mLocationManager;
|
2016-09-15 11:38:51 +00:00
|
|
|
private SensorManager mSensorManager;
|
|
|
|
private float mStepCountOffset;
|
2016-09-01 11:45:46 +00:00
|
|
|
private LocationListener mGPSListener = null;
|
|
|
|
private LocationListener mNetworkListener = null;
|
|
|
|
private Location mCurrentBestLocation;
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
|
|
|
|
2016-08-30 14:49:54 +00:00
|
|
|
// acquire reference to Location Manager
|
|
|
|
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
|
|
|
|
2016-09-15 11:38:51 +00:00
|
|
|
// acquire reference to Sensor Manager
|
|
|
|
mSensorManager = (SensorManager) this.getSystemService(Context.SENSOR_SERVICE);
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// checking for empty intent
|
|
|
|
if (intent == null) {
|
2016-09-01 11:45:46 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Null-Intent received. Stopping self.");
|
2016-08-29 12:50:41 +00:00
|
|
|
stopSelf();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ACTION START
|
|
|
|
else if (intent.getAction().equals(ACTION_START)) {
|
2016-09-01 11:45:46 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Service received command: START");
|
2016-08-29 12:50:41 +00:00
|
|
|
|
|
|
|
// create a new track
|
2016-09-01 11:45:46 +00:00
|
|
|
mTrack = new Track();
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
// add last location as WayPoint to track
|
2016-09-01 11:45:46 +00:00
|
|
|
addWayPointToTrack();
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
// set timer to retrieve new locations and to prevent endless tracking
|
2016-09-06 15:27:04 +00:00
|
|
|
mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) {
|
2016-08-29 12:50:41 +00:00
|
|
|
@Override
|
2016-09-06 15:27:04 +00:00
|
|
|
public void onTick(long millisUntilFinished) {
|
|
|
|
// update track duration
|
2016-09-15 11:38:51 +00:00
|
|
|
mTrack.setDuration(EIGHT_HOURS_IN_MILLISECONDS - millisUntilFinished);
|
2016-09-06 15:27:04 +00:00
|
|
|
// try to add WayPoint to Track
|
2016-09-01 11:45:46 +00:00
|
|
|
addWayPointToTrack();
|
2016-09-06 15:27:04 +00:00
|
|
|
// update notification
|
|
|
|
NotificationHelper.update(mTrack, true);
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onFinish() {
|
2016-09-06 15:27:04 +00:00
|
|
|
// remove listeners
|
|
|
|
stopFindingLocation();
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
};
|
2016-09-01 11:45:46 +00:00
|
|
|
mTimer.start();
|
|
|
|
|
2016-09-15 11:38:51 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
// put up notification
|
|
|
|
NotificationHelper.show(this,mTrack);
|
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
// create gps and network location listeners
|
|
|
|
startFindingLocation();
|
2016-09-15 11:38:51 +00:00
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ACTION STOP
|
|
|
|
else if (intent.getAction().equals(ACTION_STOP)) {
|
2016-09-01 11:45:46 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Service received command: STOP");
|
|
|
|
|
|
|
|
// stop timer
|
|
|
|
mTimer.cancel();
|
2016-08-30 14:49:54 +00:00
|
|
|
|
2016-09-12 12:31:37 +00:00
|
|
|
// change notification
|
|
|
|
NotificationHelper.update(mTrack, false);
|
|
|
|
|
2016-08-30 14:49:54 +00:00
|
|
|
// remove listeners
|
2016-09-06 15:27:04 +00:00
|
|
|
stopFindingLocation();
|
2016-09-15 11:38:51 +00:00
|
|
|
mSensorManager.unregisterListener(this);
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// START_STICKY is used for services that are explicitly started and stopped as needed
|
|
|
|
return START_STICKY;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
@Override
|
|
|
|
public IBinder onBind(Intent intent) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onDestroy() {
|
2016-09-01 11:45:46 +00:00
|
|
|
LogHelper.v(LOG_TAG, "onDestroy called.");
|
2016-08-29 12:50:41 +00:00
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
// remove listeners
|
2016-09-06 15:27:04 +00:00
|
|
|
stopFindingLocation();
|
2016-09-15 11:38:51 +00:00
|
|
|
mSensorManager.unregisterListener(this);
|
2016-08-30 13:22:19 +00:00
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
// cancel notification
|
|
|
|
stopForeground(true);
|
2016-08-30 14:49:54 +00:00
|
|
|
|
|
|
|
super.onDestroy();
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
|
2016-09-15 11:38:51 +00:00
|
|
|
@Override
|
|
|
|
public void onSensorChanged(SensorEvent sensorEvent) {
|
|
|
|
// save the step count offset / previously recorded steps
|
|
|
|
if (mStepCountOffset == 0) {
|
|
|
|
mStepCountOffset = sensorEvent.values[0] - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// calculate step count
|
|
|
|
float stepCount = sensorEvent.values[0] - mStepCountOffset;
|
|
|
|
|
|
|
|
// set step count in track
|
|
|
|
mTrack.setStepCount(stepCount);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void onAccuracyChanged(Sensor sensor, int i) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
/* Adds a new WayPoint to current track */
|
2016-09-09 20:28:12 +00:00
|
|
|
private void addWayPointToTrack() {
|
2016-09-01 11:45:46 +00:00
|
|
|
|
|
|
|
// create new WayPoint
|
|
|
|
WayPoint newWayPoint = null;
|
|
|
|
|
|
|
|
// get number of previously tracked WayPoints
|
|
|
|
int trackSize = mTrack.getWayPoints().size();
|
|
|
|
|
2016-09-01 12:16:32 +00:00
|
|
|
if (trackSize == 0) {
|
|
|
|
// add first location to track
|
|
|
|
newWayPoint = mTrack.addWayPoint(mCurrentBestLocation);
|
|
|
|
} else {
|
2016-09-12 12:31:37 +00:00
|
|
|
// get last WayPoint and compare it to current location
|
2016-09-01 12:16:32 +00:00
|
|
|
Location lastWayPoint = mTrack.getWayPointLocation(trackSize - 1);
|
2016-09-01 11:45:46 +00:00
|
|
|
if (LocationHelper.isNewWayPoint(lastWayPoint, mCurrentBestLocation)) {
|
|
|
|
// if new, add current best location to track
|
|
|
|
newWayPoint = mTrack.addWayPoint(mCurrentBestLocation);
|
|
|
|
}
|
2016-09-01 12:16:32 +00:00
|
|
|
|
2016-09-01 11:45:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// send local broadcast if new WayPoint added
|
|
|
|
if (newWayPoint != null) {
|
|
|
|
Intent i = new Intent();
|
|
|
|
i.setAction(ACTION_TRACK_UPDATED);
|
|
|
|
i.putExtra(EXTRA_TRACK, mTrack);
|
2016-09-06 15:27:04 +00:00
|
|
|
i.putExtra(EXTRA_LAST_LOCATION, mCurrentBestLocation);
|
2016-09-01 11:45:46 +00:00
|
|
|
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-08-30 13:22:19 +00:00
|
|
|
/* Creates a location listener */
|
|
|
|
private LocationListener createLocationListener() {
|
|
|
|
return new LocationListener() {
|
|
|
|
public void onLocationChanged(Location location) {
|
2016-09-01 11:45:46 +00:00
|
|
|
// check if the new location is better
|
|
|
|
if (LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
|
|
|
// save location
|
|
|
|
mCurrentBestLocation = location;
|
2016-08-30 13:22:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onStatusChanged(String provider, int status, Bundle extras) {
|
|
|
|
// TODO do something
|
|
|
|
}
|
|
|
|
|
|
|
|
public void onProviderEnabled(String provider) {
|
2016-09-06 15:27:04 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Location provider enabled: " + provider);
|
2016-08-30 13:22:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void onProviderDisabled(String provider) {
|
2016-09-06 15:27:04 +00:00
|
|
|
LogHelper.v(LOG_TAG, "Location provider disabled: " + provider);
|
2016-08-30 13:22:19 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2016-08-30 14:49:54 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* Creates gps and network location listeners */
|
2016-09-01 11:45:46 +00:00
|
|
|
private void startFindingLocation() {
|
2016-08-30 14:49:54 +00:00
|
|
|
|
|
|
|
// register location listeners and request updates
|
2016-09-01 11:45:46 +00:00
|
|
|
List locationProviders = mLocationManager.getProviders(true);
|
|
|
|
if (locationProviders.contains(LocationManager.GPS_PROVIDER)) {
|
|
|
|
mGPSListener = createLocationListener();
|
|
|
|
} else if (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
|
|
|
mNetworkListener = createLocationListener();
|
2016-08-30 14:49:54 +00:00
|
|
|
}
|
2016-09-01 11:45:46 +00:00
|
|
|
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
2016-08-30 14:49:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-09-06 15:27:04 +00:00
|
|
|
/* Removes gps and network location listeners */
|
|
|
|
private void stopFindingLocation() {
|
|
|
|
// remove listeners
|
|
|
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
|
|
|
|
|
|
|
// notify MainActivityFragment
|
|
|
|
Intent i = new Intent();
|
|
|
|
i.setAction(ACTION_TRACKING_STOPPED);
|
|
|
|
i.putExtra(EXTRA_TRACK, mTrack);
|
|
|
|
i.putExtra(EXTRA_LAST_LOCATION, mCurrentBestLocation);
|
|
|
|
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2016-08-29 12:50:41 +00:00
|
|
|
}
|