making trackerservice resumable (see #29)
This commit is contained in:
		
							parent
							
								
									db1e70c370
								
							
						
					
					
						commit
						707c02a092
					
				
					 7 changed files with 116 additions and 48 deletions
				
			
		|  | @ -249,9 +249,13 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { | |||
|         mBottomNavigationView.setSelectedItemId(R.id.navigation_last_tracks); | ||||
| 
 | ||||
|         // dismiss notification | ||||
|         Intent intent = new Intent(this, TrackerService.class); | ||||
|         intent.setAction(ACTION_DISMISS); | ||||
|         startService(intent); | ||||
|         startTrackerService(ACTION_DISMISS, null); | ||||
| 
 | ||||
| //        Intent intent = new Intent(this, TrackerService.class); | ||||
| //        intent.setAction(ACTION_DISMISS); | ||||
| //        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
| //            startForegroundService(intent); | ||||
| //        } | ||||
| 
 | ||||
|         // hide Floating Action Button sub menu | ||||
|         showFloatingActionButtonMenu(false); | ||||
|  | @ -262,15 +266,37 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /* Start/stop tracker service */ | ||||
|     private void startTrackerService(String intentAction, @Nullable Location lastLocation) { | ||||
|         // build intent | ||||
|         Intent intent = new Intent(this, TrackerService.class); | ||||
|         intent.setAction(intentAction); | ||||
|         if (lastLocation != null && intentAction.equals(ACTION_START)) { | ||||
|             intent.putExtra(EXTRA_LAST_LOCATION, lastLocation); | ||||
|         } | ||||
| 
 | ||||
|         // start service | ||||
|         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||
|             // ... in foreground to prevent it being killed on Oreo | ||||
|             startForegroundService(intent); | ||||
|         } else { | ||||
|             startService(intent); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     /* Handles the visual state after a save action */ | ||||
|     private void handleStateAfterClear() { | ||||
|         // notify user | ||||
|         Toast.makeText(this, getString(R.string.toast_message_track_clear), Toast.LENGTH_LONG).show(); | ||||
| 
 | ||||
|         // dismiss notification | ||||
|         Intent intent = new Intent(this, TrackerService.class); | ||||
|         intent.setAction(ACTION_DISMISS); | ||||
|         startService(intent); | ||||
|         startTrackerService(ACTION_DISMISS, null); | ||||
| 
 | ||||
| //        Intent intent = new Intent(this, TrackerService.class); // todo remove | ||||
| //        intent.setAction(ACTION_DISMISS); | ||||
| //        startService(intent); | ||||
| 
 | ||||
|         // hide Floating Action Button sub menu | ||||
|         showFloatingActionButtonMenu(false); | ||||
|  | @ -446,14 +472,16 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { | |||
| 
 | ||||
|                 if (lastLocation != null) { | ||||
|                     // start tracker service | ||||
|                     Intent intent = new Intent(this, TrackerService.class); | ||||
|                     intent.setAction(ACTION_START); | ||||
|                     intent.putExtra(EXTRA_LAST_LOCATION, lastLocation); | ||||
|                     if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) { | ||||
|                         startForegroundService(intent); | ||||
|                     } else { | ||||
|                         startService(intent); | ||||
|                     } | ||||
|                     startTrackerService(ACTION_START, lastLocation); | ||||
| 
 | ||||
| //                    Intent intent = new Intent(this, TrackerService.class); // todo remove | ||||
| //                    intent.setAction(ACTION_START); | ||||
| //                    intent.putExtra(EXTRA_LAST_LOCATION, lastLocation); | ||||
| //                    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) { | ||||
| //                        startForegroundService(intent); | ||||
| //                    } else { | ||||
| //                        startService(intent); | ||||
| //                    } | ||||
| 
 | ||||
|                 } else { | ||||
|                     Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show(); | ||||
|  | @ -472,9 +500,11 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys { | |||
|                 // --> is handled by broadcast receiver | ||||
| 
 | ||||
|                 // stop tracker service | ||||
|                 Intent intent = new Intent(this, TrackerService.class); | ||||
|                 intent.setAction(ACTION_STOP); | ||||
|                 startService(intent); | ||||
|                 startTrackerService(ACTION_STOP, null); | ||||
| 
 | ||||
| //                Intent intent = new Intent(this, TrackerService.class); // todo remove | ||||
| //                intent.setAction(ACTION_STOP); | ||||
| //                startService(intent); | ||||
| 
 | ||||
|                 break; | ||||
| 
 | ||||
|  |  | |||
|  | @ -353,10 +353,10 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O | |||
|             } | ||||
| 
 | ||||
|             // populate views | ||||
|             mDistanceView.setText(mTrack.getTrackDistance()); | ||||
|             mDistanceView.setText(mTrack.getTrackDistanceString()); | ||||
|             mStepsView.setText(stepsTaken); | ||||
|             mWaypointsView.setText(String.valueOf(mTrack.getWayPoints().size())); | ||||
|             mDurationView.setText(mTrack.getTrackDuration()); | ||||
|             mDurationView.setText(mTrack.getTrackDurationString()); | ||||
|             mRecordingStartView.setText(recordingStart); | ||||
|             mRecordingStopView.setText(recordingStop); | ||||
| 
 | ||||
|  | @ -480,7 +480,7 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O | |||
|                 int dialogNegativeButton = R.string.dialog_default_action_cancel; | ||||
|                 DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.getDefault()); | ||||
|                 String recordingStartDate = df.format(mTrack.getRecordingStart()); | ||||
|                 String dialogMessage = getString(R.string.dialog_delete_content) + " " + recordingStartDate + " | " + mTrack.getTrackDistance(); | ||||
|                 String dialogMessage = getString(R.string.dialog_delete_content) + " " + recordingStartDate + " | " + mTrack.getTrackDistanceString(); | ||||
| 
 | ||||
|                 // show delete dialog - results are handles by onActivityResult | ||||
|                 DialogFragment dialogFragment = DialogHelper.newInstance(dialogTitle, dialogMessage, dialogPositiveButton, dialogNegativeButton); | ||||
|  | @ -511,13 +511,13 @@ public class MainActivityTrackFragment extends Fragment implements AdapterView.O | |||
|                 if (exportHelper.gpxFileExists(mTrack)) { | ||||
|                     // CASE: OVERWRITE - GPX file exists | ||||
|                     dialogTitle = R.string.dialog_export_title_overwrite; | ||||
|                     dialogMessage = getString(R.string.dialog_export_content_overwrite) + " (" + recordingStartDate + " | " + mTrack.getTrackDistance() + ")"; | ||||
|                     dialogMessage = getString(R.string.dialog_export_content_overwrite) + " (" + recordingStartDate + " | " + mTrack.getTrackDistanceString() + ")"; | ||||
|                     dialogPositiveButton = R.string.dialog_export_action_overwrite; | ||||
|                     dialogNegativeButton = R.string.dialog_default_action_cancel; | ||||
|                 } else { | ||||
|                     // CASE: EXPORT - GPX file does NOT yet exits | ||||
|                     dialogTitle = R.string.dialog_export_title_export; | ||||
|                     dialogMessage = getString(R.string.dialog_export_content_export) + " (" + recordingStartDate + " | " + mTrack.getTrackDistance() + ")"; | ||||
|                     dialogMessage = getString(R.string.dialog_export_content_export) + " (" + recordingStartDate + " | " + mTrack.getTrackDistanceString() + ")"; | ||||
|                     dialogPositiveButton = R.string.dialog_export_action_export; | ||||
|                     dialogNegativeButton = R.string.dialog_default_action_cancel; | ||||
|                 } | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ | |||
| 
 | ||||
| package org.y20k.trackbook; | ||||
| 
 | ||||
| import android.app.ActivityManager; | ||||
| import android.app.Notification; | ||||
| import android.app.NotificationManager; | ||||
| import android.app.Service; | ||||
|  | @ -49,6 +50,7 @@ import org.y20k.trackbook.helpers.NotificationHelper; | |||
| import org.y20k.trackbook.helpers.StorageHelper; | ||||
| import org.y20k.trackbook.helpers.TrackbookKeys; | ||||
| 
 | ||||
| import java.util.Iterator; | ||||
| import java.util.List; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -111,16 +113,20 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|             return START_STICKY; | ||||
|         } | ||||
| 
 | ||||
|         // checking for empty intent | ||||
|         // RESTART CHECK:  checking for empty intent - try to get saved track | ||||
|         if (intent == null || intent.getAction() == null) { | ||||
|             LogHelper.e(LOG_TAG, "Null-Intent received. Stopping self."); | ||||
|             // stopSelf triggers onDestroy | ||||
|             stopSelf(); | ||||
|             LogHelper.e(LOG_TAG, "Null-Intent received. Are we being restarted?"); | ||||
|             StorageHelper storageHelper = new StorageHelper(this); | ||||
|             if (storageHelper.tempFileExists()) { | ||||
|                 mTrack = storageHelper.loadTrack(FILE_TEMP_TRACK); | ||||
|                 // restart tracking | ||||
|                 startTracking(intent, false); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // ACTION START | ||||
|         else if (intent.getAction().equals(ACTION_START) && mLocationSystemSetting) { | ||||
|             startTracking(intent); | ||||
|             startTracking(intent, true); | ||||
|         } | ||||
| 
 | ||||
|         // ACTION STOP | ||||
|  | @ -130,14 +136,14 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|                 stopTracking(); | ||||
|             } else { | ||||
|                 // handle error - save state | ||||
|                 saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_DEFAULT); | ||||
|                 saveTrackerServiceState(mTrackerServiceRunning, 0, FAB_STATE_DEFAULT); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // ACTION DISMISS | ||||
|         else if (intent.getAction().equals(ACTION_DISMISS)) { | ||||
|             // save state | ||||
|             saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_DEFAULT); | ||||
|             saveTrackerServiceState(mTrackerServiceRunning, mTrack.getTrackDuration(), FAB_STATE_DEFAULT); | ||||
|             // dismiss notification | ||||
|             mNotificationManager.cancel(TRACKER_SERVICE_NOTIFICATION_ID); // todo check if necessary? | ||||
|             stopForeground(true); | ||||
|  | @ -169,10 +175,6 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|             stopTracking(); | ||||
|         } | ||||
| 
 | ||||
| //        // remove listeners | ||||
| //        stopFindingLocation(); | ||||
| //        mSensorManager.unregisterListener(this); | ||||
| 
 | ||||
|         // remove TrackerService from foreground state | ||||
|         stopForeground(true); | ||||
| 
 | ||||
|  | @ -202,14 +204,16 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
| 
 | ||||
| 
 | ||||
|     /* Start tracking location */ | ||||
|     private void startTracking(Intent intent) { | ||||
|     private void startTracking(@Nullable Intent intent, boolean createNewTrack) { | ||||
|         LogHelper.v(LOG_TAG, "Service received command: START"); | ||||
| 
 | ||||
|         // create a new track | ||||
|         mTrack = new Track(); | ||||
|         // create a new track -- if necessary | ||||
|         if (createNewTrack) { | ||||
|             mTrack = new Track(); | ||||
|         } | ||||
| 
 | ||||
|         // get last location | ||||
|         if (intent.hasExtra(EXTRA_LAST_LOCATION)) { | ||||
|         if (intent != null && intent.hasExtra(EXTRA_LAST_LOCATION)) { | ||||
|             mCurrentBestLocation = intent.getParcelableExtra(EXTRA_LAST_LOCATION); | ||||
|         } | ||||
|         //  get last location - fallback | ||||
|  | @ -226,11 +230,13 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|         mNotificationManager.notify(TRACKER_SERVICE_NOTIFICATION_ID, mNotification); // todo check if necessary in pre Android O | ||||
| 
 | ||||
|         // set timer to retrieve new locations and to prevent endless tracking | ||||
|         SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); | ||||
|         final long previouslyRecorded = settings.getLong(PREFS_CURRENT_TRACK_DURATION, 0);// todo describe | ||||
|         mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) { | ||||
|             @Override | ||||
|             public void onTick(long millisUntilFinished) { | ||||
|                 // update track duration | ||||
|                 long duration = EIGHT_HOURS_IN_MILLISECONDS - millisUntilFinished; | ||||
|                 long duration = EIGHT_HOURS_IN_MILLISECONDS - millisUntilFinished + previouslyRecorded; | ||||
|                 mTrack.setDuration(duration); | ||||
|                 // try to add WayPoint to Track | ||||
|                 addWayPointToTrack(); | ||||
|  | @ -305,6 +311,25 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|     /* Adds a new WayPoint to current track */ | ||||
|     private void addWayPointToTrack() { | ||||
| 
 | ||||
|         // TODO REMOVE | ||||
|         ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); | ||||
|         List<ActivityManager.RunningServiceInfo> l = am.getRunningServices(50); | ||||
|         Iterator<ActivityManager.RunningServiceInfo> i = l.iterator(); | ||||
|         while (i.hasNext()) { | ||||
|             ActivityManager.RunningServiceInfo runningServiceInfo = i | ||||
|                     .next(); | ||||
| 
 | ||||
|             if(runningServiceInfo.service.getClassName().contains("TrackerService")){ | ||||
| 
 | ||||
|                 if(runningServiceInfo.foreground) | ||||
|                 { | ||||
|                     LogHelper.e(LOG_TAG, "Foreground State? YES"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         // TODO REMOVE | ||||
| 
 | ||||
| 
 | ||||
|         // create new WayPoint | ||||
|         WayPoint newWayPoint = null; | ||||
| 
 | ||||
|  | @ -334,11 +359,17 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|                 newWayPoint = mTrack.addWayPoint(mCurrentBestLocation); | ||||
|             } | ||||
| 
 | ||||
|             // save state | ||||
|             saveTrackerServiceState(mTrackerServiceRunning, mTrack.getTrackDuration(), FAB_STATE_RECORDING); | ||||
|         } | ||||
| 
 | ||||
|         // send local broadcast if new WayPoint added | ||||
|         if (newWayPoint != null) { | ||||
|             sendTrackUpdate(); | ||||
| 
 | ||||
|             // save a temp file in case the service has been killed by the system | ||||
|             SaveTempTrackAsyncHelper saveTempTrackAsyncHelper = new SaveTempTrackAsyncHelper(); | ||||
|             saveTempTrackAsyncHelper.execute(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
|  | @ -396,7 +427,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|             mTrackerServiceRunning = true; | ||||
|         } | ||||
|         LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener); | ||||
|         saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_RECORDING); | ||||
|         saveTrackerServiceState(mTrackerServiceRunning, mTrack.getTrackDuration(), FAB_STATE_RECORDING); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -405,7 +436,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
|         // remove listeners | ||||
|         LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener); | ||||
|         mTrackerServiceRunning = false; | ||||
|         saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_SAVE); | ||||
|         saveTrackerServiceState(mTrackerServiceRunning, mTrack.getTrackDuration(),FAB_STATE_SAVE); | ||||
| 
 | ||||
|         // notify MainActivityMapFragment | ||||
|         Intent i = new Intent(); | ||||
|  | @ -417,10 +448,11 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven | |||
| 
 | ||||
| 
 | ||||
|     /* Saves state of Tracker Service and floating Action Button */ | ||||
|     private void saveTrackerServiceState(boolean trackerServiceRunning, int fabState) { | ||||
|     private void saveTrackerServiceState(boolean trackerServiceRunning, long currentTrackDuration, int fabState) { | ||||
|         SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this); | ||||
|         SharedPreferences.Editor editor = settings.edit(); | ||||
|         editor.putBoolean(PREFS_TRACKER_SERVICE_RUNNING, trackerServiceRunning); | ||||
|         editor.putLong(PREFS_CURRENT_TRACK_DURATION, currentTrackDuration); | ||||
|         editor.putInt(PREFS_FAB_STATE, fabState); | ||||
|         editor.apply(); | ||||
|     } | ||||
|  |  | |||
|  | @ -149,8 +149,8 @@ public class Track implements TrackbookKeys, Parcelable { | |||
| 
 | ||||
| 
 | ||||
|     /* Getter for duration of track */ | ||||
|     public String getTrackDuration() { | ||||
|         return LocationHelper.convertToReadableTime(mDuration, true); | ||||
|     public long getTrackDuration() { | ||||
|         return mDuration; | ||||
|     } | ||||
| 
 | ||||
|     /* Getter for start date of recording */ | ||||
|  | @ -171,8 +171,13 @@ public class Track implements TrackbookKeys, Parcelable { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /* Getter for distance of track */ | ||||
|     public String getTrackDistance() { | ||||
|     /* Getter for string representation of track duration */ | ||||
|     public String getTrackDurationString() { | ||||
|         return LocationHelper.convertToReadableTime(mDuration, true); | ||||
|     } | ||||
| 
 | ||||
|     /* Getter for string representation of track distance */ | ||||
|     public String getTrackDistanceString() { | ||||
|         float trackDistance; | ||||
|         String unit; | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ import android.util.Log; | |||
|  */ | ||||
| public final class LogHelper { | ||||
| 
 | ||||
|     private final static boolean mTesting = false; | ||||
|     private final static boolean mTesting = true; | ||||
| 
 | ||||
|     public static void d(final String tag, String message) { | ||||
|         // include logging only in debug versions | ||||
|  |  | |||
|  | @ -158,8 +158,8 @@ public class NotificationHelper implements TrackbookKeys { | |||
| 
 | ||||
|     /* Build context text for notification builder */ | ||||
|     private static String getContextString(Context context, Track track) { | ||||
|         return context.getString(R.string.notification_content_distance) + ": " + track.getTrackDistance() + " | " + | ||||
|                 context.getString(R.string.notification_content_duration) + ": " + track.getTrackDuration(); | ||||
|         return context.getString(R.string.notification_content_distance) + ": " + track.getTrackDistanceString() + " | " + | ||||
|                 context.getString(R.string.notification_content_duration) + ": " + track.getTrackDurationString(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -50,6 +50,7 @@ public interface TrackbookKeys { | |||
|     /* PREFS */ | ||||
|     String PREFS_FAB_STATE = "fabStatePrefs"; | ||||
|     String PREFS_TRACKER_SERVICE_RUNNING = "trackerServiceRunning"; | ||||
|     String PREFS_CURRENT_TRACK_DURATION = "currentTrackDuration"; | ||||
| 
 | ||||
|     /* INSTANCE STATE */ | ||||
|     String INSTANCE_FIRST_START = "firstStart"; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 y20k
						y20k