Trackbook got a notification. Double tracking while showing the map removed. While recording the track is now red. Bug fixes.
This commit is contained in:
parent
f83c651970
commit
3e543444d5
17 changed files with 538 additions and 116 deletions
|
@ -18,13 +18,18 @@ package org.y20k.trackbook;
|
|||
|
||||
import android.Manifest;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.location.Location;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
|
@ -55,8 +60,10 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
private boolean mTracking;
|
||||
private boolean mPermissionsGranted;
|
||||
private List<String> mMissingPermissions;
|
||||
private View mRootView;
|
||||
private FloatingActionButton mFloatingActionButton;
|
||||
private MainActivityFragment mMainActivityFragment;
|
||||
private BroadcastReceiver mTrackingStoppedReceiver;
|
||||
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +73,7 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
// set state of tracking
|
||||
mTracking = false;
|
||||
if (savedInstanceState != null) {
|
||||
mTracking = savedInstanceState.getBoolean(INSTANCE_TRACKING_STARTED, false);
|
||||
mTracking = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false);
|
||||
}
|
||||
|
||||
// check permissions on Android 6 and higher
|
||||
|
@ -85,6 +92,11 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
// set up main layout
|
||||
setupLayout();
|
||||
|
||||
// register broadcast receiver for stopped tracking
|
||||
mTrackingStoppedReceiver = createTrackingStoppedReceiver();
|
||||
IntentFilter trackingStoppedIntentFilter = new IntentFilter(ACTION_TRACKING_STOPPED);
|
||||
LocalBroadcastManager.getInstance(this).registerReceiver(mTrackingStoppedReceiver, trackingStoppedIntentFilter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,9 +114,9 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
// handle action bar options menu selection
|
||||
switch (item.getItemId()) {
|
||||
|
||||
// CASE SETTINGS
|
||||
case R.id.action_settings:
|
||||
LogHelper.v(LOG_TAG, "Settings was selected");
|
||||
// CASE ABOUT
|
||||
case R.id.action_bar_about:
|
||||
LogHelper.v(LOG_TAG, "About was selected"); // TODO remove
|
||||
return true;
|
||||
|
||||
// CASE DEFAULT
|
||||
|
@ -116,7 +128,7 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
outState.putBoolean(INSTANCE_TRACKING_STARTED, mTracking);
|
||||
outState.putBoolean(INSTANCE_TRACKING_STATE, mTracking);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
|
@ -132,6 +144,15 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
// disable broadcast receiver
|
||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(mTrackingStoppedReceiver);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
|
@ -213,31 +234,33 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
/* Handles tap on the record button */
|
||||
private void handleFloatingActionButtonClick(View view) {
|
||||
if (mTracking) {
|
||||
// show snackbar
|
||||
Snackbar.make(view, R.string.snackbar_message_tracking_stopped, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
|
||||
|
||||
// change state
|
||||
mFloatingActionButton.setImageResource(R.drawable.ic_fiber_manual_record_white_24dp);
|
||||
mTracking = false;
|
||||
// --> is handled by broadcast receiver
|
||||
|
||||
// stop tracker service
|
||||
Intent intent = new Intent(this, TrackerService.class);
|
||||
intent.setAction(ACTION_STOP);
|
||||
startService(intent);
|
||||
LogHelper.v(LOG_TAG, "Stopping tracker service.");
|
||||
|
||||
|
||||
} else {
|
||||
// show snackbar
|
||||
Snackbar.make(view, R.string.snackbar_message_tracking_started, Snackbar.LENGTH_SHORT).setAction("Action", null).show();
|
||||
|
||||
// change state
|
||||
mFloatingActionButton.setImageResource(R.drawable.ic_fiber_manual_record_red_24dp);
|
||||
mTracking = true;
|
||||
setFloatingActionButtonState();
|
||||
|
||||
// get last location from MainActivity Fragment
|
||||
Location lastLocation = mMainActivityFragment.getCurrentBestLocation();
|
||||
|
||||
// start tracker service
|
||||
Intent intent = new Intent(this, TrackerService.class);
|
||||
intent.setAction(ACTION_START);
|
||||
intent.putExtra(EXTRA_LAST_LOCATION, lastLocation);
|
||||
startService(intent);
|
||||
LogHelper.v(LOG_TAG, "Starting tracker service.");
|
||||
}
|
||||
|
||||
// update tracking state in MainActivityFragment
|
||||
|
@ -274,4 +297,20 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
|||
return permissions;
|
||||
}
|
||||
|
||||
|
||||
/* Creates receiver for stopped tracking */
|
||||
private BroadcastReceiver createTrackingStoppedReceiver() {
|
||||
return new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// change state
|
||||
mTracking = false;
|
||||
setFloatingActionButtonState();
|
||||
|
||||
// pass tracking state to MainActivityFragment
|
||||
mMainActivityFragment.setTrackingState(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -74,7 +74,8 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
private ItemizedIconOverlay mMyLocationOverlay;
|
||||
private ItemizedIconOverlay mTrackOverlay;
|
||||
private Location mCurrentBestLocation;
|
||||
private boolean mTacking;
|
||||
private boolean mTrackerServiceRunning;
|
||||
private boolean mLocalTrackerRunning;
|
||||
|
||||
|
||||
/* Constructor (default) */
|
||||
|
@ -99,16 +100,11 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
}
|
||||
|
||||
// restore tracking state
|
||||
mTacking = false;
|
||||
mTrackerServiceRunning = false;
|
||||
if (savedInstanceState != null) {
|
||||
mTacking = savedInstanceState.getBoolean(INSTANCE_TRACKING_STARTED, false);
|
||||
mTrackerServiceRunning = savedInstanceState.getBoolean(INSTANCE_TRACKING_STATE, false);
|
||||
}
|
||||
|
||||
// register broadcast receiver for new WayPoints
|
||||
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
||||
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
||||
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
||||
|
||||
// acquire reference to Location Manager
|
||||
mLocationManager = (LocationManager) mActivity.getSystemService(Context.LOCATION_SERVICE);
|
||||
|
||||
|
@ -134,6 +130,11 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||
}
|
||||
|
||||
// register broadcast receiver for new WayPoints
|
||||
mTrackUpdatedReceiver = createTrackUpdatedReceiver();
|
||||
IntentFilter trackUpdatedIntentFilter = new IntentFilter(ACTION_TRACK_UPDATED);
|
||||
LocalBroadcastManager.getInstance(mActivity).registerReceiver(mTrackUpdatedReceiver, trackUpdatedIntentFilter);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,7 +166,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
mCurrentBestLocation = savedInstanceState.getParcelable(INSTANCE_CURRENT_LOCATION);
|
||||
} else if (mCurrentBestLocation != null) {
|
||||
// fallback or first run: set map to current position
|
||||
GeoPoint position = new GeoPoint(mCurrentBestLocation.getLatitude(), mCurrentBestLocation.getLongitude());
|
||||
GeoPoint position = convertToGeoPoint(mCurrentBestLocation);
|
||||
mController.setCenter(position);
|
||||
mController.setZoom(16);
|
||||
}
|
||||
|
@ -184,8 +185,8 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
mMapView.getOverlays().add(compassOverlay);
|
||||
|
||||
// mark user's location on map
|
||||
if (mCurrentBestLocation != null) {
|
||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation), mTacking);
|
||||
if (mCurrentBestLocation != null && !mTrackerServiceRunning) {
|
||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||
}
|
||||
|
||||
|
@ -197,8 +198,21 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// start tracking position
|
||||
startFindingLocation();
|
||||
// start preliminary tracking - if no TrackerService is running
|
||||
if (!mTrackerServiceRunning) {
|
||||
startPreliminaryTracking();
|
||||
}
|
||||
|
||||
// center map on current position - if TrackerService is running
|
||||
if (mTrackerServiceRunning) {
|
||||
mController.setCenter(convertToGeoPoint(mCurrentBestLocation));
|
||||
}
|
||||
|
||||
// draw track on map - if available
|
||||
if (mTrack != null) {
|
||||
drawTrackOverlay(mTrack);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -206,8 +220,8 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
// disable location listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
// disable preliminary location listeners
|
||||
stopPreliminaryTracking();
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,9 +229,6 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
public void onDestroyView(){
|
||||
super.onDestroyView();
|
||||
|
||||
// unregister broadcast receiver
|
||||
LocalBroadcastManager.getInstance(mActivity).unregisterReceiver(mTrackUpdatedReceiver);
|
||||
|
||||
// deactivate map
|
||||
mMapView.onDetach();
|
||||
}
|
||||
|
@ -228,6 +239,9 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
// reset first start state
|
||||
mFirstStart = true;
|
||||
|
||||
// disable broadcast receivers
|
||||
LocalBroadcastManager.getInstance(mActivity).unregisterReceiver(mTrackUpdatedReceiver);
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
@ -239,7 +253,7 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
switch (item.getItemId()) {
|
||||
|
||||
// CASE MY LOCATION
|
||||
case R.id.action_my_location:
|
||||
case R.id.action_bar_my_location:
|
||||
|
||||
Toast.makeText(mActivity, mActivity.getString(R.string.toast_message_my_location), Toast.LENGTH_LONG).show();
|
||||
|
||||
|
@ -253,12 +267,11 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
GeoPoint position;
|
||||
if (mCurrentBestLocation != null) {
|
||||
// app has a current best estimate location
|
||||
position = new GeoPoint(mCurrentBestLocation.getLatitude(), mCurrentBestLocation.getLongitude());
|
||||
} else {
|
||||
// app does not have any location fix
|
||||
mCurrentBestLocation = LocationHelper.determineLastKnownLocation(mLocationManager);
|
||||
position = new GeoPoint(mCurrentBestLocation.getLatitude(), mCurrentBestLocation.getLongitude());
|
||||
}
|
||||
position = convertToGeoPoint(mCurrentBestLocation);
|
||||
|
||||
// center map on current position
|
||||
mController.setCenter(position);
|
||||
|
@ -284,26 +297,45 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
outState.putInt(INSTANCE_ZOOM_LEVEL, mMapView.getZoomLevel());
|
||||
outState.putParcelable(INSTANCE_CURRENT_LOCATION, mCurrentBestLocation);
|
||||
outState.putParcelable(INSTANCE_TRACK, mTrack);
|
||||
outState.putBoolean(INSTANCE_TRACKING_STARTED, mTacking);
|
||||
outState.putBoolean(INSTANCE_TRACKING_STATE, mTrackerServiceRunning);
|
||||
super.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
|
||||
/* Sets tracking state */
|
||||
public void setTrackingState (boolean trackingStarted) {
|
||||
mTacking = trackingStarted;
|
||||
/* Setter for tracking state */
|
||||
public void setTrackingState (boolean trackingState) {
|
||||
mTrackerServiceRunning = trackingState;
|
||||
|
||||
// turn on/off tracking for MainActivity Fragment - prevent double tracking
|
||||
if (mTrackerServiceRunning) {
|
||||
stopPreliminaryTracking();
|
||||
} else if (!mLocalTrackerRunning){
|
||||
startPreliminaryTracking();
|
||||
if (mTrack != null) {
|
||||
drawTrackOverlay(mTrack);
|
||||
}
|
||||
}
|
||||
|
||||
// update marker
|
||||
updateMyLocationMarker();
|
||||
LogHelper.v(LOG_TAG, "TrackingState: " + trackingState);
|
||||
}
|
||||
|
||||
|
||||
/* Start finding location for map */
|
||||
private void startFindingLocation() {
|
||||
/* Getter for current best location */
|
||||
public Location getCurrentBestLocation() {
|
||||
return mCurrentBestLocation;
|
||||
}
|
||||
|
||||
|
||||
/* 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 (locationProviders.contains(LocationManager.NETWORK_PROVIDER)) {
|
||||
mNetworkListener = createLocationListener();
|
||||
}
|
||||
|
@ -313,6 +345,14 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
/* Removes gps and network location listeners */
|
||||
private void stopPreliminaryTracking() {
|
||||
mLocalTrackerRunning = false;
|
||||
// remove listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
}
|
||||
|
||||
|
||||
/* Creates listener for changes in location status */
|
||||
private LocationListener createLocationListener() {
|
||||
return new LocationListener() {
|
||||
|
@ -321,7 +361,6 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
if (LocationHelper.isBetterLocation(location, mCurrentBestLocation)) {
|
||||
// save location
|
||||
mCurrentBestLocation = location;
|
||||
LogHelper.v(LOG_TAG, "Location isBetterLocation(!): " + location.getProvider()); // TODO remove
|
||||
// mark user's new location on map and remove last marker
|
||||
updateMyLocationMarker();
|
||||
}
|
||||
|
@ -345,15 +384,18 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
/* Updates marker for current user location */
|
||||
private void updateMyLocationMarker() {
|
||||
mMapView.getOverlays().remove(mMyLocationOverlay);
|
||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation),mTacking);
|
||||
// only update while not tracking
|
||||
if (!mTrackerServiceRunning) {
|
||||
mMyLocationOverlay = MapHelper.createMyLocationOverlay(mActivity, mCurrentBestLocation, LocationHelper.isNewLocation(mCurrentBestLocation));
|
||||
mMapView.getOverlays().add(mMyLocationOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Draws track onto overlay */
|
||||
private void drawTrackOverlay(Track track) {
|
||||
mMapView.getOverlays().remove(mTrackOverlay);
|
||||
mTrackOverlay = MapHelper.createTrackOverlay(mActivity, track);
|
||||
mTrackOverlay = MapHelper.createTrackOverlay(mActivity, track, mTrackerServiceRunning);
|
||||
mMapView.getOverlays().add(mTrackOverlay);
|
||||
}
|
||||
|
||||
|
@ -370,16 +412,29 @@ public class MainActivityFragment extends Fragment implements TrackbookKeys {
|
|||
return new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.hasExtra(EXTRA_TRACK)) {
|
||||
if (intent.hasExtra(EXTRA_TRACK) && intent.hasExtra(EXTRA_LAST_LOCATION)) {
|
||||
// draw track on map
|
||||
mTrack = intent.getParcelableExtra(EXTRA_TRACK);
|
||||
drawTrackOverlay(mTrack);
|
||||
Toast.makeText(mActivity, "New WayPoint.", Toast.LENGTH_LONG).show(); // TODO Remove
|
||||
// center map over last location
|
||||
mCurrentBestLocation = intent.getParcelableExtra(EXTRA_LAST_LOCATION);
|
||||
mController.setCenter(convertToGeoPoint(mCurrentBestLocation));
|
||||
// clear intent
|
||||
intent.removeExtra(EXTRA_TRACK);
|
||||
intent.removeExtra(EXTRA_LAST_LOCATION);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/* Converts Location to GeoPoint */
|
||||
private GeoPoint convertToGeoPoint (Location location) {
|
||||
return new GeoPoint(location.getLatitude(), location.getLongitude());
|
||||
}
|
||||
|
||||
|
||||
/* Saves state of map */
|
||||
private void saveMaoState(Context context) {
|
||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.y20k.trackbook.core.Track;
|
|||
import org.y20k.trackbook.core.WayPoint;
|
||||
import org.y20k.trackbook.helpers.LocationHelper;
|
||||
import org.y20k.trackbook.helpers.LogHelper;
|
||||
import org.y20k.trackbook.helpers.NotificationHelper;
|
||||
import org.y20k.trackbook.helpers.TrackbookKeys;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -73,27 +74,40 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
// create a new track
|
||||
mTrack = new Track();
|
||||
|
||||
// add first location to 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(CONSTANT_MAXIMAL_DURATION, CONSTANT_TRACKING_INTERVAL) {
|
||||
mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) {
|
||||
@Override
|
||||
public void onTick(long l) {
|
||||
public void onTick(long millisUntilFinished) {
|
||||
// update track duration
|
||||
mTrack.setTrackDuration(EIGHT_HOURS_IN_MILLISECONDS - millisUntilFinished);
|
||||
// try to add WayPoint to Track
|
||||
addWayPointToTrack();
|
||||
// update notification
|
||||
NotificationHelper.update(mTrack, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
// TODO
|
||||
// remove listeners
|
||||
stopFindingLocation();
|
||||
}
|
||||
};
|
||||
mTimer.start();
|
||||
|
||||
// create gps and network location listeners
|
||||
startFindingLocation();
|
||||
|
||||
}
|
||||
|
||||
// ACTION STOP
|
||||
|
@ -104,7 +118,7 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
mTimer.cancel();
|
||||
|
||||
// remove listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
stopFindingLocation();
|
||||
}
|
||||
|
||||
// START_STICKY is used for services that are explicitly started and stopped as needed
|
||||
|
@ -124,7 +138,7 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
LogHelper.v(LOG_TAG, "onDestroy called.");
|
||||
|
||||
// remove listeners
|
||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||
stopFindingLocation();
|
||||
|
||||
// cancel notification
|
||||
stopForeground(true);
|
||||
|
@ -162,6 +176,7 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
Intent i = new Intent();
|
||||
i.setAction(ACTION_TRACK_UPDATED);
|
||||
i.putExtra(EXTRA_TRACK, mTrack);
|
||||
i.putExtra(EXTRA_LAST_LOCATION, mCurrentBestLocation);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i);
|
||||
}
|
||||
|
||||
|
@ -185,11 +200,11 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
}
|
||||
|
||||
public void onProviderEnabled(String provider) {
|
||||
// TODO do something
|
||||
LogHelper.v(LOG_TAG, "Location provider enabled: " + provider);
|
||||
}
|
||||
|
||||
public void onProviderDisabled(String provider) {
|
||||
// TODO do something
|
||||
LogHelper.v(LOG_TAG, "Location provider disabled: " + provider);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -197,7 +212,9 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
|
||||
/* Creates gps and network location listeners */
|
||||
private void startFindingLocation() {
|
||||
LogHelper.v(LOG_TAG, "Setting up location listeners.");
|
||||
LogHelper.v(LOG_TAG, "startFindingLocation"); // TODO remove
|
||||
// put up notification
|
||||
NotificationHelper.show(this,mTrack);
|
||||
|
||||
// register location listeners and request updates
|
||||
List locationProviders = mLocationManager.getProviders(true);
|
||||
|
@ -210,4 +227,24 @@ public class TrackerService extends Service implements TrackbookKeys {
|
|||
}
|
||||
|
||||
|
||||
/* Removes gps and network location listeners */
|
||||
private void stopFindingLocation() {
|
||||
LogHelper.v(LOG_TAG, "stopFindingLocation"); // TODO remove
|
||||
// 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);
|
||||
|
||||
// // cancel notification
|
||||
// NotificationHelper.stop();
|
||||
// change notification
|
||||
NotificationHelper.update(mTrack, false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.y20k.trackbook.core;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Location;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
@ -27,6 +26,7 @@ import org.y20k.trackbook.helpers.TrackbookKeys;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -39,9 +39,9 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
|
||||
|
||||
/* Main class variables */
|
||||
private Context mContext;
|
||||
private List<WayPoint> mWayPoints;
|
||||
private float mTrackLength;
|
||||
private long mTrackDuration;
|
||||
|
||||
|
||||
/* Constructor */
|
||||
|
@ -72,12 +72,6 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
};
|
||||
|
||||
|
||||
/* Set mContext needed by */
|
||||
public void setContext(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
|
||||
/* Adds new waypoint */
|
||||
public WayPoint addWayPoint(Location location) {
|
||||
// add up distance
|
||||
|
@ -105,6 +99,12 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
}
|
||||
|
||||
|
||||
/* Setter for duration of track */
|
||||
public void setTrackDuration(long trackDuration) {
|
||||
mTrackDuration = trackDuration;
|
||||
}
|
||||
|
||||
|
||||
/* Getter for mWayPoints */
|
||||
public List<WayPoint> getWayPoints() {
|
||||
return mWayPoints;
|
||||
|
@ -117,12 +117,25 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
}
|
||||
|
||||
|
||||
/* Getter for duration of track */
|
||||
public String getTrackDuration() {
|
||||
return convertToReadableTime(mTrackDuration);
|
||||
}
|
||||
|
||||
|
||||
/* Getter for distance of track */
|
||||
public String getTrackDistance() {
|
||||
float trackDistance = mWayPoints.get(mWayPoints.size()-1).getDistanceToStartingPoint();
|
||||
|
||||
return String.format ("%.0f", trackDistance) + "m";
|
||||
}
|
||||
|
||||
|
||||
/* Getter for location of specific WayPoint */
|
||||
public Location getWayPointLocation(int index) {
|
||||
return mWayPoints.get(index).getLocation();
|
||||
}
|
||||
|
||||
|
||||
/* Adds distance to given location to length of track */
|
||||
private float addDistanceToTrack(Location location) {
|
||||
// get number of previously recorded waypoints
|
||||
|
@ -139,6 +152,14 @@ public class Track implements TrackbookKeys, Parcelable {
|
|||
}
|
||||
|
||||
|
||||
/* Converts milliseconds to hh:mm:ss */
|
||||
private String convertToReadableTime(long milliseconds) {
|
||||
return String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(milliseconds),
|
||||
TimeUnit.MILLISECONDS.toMinutes(milliseconds) % TimeUnit.HOURS.toMinutes(1),
|
||||
TimeUnit.MILLISECONDS.toSeconds(milliseconds) % TimeUnit.MINUTES.toSeconds(1));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
|
|
|
@ -27,19 +27,12 @@ import java.util.List;
|
|||
/**
|
||||
* LocationHelper class
|
||||
*/
|
||||
public final class LocationHelper {
|
||||
public final class LocationHelper implements TrackbookKeys {
|
||||
|
||||
/* Define log tag */
|
||||
private static final String LOG_TAG = LocationHelper.class.getSimpleName();
|
||||
|
||||
|
||||
/* Main class variables */
|
||||
// private static final int TWO_MINUTES = 1000 * 1000 * 60 * 2;
|
||||
private static final long FIVE_MINUTES = 5L * 60000000000L; // 2 minutes
|
||||
private static final long TWO_MINUTES = 2L * 60000000000L; // 2 minutes
|
||||
private static final long TWENTY_SECONDS = 20000000000L; // 20 seconds
|
||||
|
||||
|
||||
/* Determines last known location */
|
||||
public static Location determineLastKnownLocation(LocationManager locationManager) {
|
||||
// define variables
|
||||
|
@ -72,13 +65,14 @@ public final class LocationHelper {
|
|||
}
|
||||
}
|
||||
|
||||
// return best estimate location
|
||||
if (isBetterLocation(networkLocation, gpsLocation)) {
|
||||
LogHelper.v(LOG_TAG, "Best last known location came from: " + networkLocation.getProvider()); // TODO remove
|
||||
if (gpsLocation == null) {
|
||||
return networkLocation;
|
||||
} else {
|
||||
LogHelper.v(LOG_TAG, "Best last known location came from: " + gpsLocation.getProvider()); // TODO remove
|
||||
} else if (networkLocation == null) {
|
||||
return gpsLocation;
|
||||
} else if (isBetterLocation(gpsLocation, networkLocation)) {
|
||||
return gpsLocation;
|
||||
} else {
|
||||
return networkLocation;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,8 +88,8 @@ public final class LocationHelper {
|
|||
|
||||
// check whether the new location fix is newer or older
|
||||
long timeDelta = location.getElapsedRealtimeNanos() - currentBestLocation.getElapsedRealtimeNanos();
|
||||
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
|
||||
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
|
||||
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES_IN_NANOSECONDS;
|
||||
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES_IN_NANOSECONDS;
|
||||
boolean isNewer = timeDelta > 0;
|
||||
|
||||
// if it's been more than two minutes since the current location, use the new location because the user has likely moved
|
||||
|
@ -118,16 +112,12 @@ public final class LocationHelper {
|
|||
|
||||
// determine location quality using a combination of timeliness and accuracy
|
||||
if (isMoreAccurate) {
|
||||
LogHelper.v(LOG_TAG, "Location isMoreAccurate: " + location.getProvider()); // TODO remove
|
||||
return true;
|
||||
} else if (isNewer && !isLessAccurate) {
|
||||
LogHelper.v(LOG_TAG, "Location isNewer && !isLessAccurate: " + location.getProvider()); // TODO remove
|
||||
return true;
|
||||
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
|
||||
LogHelper.v(LOG_TAG, "Location isNewer && !isSignificantlyLessAccurate && isFromSameProvider: " + location.getProvider()); // TODO remove
|
||||
return true;
|
||||
}
|
||||
LogHelper.v(LOG_TAG, "Location is not better: " + location.getProvider()); // TODO remove
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -138,7 +128,7 @@ public final class LocationHelper {
|
|||
return false;
|
||||
} else {
|
||||
long locationTime = SystemClock.elapsedRealtimeNanos() - location.getElapsedRealtimeNanos();
|
||||
return locationTime < TWO_MINUTES;
|
||||
return locationTime < TWO_MINUTES_IN_NANOSECONDS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -148,15 +138,15 @@ public final class LocationHelper {
|
|||
float distance = newLocation.distanceTo(lastLocation);
|
||||
long timeDifference = newLocation.getElapsedRealtimeNanos() - lastLocation.getElapsedRealtimeNanos();
|
||||
|
||||
// distance is bigger than 10 meters and time difference bigger than 20 seconds
|
||||
return distance > 10 && timeDifference >= TWENTY_SECONDS;
|
||||
// distance is bigger than 10 meters and time difference bigger than 12 seconds
|
||||
return distance > 10 && timeDifference >= TWELVE_SECONDS_IN_NANOSECONDS;
|
||||
}
|
||||
|
||||
|
||||
/* Checks if given location is a stop over */
|
||||
public static boolean isStopOver(Location lastLocation, Location newLocation) {
|
||||
long timeDifference = newLocation.getElapsedRealtimeNanos() - lastLocation.getElapsedRealtimeNanos();
|
||||
return timeDifference >= FIVE_MINUTES;
|
||||
return timeDifference >= FIVE_MINUTES_IN_NANOSECONDS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.graphics.drawable.Drawable;
|
|||
import android.location.Location;
|
||||
import android.support.v7.widget.AppCompatDrawableManager;
|
||||
import android.text.format.DateFormat;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.osmdroid.util.GeoPoint;
|
||||
import org.osmdroid.views.overlay.ItemizedIconOverlay;
|
||||
|
@ -42,17 +43,14 @@ public final class MapHelper {
|
|||
private static final String LOG_TAG = MapHelper.class.getSimpleName();
|
||||
|
||||
|
||||
/* Creates icon overlay for current position */
|
||||
public static ItemizedIconOverlay createMyLocationOverlay(Context context, Location currentBestLocation, boolean locationIsNew, boolean trackingStarted) {
|
||||
/* Creates icon overlay for current position (used in MainActivity Fragment) */
|
||||
public static ItemizedIconOverlay createMyLocationOverlay(Context context, Location currentBestLocation, boolean locationIsNew) {
|
||||
|
||||
final ArrayList<OverlayItem> overlayItems = new ArrayList<>();
|
||||
LogHelper.v(LOG_TAG, "Location is new? " + locationIsNew + " Provider: " + currentBestLocation.getProvider()); // TODO remove
|
||||
|
||||
// create marker
|
||||
Drawable newMarker;
|
||||
if (trackingStarted) {
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_red_24dp);
|
||||
} else if (locationIsNew) {
|
||||
if (locationIsNew) {
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_blue_24dp);
|
||||
} else {
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_grey_24dp);
|
||||
|
@ -83,20 +81,62 @@ public final class MapHelper {
|
|||
|
||||
|
||||
/* Creates icon overlay for track */
|
||||
public static ItemizedIconOverlay createTrackOverlay(Context context, Track track){
|
||||
public static ItemizedIconOverlay createTrackOverlay(final Context context, Track track, boolean trackingActive){
|
||||
|
||||
WayPoint wayPoint;
|
||||
boolean currentPosition;
|
||||
final int trackSize = track.getSize();
|
||||
final List<WayPoint> wayPoints = track.getWayPoints();
|
||||
final ArrayList<OverlayItem> overlayItems = new ArrayList<>();
|
||||
|
||||
for (WayPoint wayPoint : wayPoints) {
|
||||
for (int i = 0 ; i < track.getSize() ; i++) {
|
||||
// get waypoint and check if it is current position
|
||||
wayPoint = wayPoints.get(i);
|
||||
currentPosition = i == trackSize - 1;
|
||||
|
||||
// create marker
|
||||
Drawable newMarker;
|
||||
|
||||
// CASE 1: Tracking active and waypoint is not current position
|
||||
if (trackingActive && !currentPosition) {
|
||||
if (wayPoint.getIsStopOver()) {
|
||||
// stop over marker
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_grey_24dp);
|
||||
} else {
|
||||
// default marker for this case
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_red_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
// CASE 2: Tracking active and waypoint is current position
|
||||
else if (trackingActive && currentPosition) {
|
||||
if (wayPoint.getIsStopOver()) {
|
||||
// stop over marker
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_grey_24dp);
|
||||
} else {
|
||||
// default marker for this case
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_dot_red_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
// CASE 3: Tracking not active and waypoint is not current position
|
||||
else if (!trackingActive && !currentPosition) {
|
||||
if (wayPoint.getIsStopOver()) {
|
||||
// stop over marker
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_grey_24dp);
|
||||
} else {
|
||||
// default marker for this case
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_blue_24dp);
|
||||
}
|
||||
final String title = Float.toString(wayPoint.getDistanceToStartingPoint());
|
||||
}
|
||||
|
||||
// CASE 4: Tracking not active and waypoint is current position
|
||||
else {
|
||||
// default marker
|
||||
newMarker = AppCompatDrawableManager.get().getDrawable(context, R.drawable.ic_my_location_crumb_blue_24dp);
|
||||
}
|
||||
|
||||
final String title = Float.toString(wayPoint.getDistanceToStartingPoint()) + " (" + wayPoint.getLocation().getProvider() + ")";
|
||||
final String description = DateFormat.getDateFormat(context).format(wayPoint.getLocation().getTime());
|
||||
final GeoPoint position = new GeoPoint(wayPoint.getLocation().getLatitude(), wayPoint.getLocation().getLongitude());
|
||||
OverlayItem overlayItem = new OverlayItem(title, description, position);
|
||||
|
@ -111,6 +151,7 @@ public final class MapHelper {
|
|||
new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
|
||||
@Override
|
||||
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
|
||||
Toast.makeText(context, "Measured distance: " + item.getTitle(), Toast.LENGTH_LONG).show(); // TODO make string
|
||||
LogHelper.v(LOG_TAG, "Tap on a track crumb icon detected. Measured distance: " + item.getTitle());
|
||||
return true;
|
||||
}
|
||||
|
@ -125,6 +166,4 @@ public final class MapHelper {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -1,7 +1,177 @@
|
|||
/**
|
||||
* NotificationHelper.java
|
||||
* Implements the NotificationHelper class
|
||||
* A NotificationHelper creates and configures 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.helpers;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
|
||||
import org.y20k.trackbook.MainActivity;
|
||||
import org.y20k.trackbook.R;
|
||||
import org.y20k.trackbook.TrackerService;
|
||||
import org.y20k.trackbook.core.Track;
|
||||
|
||||
|
||||
/**
|
||||
* Created by solaris on 29/07/16.
|
||||
* NotificationHelper class
|
||||
*/
|
||||
public class NotificationHelper {
|
||||
public class NotificationHelper implements TrackbookKeys {
|
||||
|
||||
/* Define log tag */
|
||||
private static final String LOG_TAG = NotificationHelper.class.getSimpleName();
|
||||
|
||||
|
||||
/* Main class variables */
|
||||
private static Notification mNotification;
|
||||
private static Service mService;
|
||||
|
||||
/* Create and put up notification */
|
||||
public static void show(final Service service, Track track) {
|
||||
// save service
|
||||
mService = service;
|
||||
|
||||
// build notification
|
||||
mNotification = getNotificationBuilder(track, true).build();
|
||||
|
||||
// display notification
|
||||
mService.startForeground(TRACKER_SERVICE_NOTIFICATION_ID, mNotification);
|
||||
}
|
||||
|
||||
|
||||
/* Updates the notification */
|
||||
public static void update(Track track, boolean tracking) {
|
||||
|
||||
// build notification
|
||||
mNotification = getNotificationBuilder(track, tracking).build();
|
||||
|
||||
// display updated notification
|
||||
NotificationManager notificationManager = (NotificationManager) mService.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(TRACKER_SERVICE_NOTIFICATION_ID, mNotification);
|
||||
|
||||
if (!tracking) {
|
||||
// make notification swipe-able
|
||||
mService.stopForeground(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Stop displaying notification */
|
||||
public static void stop() {
|
||||
if (mService != null) {
|
||||
mService.stopForeground(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Creates a notification builder */
|
||||
private static NotificationCompat.Builder getNotificationBuilder(Track track, boolean tracking) {
|
||||
|
||||
String contentText = mService.getString(R.string.notification_content_distance) + ": " + track.getTrackDistance() + " | " +
|
||||
mService.getString(R.string.notification_content_duration) + " : " + track.getTrackDuration();
|
||||
|
||||
// explicit intent for notification tap
|
||||
Intent tapActionIntent = new Intent(mService, MainActivity.class);
|
||||
|
||||
// explicit intent for stopping playback
|
||||
Intent stopActionIntent = new Intent(mService, TrackerService.class);
|
||||
stopActionIntent.setAction(ACTION_STOP);
|
||||
|
||||
// artificial back stack for started Activity.
|
||||
// -> navigating backward from the Activity leads to Home screen.
|
||||
TaskStackBuilder stackBuilder = TaskStackBuilder.create(mService);
|
||||
// // backstack: adds back stack for Intent (but not the Intent itself)
|
||||
// stackBuilder.addParentStack(MainActivity.class);
|
||||
// backstack: add explicit intent for notification tap
|
||||
stackBuilder.addNextIntent(tapActionIntent);
|
||||
|
||||
// pending intent wrapper for notification tap
|
||||
PendingIntent tapActionPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
// pending intent wrapper for notification stop action
|
||||
PendingIntent stopActionPendingIntent = PendingIntent.getService(mService, 0, stopActionIntent, 0);
|
||||
|
||||
// construct notification in builder
|
||||
NotificationCompat.Builder builder;
|
||||
builder = new NotificationCompat.Builder(mService);
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
builder.setShowWhen(false);
|
||||
builder.setContentIntent(tapActionPendingIntent);
|
||||
builder.setSmallIcon(R.drawable.ic_notification_small_24dp);
|
||||
builder.setLargeIcon(getNotificationIconLarge(tracking));
|
||||
if (tracking) {
|
||||
builder.addAction(R.drawable.ic_stop_white_36dp, mService.getString(R.string.notification_stop), stopActionPendingIntent);
|
||||
builder.setContentTitle(mService.getString(R.string.notification_title_trackbook_running));
|
||||
builder.setContentText(contentText);
|
||||
// third line of text - only appears in expanded view
|
||||
// builder.setSubText();
|
||||
} else {
|
||||
builder.setContentTitle(mService.getString(R.string.notification_title_trackbook_not_running));
|
||||
builder.setContentText(contentText);
|
||||
// third line of text - only appears in expanded view
|
||||
// builder.setSubText();
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
/* Get station image for notification's large icon */
|
||||
private static Bitmap getNotificationIconLarge(boolean tracking) {
|
||||
|
||||
// get dimensions
|
||||
Resources resources = mService.getResources();
|
||||
int height = (int) resources.getDimension(android.R.dimen.notification_large_icon_height);
|
||||
int width = (int) resources.getDimension(android.R.dimen.notification_large_icon_width);
|
||||
|
||||
Bitmap bitmap;
|
||||
if (tracking) {
|
||||
bitmap = getBitmap(R.drawable.ic_notification_large_tracking_48dp);
|
||||
} else {
|
||||
bitmap = getBitmap(R.drawable.ic_notification_large_not_tracking_48dp);
|
||||
}
|
||||
|
||||
return Bitmap.createScaledBitmap(bitmap, width, height, false);
|
||||
}
|
||||
|
||||
|
||||
/* Return a bitmap for a given resource id of a vector drawable */
|
||||
private static Bitmap getBitmap(int resource) {
|
||||
VectorDrawableCompat drawable = VectorDrawableCompat.create(mService.getResources(), resource, null);
|
||||
if (drawable != null) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -26,9 +26,11 @@ public interface TrackbookKeys {
|
|||
public static final String ACTION_START = "org.y20k.transistor.action.START";
|
||||
public static final String ACTION_STOP = "org.y20k.transistor.action.STOP";
|
||||
public static final String ACTION_TRACK_UPDATED = "TRACK_UPDATED";
|
||||
public static final String ACTION_TRACKING_STOPPED = "TRACKING_STOPPED";
|
||||
|
||||
/* EXTRAS */
|
||||
public static final String EXTRA_TRACK = "TRACK";
|
||||
public static final String EXTRA_LAST_LOCATION = "LAST_LOCATION";
|
||||
|
||||
/* ARGS */
|
||||
public static final String ARG_PERMISSIONS_GRANTED = "ArgPermissionsGranted";
|
||||
|
@ -48,21 +50,21 @@ public interface TrackbookKeys {
|
|||
public static final String INSTANCE_LONGITUDE = "longitude";
|
||||
public static final String INSTANCE_ZOOM_LEVEL = "zoomLevel";
|
||||
public static final String INSTANCE_CURRENT_LOCATION = "currentLocation";
|
||||
public static final String INSTANCE_TRACKING_STARTED = "trackingStarted";
|
||||
public static final String INSTANCE_TRACKING_STATE = "trackingState";
|
||||
public static final String INSTANCE_TRACK = "track";
|
||||
|
||||
/* RESULTS */
|
||||
|
||||
/* CONSTANTS */
|
||||
public static final int CONSTANT_MINIMAL_STOP_TIME = 300000; // equals 5 minutes
|
||||
public static final long CONSTANT_MAXIMAL_DURATION = 43200000; // equals 8 hours
|
||||
public static final long CONSTANT_TRACKING_INTERVAL = 15000; // equals 15 seconds
|
||||
public static final long EIGHT_HOURS_IN_MILLISECONDS = 43200000; // maximum tracking duration
|
||||
public static final long FIFTEEN_SECONDS_IN_MILLISECONDS = 15000; // timer interval for tracking
|
||||
public static final long FIVE_MINUTES_IN_NANOSECONDS = 5L * 60000000000L; // determines a stop over
|
||||
public static final long TWO_MINUTES_IN_NANOSECONDS = 2L * 60000000000L; // defines an old location
|
||||
public static final long TWELVE_SECONDS_IN_NANOSECONDS = 12000000000L; // defines a new location
|
||||
|
||||
|
||||
/* MISC */
|
||||
public static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
|
||||
public static final int LOCATION_STATUS_OFFLINE = 0;
|
||||
public static final int LOCATION_STATUS_OK = 1;
|
||||
public static final int LOCATION_STATUS_GPS_ONLY = 2;
|
||||
public static final int LOCATION_STATUS_NETWORK_ONLY = 3;
|
||||
public static final int TRACKER_SERVICE_NOTIFICATION_ID = 1;
|
||||
|
||||
}
|
||||
|
|
10
app/src/main/res/drawable/ic_my_location_crumb_red_24dp.xml
Normal file
10
app/src/main/res/drawable/ic_my_location_crumb_red_24dp.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="96.0"
|
||||
android:viewportWidth="96.0"
|
||||
android:width="24dp">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/trackbook_red"
|
||||
android:pathData="M48,48m-24,0a24,24 0,1 1,48 0a24,24 0,1 1,-48 0"/>
|
||||
</vector>
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:alpha="0.01" android:height="24dp"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M6,6h12v12H6z"/>
|
||||
</vector>
|
|
@ -4,6 +4,6 @@
|
|||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:fillColor="@color/trackbook_white"
|
||||
android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM20.94,11c-0.46,-4.17 -3.77,-7.48 -7.94,-7.94L13,1h-2v2.06C6.83,3.52 3.52,6.83 3.06,11L1,11v2h2.06c0.46,4.17 3.77,7.48 7.94,7.94L11,23h2v-2.06c4.17,-0.46 7.48,-3.77 7.94,-7.94L23,13v-2h-2.06zM12,19c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
|
||||
</vector>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="48dp"
|
||||
android:viewportHeight="192.0"
|
||||
android:viewportWidth="192.0"
|
||||
android:width="48dp" >
|
||||
<path
|
||||
android:fillColor="@color/trackbook_blue"
|
||||
android:pathData="M96,96m-96,0a96,96 0,1 1,192 0a96,96 0,1 1,-192 0"/>
|
||||
<path
|
||||
android:fillColor="@color/trackbook_white"
|
||||
android:pathData="M48,96a48,46.5 0,1 0,96 0a48,46.5 0,1 0,-96 0z"/>
|
||||
</vector>
|
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="48dp"
|
||||
android:viewportHeight="192.0"
|
||||
android:viewportWidth="192.0"
|
||||
android:width="48dp" >
|
||||
<path
|
||||
android:fillColor="@color/trackbook_blue"
|
||||
android:pathData="M96,96m-96,0a96,96 0,1 1,192 0a96,96 0,1 1,-192 0"/>
|
||||
<path
|
||||
android:fillColor="@color/trackbook_red_dark"
|
||||
android:pathData="M48,96a48,46.5 0,1 0,96 0a48,46.5 0,1 0,-96 0z"/>
|
||||
</vector>
|
12
app/src/main/res/drawable/ic_notification_small_24dp.xml
Normal file
12
app/src/main/res/drawable/ic_notification_small_24dp.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:viewportHeight="96.0"
|
||||
android:viewportWidth="96.0"
|
||||
android:height="24dp"
|
||||
android:width="24dp">
|
||||
<path
|
||||
android:fillColor="@color/trackbook_white"
|
||||
android:pathData="M44,12.99L20.69,8.74L5.12,5.89C2.29,5.38 0,7.44 0,10.49v67.38c0,3.06 2.29,5.96 5.12,6.47l15.57,2.85l22.19,4.05L44,91.46V12.99z"/>
|
||||
<path
|
||||
android:fillColor="@color/trackbook_white"
|
||||
android:pathData="M90.88,5.89L75.31,8.74L53.12,12.79L52,12.99v78.46l23.31,-4.26l15.57,-2.85c2.83,-0.52 5.12,-3.41 5.12,-6.47V10.49C96,7.44 93.71,5.38 90.88,5.89z"/>
|
||||
</vector>
|
10
app/src/main/res/drawable/ic_stop_white_36dp.xml
Normal file
10
app/src/main/res/drawable/ic_stop_white_36dp.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="36dp"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0"
|
||||
android:width="36dp">
|
||||
|
||||
<path
|
||||
android:fillColor="@color/trackbook_white"
|
||||
android:pathData="M6,6h12v12H6z"/>
|
||||
</vector>
|
|
@ -4,16 +4,16 @@
|
|||
tools:context="org.y20k.trackbook.MainActivity">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_my_location"
|
||||
android:id="@+id/action_bar_my_location"
|
||||
android:icon="@drawable/ic_my_location_white_24dp"
|
||||
android:title="@string/menu_my_location"
|
||||
android:visible="true"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:id="@+id/action_bar_about"
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/menu_settings"
|
||||
android:title="@string/menu_about"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
||||
|
|
|
@ -3,8 +3,16 @@
|
|||
<string name="app_name">Trackbook</string>
|
||||
|
||||
<!-- menu entries -->
|
||||
<string name="menu_settings">Settings</string>
|
||||
<string name="menu_my_location">My Location</string>
|
||||
<string name="menu_about">About</string>
|
||||
|
||||
|
||||
<!-- notification -->
|
||||
<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_content_duration">Duration</string>
|
||||
<string name="notification_content_distance">Distance</string>
|
||||
|
||||
<!-- snackbar messages -->
|
||||
<string name="snackbar_message_tracking_stopped">Tracking stopped</string>
|
||||
|
|
Loading…
Reference in a new issue