some Android O-related fixes (location updates should continue to work - notification too)
This commit is contained in:
parent
419448bcbd
commit
ae9b2d8fca
15 changed files with 319 additions and 152 deletions
|
@ -25,6 +25,6 @@ dependencies {
|
||||||
compile 'com.android.support:appcompat-v7:' + supportLibraryVersion
|
compile 'com.android.support:appcompat-v7:' + supportLibraryVersion
|
||||||
compile 'com.android.support:design:' + supportLibraryVersion
|
compile 'com.android.support:design:' + supportLibraryVersion
|
||||||
compile 'com.android.support:cardview-v7:' + supportLibraryVersion
|
compile 'com.android.support:cardview-v7:' + supportLibraryVersion
|
||||||
compile 'org.osmdroid:osmdroid-android:5.6.5'
|
compile 'org.osmdroid:osmdroid-android:' + osmdroidVersion
|
||||||
compile 'com.google.code.gson:gson:2.8.1'
|
compile 'com.google.code.gson:gson:' + gsonVersion
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.y20k.trackbook.action.START" />
|
<action android:name="org.y20k.trackbook.action.START" />
|
||||||
<action android:name="org.y20k.trackbook.action.STOP" />
|
<action android:name="org.y20k.trackbook.action.STOP" />
|
||||||
|
<action android:name="org.y20k.trackbook.action.DISMISS" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@ import android.widget.Toast;
|
||||||
|
|
||||||
import org.y20k.trackbook.helpers.DialogHelper;
|
import org.y20k.trackbook.helpers.DialogHelper;
|
||||||
import org.y20k.trackbook.helpers.LogHelper;
|
import org.y20k.trackbook.helpers.LogHelper;
|
||||||
import org.y20k.trackbook.helpers.NotificationHelper;
|
|
||||||
import org.y20k.trackbook.helpers.TrackbookKeys;
|
import org.y20k.trackbook.helpers.TrackbookKeys;
|
||||||
import org.y20k.trackbook.layout.NonSwipeableViewPager;
|
import org.y20k.trackbook.layout.NonSwipeableViewPager;
|
||||||
|
|
||||||
|
@ -192,8 +191,8 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
|
|
||||||
// save state of Floating Action Button
|
// // save state of Floating Action Button
|
||||||
saveFloatingActionButtonState(this);
|
// saveFloatingActionButtonState(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -291,7 +290,9 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
mViewPager.setCurrentItem(mSelectedTab);
|
mViewPager.setCurrentItem(mSelectedTab);
|
||||||
|
|
||||||
// dismiss notification
|
// dismiss notification
|
||||||
NotificationHelper.stop();
|
Intent intent = new Intent(this, TrackerService.class);
|
||||||
|
intent.setAction(ACTION_DISMISS);
|
||||||
|
startService(intent);
|
||||||
|
|
||||||
// hide Floating Action Button sub menu
|
// hide Floating Action Button sub menu
|
||||||
showFloatingActionButtonMenu(false);
|
showFloatingActionButtonMenu(false);
|
||||||
|
@ -308,7 +309,9 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
Toast.makeText(this, getString(R.string.toast_message_track_clear), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.toast_message_track_clear), Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
// dismiss notification
|
// dismiss notification
|
||||||
NotificationHelper.stop();
|
Intent intent = new Intent(this, TrackerService.class);
|
||||||
|
intent.setAction(ACTION_DISMISS);
|
||||||
|
startService(intent);
|
||||||
|
|
||||||
// hide Floating Action Button sub menu
|
// hide Floating Action Button sub menu
|
||||||
showFloatingActionButtonMenu(false);
|
showFloatingActionButtonMenu(false);
|
||||||
|
@ -326,13 +329,13 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Saves state of Floating Action Button */
|
// /* Saves state of Floating Action Button */
|
||||||
private void saveFloatingActionButtonState(Context context) {
|
// private void saveFloatingActionButtonState(Context context) {
|
||||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
// SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
// SharedPreferences.Editor editor = settings.edit();
|
||||||
editor.putInt(PREFS_FAB_STATE, mFloatingActionButtonState);
|
// editor.putInt(PREFS_FAB_STATE, mFloatingActionButtonState);
|
||||||
editor.apply();
|
// editor.apply();
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
||||||
/* Set up main layout */
|
/* Set up main layout */
|
||||||
|
@ -480,7 +483,13 @@ public class MainActivity extends AppCompatActivity implements TrackbookKeys {
|
||||||
Intent intent = new Intent(this, TrackerService.class);
|
Intent intent = new Intent(this, TrackerService.class);
|
||||||
intent.setAction(ACTION_START);
|
intent.setAction(ACTION_START);
|
||||||
intent.putExtra(EXTRA_LAST_LOCATION, lastLocation);
|
intent.putExtra(EXTRA_LAST_LOCATION, lastLocation);
|
||||||
|
// startService(intent);
|
||||||
|
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
|
||||||
|
startForegroundService(intent);
|
||||||
|
} else {
|
||||||
startService(intent);
|
startService(intent);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show();
|
Toast.makeText(this, getString(R.string.toast_message_location_services_not_ready), Toast.LENGTH_LONG).show();
|
||||||
// change state back
|
// change state back
|
||||||
|
|
|
@ -194,10 +194,10 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
mFirstStart = false;
|
mFirstStart = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// load track from saved instance
|
// // load track from saved instance
|
||||||
if (savedInstanceState != null) {
|
// if (savedInstanceState != null) {
|
||||||
mTrack = savedInstanceState.getParcelable(INSTANCE_TRACK_MAIN_MAP);
|
// mTrack = savedInstanceState.getParcelable(INSTANCE_TRACK_MAIN_MAP);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// mark user's location on map
|
// mark user's location on map
|
||||||
if (mCurrentBestLocation != null && !mTrackerServiceRunning) {
|
if (mCurrentBestLocation != null && !mTrackerServiceRunning) {
|
||||||
|
@ -222,9 +222,9 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
// CASE 1: recording active
|
// CASE 1: recording active
|
||||||
if (mTrackerServiceRunning) {
|
if (mTrackerServiceRunning) {
|
||||||
// request an updated track recording from service
|
// request an updated track recording from service
|
||||||
Intent i = new Intent();
|
Intent intent = new Intent(mActivity, TrackerService.class);
|
||||||
i.setAction(ACTION_TRACK_REQUEST);
|
intent.setAction(ACTION_TRACK_REQUEST);
|
||||||
LocalBroadcastManager.getInstance(mActivity).sendBroadcast(i);
|
mActivity.startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// CASE 2: recording stopped - temp file exists
|
// CASE 2: recording stopped - temp file exists
|
||||||
|
@ -232,13 +232,14 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
// load track from temp file if it exists
|
// load track from temp file if it exists
|
||||||
LoadTempTrackAsyncHelper loadTempTrackAsyncHelper = new LoadTempTrackAsyncHelper();
|
LoadTempTrackAsyncHelper loadTempTrackAsyncHelper = new LoadTempTrackAsyncHelper();
|
||||||
loadTempTrackAsyncHelper.execute();
|
loadTempTrackAsyncHelper.execute();
|
||||||
|
|
||||||
// CASE 3: not recording and no temp file
|
|
||||||
} else if (mTrack != null) {
|
|
||||||
// just draw existing track data (from saved instance)
|
|
||||||
drawTrackOverlay(mTrack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // CASE 3: not recording and no temp file
|
||||||
|
// else if (mTrack != null) {
|
||||||
|
// // just draw existing track data (from saved instance)
|
||||||
|
// drawTrackOverlay(mTrack);
|
||||||
|
// }
|
||||||
|
|
||||||
// show/hide the location off notification bar
|
// show/hide the location off notification bar
|
||||||
toggleLocationOffBar();
|
toggleLocationOffBar();
|
||||||
|
|
||||||
|
@ -385,7 +386,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
outState.putDouble(INSTANCE_LATITUDE_MAIN_MAP, mMapView.getMapCenter().getLatitude());
|
outState.putDouble(INSTANCE_LATITUDE_MAIN_MAP, mMapView.getMapCenter().getLatitude());
|
||||||
outState.putDouble(INSTANCE_LONGITUDE_MAIN_MAP, mMapView.getMapCenter().getLongitude());
|
outState.putDouble(INSTANCE_LONGITUDE_MAIN_MAP, mMapView.getMapCenter().getLongitude());
|
||||||
outState.putInt(INSTANCE_ZOOM_LEVEL_MAIN_MAP, mMapView.getZoomLevel());
|
outState.putInt(INSTANCE_ZOOM_LEVEL_MAIN_MAP, mMapView.getZoomLevel());
|
||||||
outState.putParcelable(INSTANCE_TRACK_MAIN_MAP, mTrack);
|
// outState.putParcelable(INSTANCE_TRACK_MAIN_MAP, mTrack);
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,8 +582,7 @@ public class MainActivityMapFragment extends Fragment implements TrackbookKeys {
|
||||||
/* Loads state tracker service from preferences */
|
/* Loads state tracker service from preferences */
|
||||||
private void loadTrackerServiceState(Context context) {
|
private void loadTrackerServiceState(Context context) {
|
||||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
int fabState = settings.getInt(PREFS_FAB_STATE, FAB_STATE_DEFAULT);
|
mTrackerServiceRunning = settings.getBoolean(PREFS_TRACKER_SERVICE_RUNNING, false);
|
||||||
mTrackerServiceRunning = fabState == FAB_STATE_RECORDING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
|
|
||||||
package org.y20k.trackbook;
|
package org.y20k.trackbook;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
|
@ -37,6 +37,7 @@ import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.content.LocalBroadcastManager;
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
@ -70,7 +71,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
private LocationListener mNetworkListener = null;
|
private LocationListener mNetworkListener = null;
|
||||||
private SettingsContentObserver mSettingsContentObserver;
|
private SettingsContentObserver mSettingsContentObserver;
|
||||||
private Location mCurrentBestLocation;
|
private Location mCurrentBestLocation;
|
||||||
private BroadcastReceiver mTrackRequestReceiver;
|
private Notification mNotification;
|
||||||
|
private NotificationCompat.Builder mNotificationBuilder;
|
||||||
|
private NotificationManager mNotificationManager;
|
||||||
private boolean mTrackerServiceRunning;
|
private boolean mTrackerServiceRunning;
|
||||||
private boolean mLocationSystemSetting;
|
private boolean mLocationSystemSetting;
|
||||||
|
|
||||||
|
@ -79,15 +82,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
// receiver: listen track request issued by the main map - in onResume
|
// prepare notification channel and get NotificationManager
|
||||||
mTrackRequestReceiver = new BroadcastReceiver() {
|
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
@Override
|
NotificationHelper.createNotificationChannel(this);
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
sendTrackUpdate();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
IntentFilter trackRequestReceiverIntentFilter = new IntentFilter(ACTION_TRACK_REQUEST);
|
|
||||||
LocalBroadcastManager.getInstance(this).registerReceiver(mTrackRequestReceiver, trackRequestReceiverIntentFilter);
|
|
||||||
|
|
||||||
// acquire reference to Location Manager
|
// acquire reference to Location Manager
|
||||||
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
||||||
|
@ -100,7 +97,6 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
|
|
||||||
// create content observer for changes in System Settings
|
// create content observer for changes in System Settings
|
||||||
mSettingsContentObserver = new SettingsContentObserver(new Handler());
|
mSettingsContentObserver = new SettingsContentObserver(new Handler());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,7 +112,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
}
|
}
|
||||||
|
|
||||||
// checking for empty intent
|
// checking for empty intent
|
||||||
if (intent == null) {
|
if (intent == null || intent.getAction() == null) {
|
||||||
LogHelper.e(LOG_TAG, "Null-Intent received. Stopping self.");
|
LogHelper.e(LOG_TAG, "Null-Intent received. Stopping self.");
|
||||||
// stopSelf triggers onDestroy
|
// stopSelf triggers onDestroy
|
||||||
stopSelf();
|
stopSelf();
|
||||||
|
@ -129,15 +125,28 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
|
|
||||||
// ACTION STOP
|
// ACTION STOP
|
||||||
else if (intent.getAction().equals(ACTION_STOP) || !mLocationSystemSetting) {
|
else if (intent.getAction().equals(ACTION_STOP) || !mLocationSystemSetting) {
|
||||||
|
mTrackerServiceRunning = false;
|
||||||
if (mTrack != null && mTimer != null) {
|
if (mTrack != null && mTimer != null) {
|
||||||
stopTracking();
|
stopTracking();
|
||||||
|
} else {
|
||||||
|
// handle error - save state
|
||||||
|
saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_DEFAULT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// save changed state of Floating Action Button
|
// ACTION DISMISS
|
||||||
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
|
else if (intent.getAction().equals(ACTION_DISMISS)) {
|
||||||
SharedPreferences.Editor editor = settings.edit();
|
// save state
|
||||||
editor.putInt(PREFS_FAB_STATE, FAB_STATE_SAVE);
|
saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_DEFAULT);
|
||||||
editor.apply();
|
// dismiss notification
|
||||||
|
mNotificationManager.cancel(TRACKER_SERVICE_NOTIFICATION_ID); // todo check if necessary?
|
||||||
|
stopForeground(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ACTION TRACK REQUEST
|
||||||
|
else if (intent.getAction().equals(ACTION_TRACK_REQUEST)) {
|
||||||
|
// send track via broadcast
|
||||||
|
sendTrackUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -156,12 +165,15 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
LogHelper.v(LOG_TAG, "onDestroy called.");
|
LogHelper.v(LOG_TAG, "onDestroy called.");
|
||||||
|
|
||||||
// remove receivers and listeners
|
if (mTrackerServiceRunning) {
|
||||||
stopFindingLocation();
|
stopTracking();
|
||||||
mSensorManager.unregisterListener(this);
|
}
|
||||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(mTrackRequestReceiver);
|
|
||||||
|
|
||||||
// cancel notification
|
// // remove listeners
|
||||||
|
// stopFindingLocation();
|
||||||
|
// mSensorManager.unregisterListener(this);
|
||||||
|
|
||||||
|
// todo describe
|
||||||
stopForeground(true);
|
stopForeground(true);
|
||||||
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
@ -208,6 +220,11 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
// add last location as WayPoint to track
|
// add last location as WayPoint to track
|
||||||
addWayPointToTrack();
|
addWayPointToTrack();
|
||||||
|
|
||||||
|
// put up notification
|
||||||
|
mNotificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANEL_ID_RECORDING_CHANNEL);
|
||||||
|
mNotification = NotificationHelper.getNotification(this, mNotificationBuilder, mTrack, true);
|
||||||
|
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
|
// set timer to retrieve new locations and to prevent endless tracking
|
||||||
mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) {
|
mTimer = new CountDownTimer(EIGHT_HOURS_IN_MILLISECONDS, FIFTEEN_SECONDS_IN_MILLISECONDS) {
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,13 +235,14 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
// try to add WayPoint to Track
|
// try to add WayPoint to Track
|
||||||
addWayPointToTrack();
|
addWayPointToTrack();
|
||||||
// update notification
|
// update notification
|
||||||
NotificationHelper.update(mTrack, true);
|
mNotification = NotificationHelper.getUpdatedNotification(TrackerService.this, mNotificationBuilder, mTrack);
|
||||||
|
mNotificationManager.notify(TRACKER_SERVICE_NOTIFICATION_ID, mNotification);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFinish() {
|
public void onFinish() {
|
||||||
// remove listeners
|
// stop tracking after eight hours
|
||||||
stopFindingLocation();
|
stopTracking();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
mTimer.start();
|
mTimer.start();
|
||||||
|
@ -239,14 +257,14 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
mTrack.setStepCount(-1);
|
mTrack.setStepCount(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// put up notification
|
|
||||||
NotificationHelper.show(this,mTrack);
|
|
||||||
|
|
||||||
// create gps and network location listeners
|
// create gps and network location listeners
|
||||||
startFindingLocation();
|
startFindingLocation();
|
||||||
|
|
||||||
// register content observer for changes in System Settings
|
// register content observer for changes in System Settings
|
||||||
this.getContentResolver().registerContentObserver(android.provider.Settings.Secure.CONTENT_URI, true, mSettingsContentObserver );
|
this.getContentResolver().registerContentObserver(android.provider.Settings.Secure.CONTENT_URI, true, mSettingsContentObserver);
|
||||||
|
|
||||||
|
// start service in foreground
|
||||||
|
startForeground(TRACKER_SERVICE_NOTIFICATION_ID, mNotification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,7 +286,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
saveTempTrackAsyncHelper.execute();
|
saveTempTrackAsyncHelper.execute();
|
||||||
|
|
||||||
// change notification
|
// change notification
|
||||||
NotificationHelper.update(mTrack, false);
|
mNotificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANEL_ID_RECORDING_CHANNEL);
|
||||||
|
mNotification = NotificationHelper.getNotification(this, mNotificationBuilder, mTrack, false);
|
||||||
|
mNotificationManager.notify(TRACKER_SERVICE_NOTIFICATION_ID, mNotification);
|
||||||
|
|
||||||
// remove listeners
|
// remove listeners
|
||||||
stopFindingLocation();
|
stopFindingLocation();
|
||||||
|
@ -276,6 +296,9 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
|
|
||||||
// disable content observer for changes in System Settings
|
// disable content observer for changes in System Settings
|
||||||
this.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
|
this.getContentResolver().unregisterContentObserver(mSettingsContentObserver);
|
||||||
|
|
||||||
|
// todo describe
|
||||||
|
stopForeground(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,7 +326,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
Location firstWayPoint = mTrack.getWayPointLocation(0);
|
Location firstWayPoint = mTrack.getWayPointLocation(0);
|
||||||
float distance = firstWayPoint.distanceTo(lastWayPoint);
|
float distance = firstWayPoint.distanceTo(lastWayPoint);
|
||||||
long timeDifference = lastWayPoint.getElapsedRealtimeNanos() - firstWayPoint.getElapsedRealtimeNanos();
|
long timeDifference = lastWayPoint.getElapsedRealtimeNanos() - firstWayPoint.getElapsedRealtimeNanos();
|
||||||
averageSpeed = distance / ((float)timeDifference / ONE_NANOSECOND);
|
averageSpeed = distance / ((float) timeDifference / ONE_NANOSECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LocationHelper.isNewWayPoint(lastWayPoint, mCurrentBestLocation, averageSpeed)) {
|
if (LocationHelper.isNewWayPoint(lastWayPoint, mCurrentBestLocation, averageSpeed)) {
|
||||||
|
@ -373,6 +396,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
mTrackerServiceRunning = true;
|
mTrackerServiceRunning = true;
|
||||||
}
|
}
|
||||||
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
LocationHelper.registerLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
|
saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_RECORDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -381,6 +405,7 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
// remove listeners
|
// remove listeners
|
||||||
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
LocationHelper.removeLocationListeners(mLocationManager, mGPSListener, mNetworkListener);
|
||||||
mTrackerServiceRunning = false;
|
mTrackerServiceRunning = false;
|
||||||
|
saveTrackerServiceState(mTrackerServiceRunning, FAB_STATE_SAVE);
|
||||||
|
|
||||||
// notify MainActivityMapFragment
|
// notify MainActivityMapFragment
|
||||||
Intent i = new Intent();
|
Intent i = new Intent();
|
||||||
|
@ -391,6 +416,16 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Saves state of Tracker Service and floating Action Button */
|
||||||
|
private void saveTrackerServiceState(boolean trackerServiceRunning, int fabState) {
|
||||||
|
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
SharedPreferences.Editor editor = settings.edit();
|
||||||
|
editor.putBoolean(PREFS_TRACKER_SERVICE_RUNNING, trackerServiceRunning);
|
||||||
|
editor.putInt(PREFS_FAB_STATE, fabState);
|
||||||
|
editor.apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner class: SettingsContentObserver is a custom ContentObserver for changes in Android Settings
|
* Inner class: SettingsContentObserver is a custom ContentObserver for changes in Android Settings
|
||||||
*/
|
*/
|
||||||
|
@ -452,5 +487,4 @@ public class TrackerService extends Service implements TrackbookKeys, SensorEven
|
||||||
* End of inner class
|
* End of inner class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -17,17 +17,18 @@
|
||||||
package org.y20k.trackbook.helpers;
|
package org.y20k.trackbook.helpers;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.os.Build;
|
||||||
import android.support.graphics.drawable.VectorDrawableCompat;
|
import android.support.graphics.drawable.VectorDrawableCompat;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.app.TaskStackBuilder;
|
import android.support.v4.app.TaskStackBuilder;
|
||||||
import android.support.v7.app.NotificationCompat;
|
|
||||||
|
|
||||||
import org.y20k.trackbook.MainActivity;
|
import org.y20k.trackbook.MainActivity;
|
||||||
import org.y20k.trackbook.R;
|
import org.y20k.trackbook.R;
|
||||||
|
@ -44,110 +45,96 @@ public class NotificationHelper implements TrackbookKeys {
|
||||||
private static final String LOG_TAG = NotificationHelper.class.getSimpleName();
|
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 */
|
/* Creates a notification builder */
|
||||||
private static NotificationCompat.Builder getNotificationBuilder(Track track, boolean tracking) {
|
public static Notification getNotification(Context context, NotificationCompat.Builder builder, Track track, boolean tracking) {
|
||||||
|
|
||||||
String contentText = mService.getString(R.string.notification_content_distance) + ": " + track.getTrackDistance() + " | " +
|
// create notification channel
|
||||||
mService.getString(R.string.notification_content_duration) + ": " + track.getTrackDuration();
|
createNotificationChannel(context);
|
||||||
|
|
||||||
|
// build context text for notification builder
|
||||||
|
String contentText = getContextString(context, track);
|
||||||
|
|
||||||
// ACTION: NOTIFICATION TAP
|
// ACTION: NOTIFICATION TAP
|
||||||
Intent tapActionIntent = new Intent(mService, MainActivity.class);
|
Intent tapActionIntent = new Intent(context, MainActivity.class);
|
||||||
tapActionIntent.setAction(ACTION_SHOW_MAP);
|
tapActionIntent.setAction(ACTION_SHOW_MAP);
|
||||||
tapActionIntent.putExtra(EXTRA_TRACK, track);
|
tapActionIntent.putExtra(EXTRA_TRACK, track);
|
||||||
tapActionIntent.putExtra(EXTRA_TRACKING_STATE, tracking);
|
tapActionIntent.putExtra(EXTRA_TRACKING_STATE, tracking);
|
||||||
// artificial back stack for started Activity (https://developer.android.com/training/notify-user/navigation.html#DirectEntry)
|
// artificial back stack for started Activity (https://developer.android.com/training/notify-user/navigation.html#DirectEntry)
|
||||||
TaskStackBuilder tapActionIntentBuilder = TaskStackBuilder.create(mService);
|
TaskStackBuilder tapActionIntentBuilder = TaskStackBuilder.create(context);
|
||||||
tapActionIntentBuilder.addParentStack(MainActivity.class);
|
tapActionIntentBuilder.addParentStack(MainActivity.class);
|
||||||
tapActionIntentBuilder.addNextIntent(tapActionIntent);
|
tapActionIntentBuilder.addNextIntent(tapActionIntent);
|
||||||
// pending intent wrapper for notification tap
|
// pending intent wrapper for notification tap
|
||||||
PendingIntent tapActionPendingIntent = tapActionIntentBuilder.getPendingIntent(10, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent tapActionPendingIntent = tapActionIntentBuilder.getPendingIntent(10, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
|
||||||
// ACTION: NOTIFICATION BUTTON STOP
|
// ACTION: NOTIFICATION BUTTON STOP
|
||||||
Intent stopActionIntent = new Intent(mService, TrackerService.class);
|
Intent stopActionIntent = new Intent(context, TrackerService.class);
|
||||||
stopActionIntent.setAction(ACTION_STOP);
|
stopActionIntent.setAction(ACTION_STOP);
|
||||||
// pending intent wrapper for notification stop action
|
// pending intent wrapper for notification stop action
|
||||||
PendingIntent stopActionPendingIntent = PendingIntent.getService(mService, 12, stopActionIntent, 0);
|
PendingIntent stopActionPendingIntent = PendingIntent.getService(context, 12, stopActionIntent, 0);
|
||||||
|
|
||||||
|
|
||||||
// construct notification in builder
|
// construct notification in builder
|
||||||
NotificationCompat.Builder builder;
|
|
||||||
builder = new NotificationCompat.Builder(mService);
|
|
||||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||||
builder.setShowWhen(false);
|
builder.setShowWhen(false);
|
||||||
builder.setContentIntent(tapActionPendingIntent);
|
builder.setContentIntent(tapActionPendingIntent);
|
||||||
builder.setSmallIcon(R.drawable.ic_notification_small_24dp);
|
builder.setSmallIcon(R.drawable.ic_notification_small_24dp);
|
||||||
builder.setLargeIcon(getNotificationIconLarge(tracking));
|
builder.setLargeIcon(getNotificationIconLarge(context, tracking));
|
||||||
if (tracking) {
|
if (tracking) {
|
||||||
builder.addAction(R.drawable.ic_stop_white_36dp, mService.getString(R.string.notification_stop), stopActionPendingIntent);
|
builder.addAction(R.drawable.ic_stop_white_36dp, context.getString(R.string.notification_stop), stopActionPendingIntent);
|
||||||
builder.setContentTitle(mService.getString(R.string.notification_title_trackbook_running));
|
builder.setContentTitle(context.getString(R.string.notification_title_trackbook_running));
|
||||||
builder.setContentText(contentText);
|
builder.setContentText(getContextString(context, track));
|
||||||
} else {
|
} else {
|
||||||
builder.setContentTitle(mService.getString(R.string.notification_title_trackbook_not_running));
|
builder.setContentTitle(context.getString(R.string.notification_title_trackbook_not_running));
|
||||||
builder.setContentText(contentText);
|
builder.setContentText(getContextString(context, track));
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder;
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Constructs an updated notification */
|
||||||
|
public static Notification getUpdatedNotification(Context context, NotificationCompat.Builder builder, Track track) {
|
||||||
|
builder.setContentText(getContextString(context, track));
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a notification channel */
|
||||||
|
public static boolean createNotificationChannel(Context context) {
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
// API level 26 ("Android O") supports notification channels.
|
||||||
|
String id = NOTIFICATION_CHANEL_ID_RECORDING_CHANNEL;
|
||||||
|
CharSequence name = context.getString(R.string.notification_channel_recording_name);
|
||||||
|
String description = context.getString(R.string.notification_channel_recording_description);
|
||||||
|
int importance = NotificationManager.IMPORTANCE_LOW;
|
||||||
|
|
||||||
|
// create channel
|
||||||
|
NotificationChannel channel = new NotificationChannel(id, name, importance);
|
||||||
|
channel.setDescription(description);
|
||||||
|
|
||||||
|
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Get station image for notification's large icon */
|
/* Get station image for notification's large icon */
|
||||||
private static Bitmap getNotificationIconLarge(boolean tracking) {
|
private static Bitmap getNotificationIconLarge(Context context, boolean tracking) {
|
||||||
|
|
||||||
// get dimensions
|
// get dimensions
|
||||||
Resources resources = mService.getResources();
|
Resources resources = context.getResources();
|
||||||
int height = (int) resources.getDimension(android.R.dimen.notification_large_icon_height);
|
int height = (int) resources.getDimension(android.R.dimen.notification_large_icon_height);
|
||||||
int width = (int) resources.getDimension(android.R.dimen.notification_large_icon_width);
|
int width = (int) resources.getDimension(android.R.dimen.notification_large_icon_width);
|
||||||
|
|
||||||
Bitmap bitmap;
|
Bitmap bitmap;
|
||||||
if (tracking) {
|
if (tracking) {
|
||||||
bitmap = getBitmap(R.drawable.ic_notification_large_tracking_48dp);
|
bitmap = getBitmap(context, R.drawable.ic_notification_large_tracking_48dp);
|
||||||
} else {
|
} else {
|
||||||
bitmap = getBitmap(R.drawable.ic_notification_large_not_tracking_48dp);
|
bitmap = getBitmap(context, R.drawable.ic_notification_large_not_tracking_48dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Bitmap.createScaledBitmap(bitmap, width, height, false);
|
return Bitmap.createScaledBitmap(bitmap, width, height, false);
|
||||||
|
@ -155,8 +142,8 @@ public class NotificationHelper implements TrackbookKeys {
|
||||||
|
|
||||||
|
|
||||||
/* Return a bitmap for a given resource id of a vector drawable */
|
/* Return a bitmap for a given resource id of a vector drawable */
|
||||||
private static Bitmap getBitmap(int resource) {
|
private static Bitmap getBitmap(Context context, int resource) {
|
||||||
VectorDrawableCompat drawable = VectorDrawableCompat.create(mService.getResources(), resource, null);
|
VectorDrawableCompat drawable = VectorDrawableCompat.create(context.getResources(), resource, null);
|
||||||
if (drawable != null) {
|
if (drawable != null) {
|
||||||
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||||
Canvas canvas = new Canvas(bitmap);
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
@ -168,4 +155,11 @@ 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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ public interface TrackbookKeys {
|
||||||
/* ACTIONS */
|
/* ACTIONS */
|
||||||
String ACTION_START = "org.y20k.trackbook.action.START";
|
String ACTION_START = "org.y20k.trackbook.action.START";
|
||||||
String ACTION_STOP = "org.y20k.trackbook.action.STOP";
|
String ACTION_STOP = "org.y20k.trackbook.action.STOP";
|
||||||
|
String ACTION_DISMISS = "org.y20k.transistor.action.DISMISS";
|
||||||
String ACTION_DEFAULT = "DEFAULT";
|
String ACTION_DEFAULT = "DEFAULT";
|
||||||
String ACTION_SHOW_MAP = "SHOW_MAP";
|
String ACTION_SHOW_MAP = "SHOW_MAP";
|
||||||
String ACTION_TRACK_UPDATED = "TRACK_UPDATED";
|
String ACTION_TRACK_UPDATED = "TRACK_UPDATED";
|
||||||
|
@ -54,6 +55,7 @@ public interface TrackbookKeys {
|
||||||
|
|
||||||
/* PREFS */
|
/* PREFS */
|
||||||
String PREFS_FAB_STATE = "fabStatePrefs";
|
String PREFS_FAB_STATE = "fabStatePrefs";
|
||||||
|
String PREFS_TRACKER_SERVICE_RUNNING = "trackerServiceRunning";
|
||||||
|
|
||||||
/* INSTANCE STATE */
|
/* INSTANCE STATE */
|
||||||
String INSTANCE_FIRST_START = "firstStart";
|
String INSTANCE_FIRST_START = "firstStart";
|
||||||
|
@ -112,6 +114,7 @@ public interface TrackbookKeys {
|
||||||
String FILE_TYPE_TRACKBOOK_EXTENSION = ".trackbook";
|
String FILE_TYPE_TRACKBOOK_EXTENSION = ".trackbook";
|
||||||
String FILE_NAME_TEMP = "temp";
|
String FILE_NAME_TEMP = "temp";
|
||||||
|
|
||||||
|
String NOTIFICATION_CHANEL_ID_RECORDING_CHANNEL ="notificationChannelIdRecordingChannel";
|
||||||
|
|
||||||
double DEFAULT_LATITUDE = 49.41667; // latitude Nordkapp, Norway
|
double DEFAULT_LATITUDE = 49.41667; // latitude Nordkapp, Norway
|
||||||
double DEFAULT_LONGITUDE = 8.67201; // longitude Nordkapp, Norway
|
double DEFAULT_LONGITUDE = 8.67201; // longitude Nordkapp, Norway
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
<string name="notification_swipe_to_clear_map">(Ausblenden setzt Kartenansicht zurück)</string>
|
<string name="notification_swipe_to_clear_map">(Ausblenden setzt Kartenansicht zurück)</string>
|
||||||
<string name="notification_content_duration">Dauer</string>
|
<string name="notification_content_duration">Dauer</string>
|
||||||
<string name="notification_content_distance">Entfernung</string>
|
<string name="notification_content_distance">Entfernung</string>
|
||||||
|
<string name="notification_channel_recording_name">Status der Aufzeichnung</string>
|
||||||
|
<string name="notification_channel_recording_description">Dauer- und Entfernungsanzeige. Option die Aufzeichnung von Standort-Bewegungen zu beenden.</string>
|
||||||
|
|
||||||
<!-- snackbar messages -->
|
<!-- snackbar messages -->
|
||||||
<string name="snackbar_message_tracking_stopped">Tracking deaktiviert</string>
|
<string name="snackbar_message_tracking_stopped">Tracking deaktiviert</string>
|
||||||
|
|
|
@ -1,22 +1,139 @@
|
||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<resources><string name="app_name">Trackbook</string> <string name="title_activity_infosheet">Infosheet</string>
|
<resources>
|
||||||
|
<!-- activities -->
|
||||||
|
<string name="app_name">Trackbook</string>
|
||||||
|
<string name="title_activity_infosheet">Infosheet</string>
|
||||||
|
|
||||||
|
<!-- menu entries -->
|
||||||
<string name="menu_my_location">Lokasi Saya</string>
|
<string name="menu_my_location">Lokasi Saya</string>
|
||||||
<string name="menu_about">Tentang</string>
|
<string name="menu_about">Tentang</string>
|
||||||
|
|
||||||
|
<!-- headers -->
|
||||||
<string name="header_about">Tentang Trackbook</string>
|
<string name="header_about">Tentang Trackbook</string>
|
||||||
|
|
||||||
|
<!-- tabs -->
|
||||||
<string name="tab_map">PETA</string>
|
<string name="tab_map">PETA</string>
|
||||||
<string name="tab_last_track">JALUR TERAKHIR</string>
|
<string name="tab_last_track">JALUR TERAKHIR</string>
|
||||||
<string name="tab_last_tracks">JALUR TERAKHIR</string>
|
<string name="tab_last_tracks">JALUR TERAKHIR</string>
|
||||||
|
|
||||||
|
<!-- notification -->
|
||||||
<string name="notification_title_trackbook_running">Trackbook aktif</string>
|
<string name="notification_title_trackbook_running">Trackbook aktif</string>
|
||||||
<string name="notification_title_trackbook_not_running">Trackbook tidak aktif</string>
|
<string name="notification_title_trackbook_not_running">Trackbook tidak aktif</string>
|
||||||
<string name="notification_stop">Berhenti</string>
|
<string name="notification_stop">Berhenti</string>
|
||||||
<string name="notification_swipe_to_clear_map">(geser untuk menghapus peta)</string>
|
<string name="notification_swipe_to_clear_map">(geser untuk menghapus peta)</string>
|
||||||
<string name="notification_content_duration">Durasi</string>
|
<string name="notification_content_duration">Durasi</string>
|
||||||
<string name="notification_content_distance">Jarak</string>
|
<string name="notification_content_distance">Jarak</string>
|
||||||
|
<string name="notification_channel_recording_name">Movement Recording State</string>
|
||||||
|
<string name="notification_channel_recording_description">Display duration and distance. Option to stop movement recording.</string>
|
||||||
|
|
||||||
|
<!-- snackbar messages -->
|
||||||
<string name="snackbar_message_tracking_stopped">Pelacakan berhenti</string>
|
<string name="snackbar_message_tracking_stopped">Pelacakan berhenti</string>
|
||||||
<string name="snackbar_message_tracking_started">Pelacakan dimulai</string>
|
<string name="snackbar_message_tracking_started">Pelacakan dimulai</string>
|
||||||
</resources>
|
<string name="snackbar_message_location_offline">Location is turned off. Trackbook will not work.</string>
|
||||||
|
|
||||||
|
<!-- fab sub menu -->
|
||||||
|
<string name="fab_sub_menu_clear">Clear</string>
|
||||||
|
<string name="fab_sub_menu_save_and_clear">Save and Clear</string>
|
||||||
|
|
||||||
|
<!-- dialogs -->
|
||||||
|
<string name="dialog_default_action_cancel">Cancel</string>
|
||||||
|
<string name="dialog_clear_content">Clear Recording?</string>
|
||||||
|
<string name="dialog_clear_action_clear">Clear</string>
|
||||||
|
<string name="dialog_delete_title">Delete Recording?</string>
|
||||||
|
<string name="dialog_delete_content">Delete this recording:</string>
|
||||||
|
<string name="dialog_delete_action_delete">Delete</string>
|
||||||
|
<string name="dialog_export_title_export">Export Recording as GPX?</string>
|
||||||
|
<string name="dialog_export_content_export">Export this recording as GPX track.</string>
|
||||||
|
<string name="dialog_export_action_export">Export</string>
|
||||||
|
<string name="dialog_export_title_overwrite">Export and Overwrite?</string>
|
||||||
|
<string name="dialog_export_content_overwrite">File already exists. Export and overwrite this recording as GPX track.</string>
|
||||||
|
<string name="dialog_export_action_overwrite">Export and Overwrite</string>
|
||||||
|
|
||||||
|
<!-- toast messages -->
|
||||||
|
<string name="toast_message_permissions_granted">Permissions granted.</string>
|
||||||
|
<string name="toast_message_unable_to_start_app">Unable to start Trackbook.</string>
|
||||||
|
<string name="toast_message_no_external_storage">Unable to access external storage.</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_location_services_not_ready">Location services not ready. Please retry.</string>
|
||||||
|
<string name="toast_message_last_location">Last location:</string>
|
||||||
|
<string name="toast_message_save_track">Saving current track.</string>
|
||||||
|
<string name="toast_message_last_location_age_one_hour">over one hour</string>
|
||||||
|
<string name="toast_message_track_clear">Current track data removed.</string>
|
||||||
|
<string name="toast_message_export_success">GPX export successful:</string>
|
||||||
|
<string name="toast_message_export_fail">GPX export failed:</string>
|
||||||
|
|
||||||
|
<!-- map markers -->
|
||||||
|
<string name="marker_description_source">Source</string>
|
||||||
|
<string name="marker_description_time">Time</string>
|
||||||
|
<string name="marker_description_accuracy">Accuracy</string>
|
||||||
|
|
||||||
|
<!-- statistics sheet -->
|
||||||
|
<string name="statistics_sheet_h1_statistics">Statistics</string>
|
||||||
|
<string name="statistics_sheet_p_default_data">track data missing</string>
|
||||||
|
<string name="statistics_sheet_p_distance">Total distance:</string>
|
||||||
|
<string name="statistics_sheet_p_steps">Steps taken:</string>
|
||||||
|
<string name="statistics_sheet_p_waypoints">Recorded waypoints:</string>
|
||||||
|
<string name="statistics_sheet_p_duration">Total duration:</string>
|
||||||
|
<string name="statistics_sheet_p_recording_start">Recording started:</string>
|
||||||
|
<string name="statistics_sheet_p_recording_stop">Recording stopped:</string>
|
||||||
|
|
||||||
|
<!-- onboarding layout -->
|
||||||
|
<string name="layout_onboarding_h1_welcome">Hello</string>
|
||||||
|
<string name="layout_onboarding_description_app_icon">Trackbook App Icon</string>
|
||||||
|
<string name="layout_onboarding_h2_app_name">Trackbook</string>
|
||||||
|
<string name="layout_onboarding_p_app_claim">Movement Recorder for Android</string>
|
||||||
|
<string name="layout_onboarding_h2_request_permissions">Trackbook cannot work without these permissions:</string>
|
||||||
|
<string name="layout_onboarding_h3_permission_location">LOCATION</string>
|
||||||
|
<string name="layout_onboarding_p_permission_location">Trackbook needs accurate GPS 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 Wi-Fi triangulation.</string>
|
||||||
|
<string name="layout_onboarding_h3_permission_storage">STORAGE</string>
|
||||||
|
<string name="layout_onboarding_p_permission_storage">Trackbook uses osmdroid, which caches map tiles on Android\'s external storage. You can find the map cache in the osmdroid folder on the top level of the user-facing file system.</string>
|
||||||
|
<string name="layout_onboarding_button_okay">Got it!</string>
|
||||||
|
|
||||||
|
<!-- track tab onboarding -->
|
||||||
|
<string name="track_tab_onboarding_h1_part_1">Your recorded tracks</string>
|
||||||
|
<string name="track_tab_onboarding_h1_part_2">… will show up here.</string>
|
||||||
|
|
||||||
|
<!-- infosheet about -->
|
||||||
|
<string name="infosheet_about_h1_about">About Trackbook</string>
|
||||||
|
<string name="infosheet_about_h2_recorder">Movement Recorder for Android</string>
|
||||||
|
<string name="infosheet_about_h3_version">Version 1.0 (Astronomy Domine)</string>
|
||||||
|
<string name="infosheet_about_p_bare">Trackbook is a bare bones app for recording your movements. Trackbook is great for hiking, vacation or workout. Once started it traces your movements on a map. The map data is provided by OpenStreetMap (OSM).</string>
|
||||||
|
<string name="infosheet_about_p_free">Trackbook is free software. You can find the code on GitHub. GitHub is also a good place to file bugs or even to contribute, if you are interested. Trackbook is published under the MIT open source license. Trackbook uses osmdroid to display the map, which is also free software published under the Apache License.</string>
|
||||||
|
<string name="infosheet_about_h2_permissions">Which Permissions does Trackbook need?</string>
|
||||||
|
<string name="infosheet_about_h3_internet">Permission INTERNET</string>
|
||||||
|
<string name="infosheet_about_p_internet">Trackbook needs to download map data from OpenStreetMap servers and therefore needs access to the internet.</string>
|
||||||
|
<string name="infosheet_about_h3_network">Permissions ACCESS_WIFI_STATE and ACCESS_NETWORK_STATE</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">Permissions ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION</string>
|
||||||
|
<string name="infosheet_about_p_location">Trackbook needs accurate GPS location data to be able to record your movements. If the GPS data is not available or not accurate enough Trackbook uses location data from cell tower and WiFi triangulation.</string>
|
||||||
|
<string name="infosheet_about_h3_external">Permission WRITE_EXTERNAL_STORAGE</string>
|
||||||
|
<string name="infosheet_about_p_external">Trackbook uses osmdroid, which caches map tiles on Android\'s external storage. You can find the map cache in the osmdroid folder on the top level of the user-facing file system.</string>
|
||||||
|
|
||||||
|
<!-- descriptions -->
|
||||||
|
<string name="descr_map_current_track">Mapping of current track</string>
|
||||||
|
<string name="descr_map_last_track">Mapping of last track</string>
|
||||||
|
<string name="descr_fab_main">Main Action Button</string>
|
||||||
|
<string name="descr_fab_sub_menu_label_1">Label of the Save and Clear button</string>
|
||||||
|
<string name="descr_fab_sub_menu_button_1">small Save and Clear button</string>
|
||||||
|
<string name="descr_fab_sub_menu_label_2">Label of the Clear button</string>
|
||||||
|
<string name="descr_fab_sub_menu_button_2">small Clear button</string>
|
||||||
|
<string name="descr_statistics_sheet_headline">Headline of the statistics sheet</string>
|
||||||
|
<string name="descr_statistics_sheet_icon">Icon of a bar chart</string>
|
||||||
|
<string name="descr_statistics_sheet_p_distance">Data point: Distance</string>
|
||||||
|
<string name="descr_statistics_sheet_p_steps">Data point: Steps</string>
|
||||||
|
<string name="descr_statistics_sheet_p_waypoints">Data point: Waypoints</string>
|
||||||
|
<string name="descr_statistics_sheet_p_duration">Data point: Duration</string>
|
||||||
|
<string name="descr_statistics_sheet_p_recording_start">Data point: Start of recording</string>
|
||||||
|
<string name="descr_statistics_sheet_p_recording_end">Data point: End of recording</string>
|
||||||
|
<string name="descr_statistics_sheet_p_distance_value">Value: Distance</string>
|
||||||
|
<string name="descr_statistics_sheet_p_steps_value">Value: Steps</string>
|
||||||
|
<string name="descr_statistics_sheet_p_waypoints_value">Value: Waypoints</string>
|
||||||
|
<string name="descr_statistics_sheet_p_duration_value">Value: Duration</string>
|
||||||
|
<string name="descr_statistics_sheet_p_recording_start_value">Value: Start of recording</string>
|
||||||
|
<string name="descr_statistics_sheet_p_recording_end_value">Value: End of recording</string>
|
||||||
|
<string name="descr_track_selector">Dropdown menu for further tracks</string>
|
||||||
|
<string name="descr_export_button">Track export button</string>
|
||||||
|
<string name="descr_delete_button">Track delete button</string>
|
||||||
|
|
||||||
|
</resources>
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
<string name="notification_swipe_to_clear_map">(scorri per spostare la mappa)</string>
|
<string name="notification_swipe_to_clear_map">(scorri per spostare la mappa)</string>
|
||||||
<string name="notification_content_duration">Durata</string>
|
<string name="notification_content_duration">Durata</string>
|
||||||
<string name="notification_content_distance">Distanza</string>
|
<string name="notification_content_distance">Distanza</string>
|
||||||
|
<string name="notification_channel_recording_name">Movement Recording State</string>
|
||||||
|
<string name="notification_channel_recording_description">Display duration and distance. Option to stop movement recording.</string>
|
||||||
|
|
||||||
<!-- snackbar messages -->
|
<!-- snackbar messages -->
|
||||||
<string name="snackbar_message_tracking_stopped">Tracciamento interrotto</string>
|
<string name="snackbar_message_tracking_stopped">Tracciamento interrotto</string>
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
<string name="notification_swipe_to_clear_map">(スワイプしてマップをクリア)</string>
|
<string name="notification_swipe_to_clear_map">(スワイプしてマップをクリア)</string>
|
||||||
<string name="notification_content_duration">期間</string>
|
<string name="notification_content_duration">期間</string>
|
||||||
<string name="notification_content_distance">距離</string>
|
<string name="notification_content_distance">距離</string>
|
||||||
|
<string name="notification_channel_recording_name">Movement Recording State</string>
|
||||||
|
<string name="notification_channel_recording_description">Display duration and distance. Option to stop movement recording.</string>
|
||||||
|
|
||||||
<string name="snackbar_message_tracking_stopped">トレースを停止しました</string>
|
<string name="snackbar_message_tracking_stopped">トレースを停止しました</string>
|
||||||
<string name="snackbar_message_tracking_started">トレースを開始しました</string>
|
<string name="snackbar_message_tracking_started">トレースを開始しました</string>
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
<string name="notification_swipe_to_clear_map">(sveip for å tømme kart)</string>
|
<string name="notification_swipe_to_clear_map">(sveip for å tømme kart)</string>
|
||||||
<string name="notification_content_duration">Varighet</string>
|
<string name="notification_content_duration">Varighet</string>
|
||||||
<string name="notification_content_distance">Distanse</string>
|
<string name="notification_content_distance">Distanse</string>
|
||||||
|
<string name="notification_channel_recording_name">Movement Recording State</string>
|
||||||
|
<string name="notification_channel_recording_description">Display duration and distance. Option to stop movement recording.</string>
|
||||||
|
|
||||||
<string name="snackbar_message_tracking_stopped">Sporing stoppet</string>
|
<string name="snackbar_message_tracking_stopped">Sporing stoppet</string>
|
||||||
<string name="snackbar_message_tracking_started">Sporing startet</string>
|
<string name="snackbar_message_tracking_started">Sporing startet</string>
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
<string name="notification_swipe_to_clear_map">(veeg om kaart te wissen)</string>
|
<string name="notification_swipe_to_clear_map">(veeg om kaart te wissen)</string>
|
||||||
<string name="notification_content_duration">Duur</string>
|
<string name="notification_content_duration">Duur</string>
|
||||||
<string name="notification_content_distance">Afstand</string>
|
<string name="notification_content_distance">Afstand</string>
|
||||||
|
<string name="notification_channel_recording_name">Movement Recording State</string>
|
||||||
|
<string name="notification_channel_recording_description">Display duration and distance. Option to stop movement recording.</string>
|
||||||
|
|
||||||
<string name="snackbar_message_tracking_stopped">Bijhouden gestopt</string>
|
<string name="snackbar_message_tracking_stopped">Bijhouden gestopt</string>
|
||||||
<string name="snackbar_message_tracking_started">Bijhouden gestart</string>
|
<string name="snackbar_message_tracking_started">Bijhouden gestart</string>
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
<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>
|
||||||
|
<string name="notification_channel_recording_name">Movement Recording State</string>
|
||||||
|
<string name="notification_channel_recording_description">Display duration and distance. Option to stop movement recording.</string>
|
||||||
|
|
||||||
<!-- snackbar messages -->
|
<!-- snackbar messages -->
|
||||||
<string name="snackbar_message_tracking_stopped">Tracking stopped</string>
|
<string name="snackbar_message_tracking_stopped">Tracking stopped</string>
|
||||||
|
|
21
build.gradle
21
build.gradle
|
@ -21,19 +21,16 @@ allprojects {
|
||||||
}
|
}
|
||||||
project.ext {
|
project.ext {
|
||||||
applicationId = 'org.y20k.trackbook'
|
applicationId = 'org.y20k.trackbook'
|
||||||
versionCode = 12
|
versionCode = 13
|
||||||
versionName = '1.0.5 (Astronomy Domine)'
|
versionName = '1.0.6 (Astronomy Domine)'
|
||||||
minSdkVersion = 22
|
minSdkVersion = 22
|
||||||
// Android N - release
|
compileSdkVersion = 26
|
||||||
compileSdkVersion = 25
|
targetSdkVersion = 26
|
||||||
targetSdkVersion = 25
|
buildToolsVersion = '26.0.1'
|
||||||
buildToolsVersion = '25.0.3 '
|
supportLibraryVersion = '26.0.1'
|
||||||
supportLibraryVersion = '25.4.0'
|
|
||||||
// Android O - test
|
osmdroidVersion = '5.6.5'
|
||||||
// compileSdkVersion = 26
|
gsonVersion = '2.8.1'
|
||||||
// targetSdkVersion = 26
|
|
||||||
// buildToolsVersion = '26.0.0'
|
|
||||||
// supportLibraryVersion = '26.0.0-beta2'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue