From 7d47068bb0f9bb3bb3f81670c9325c13d77f2273 Mon Sep 17 00:00:00 2001 From: y20k Date: Mon, 3 Aug 2020 11:39:05 +0200 Subject: [PATCH] Reverts code style changes introduced in 4dcea979 and 66f4865d --- .../org/y20k/trackbook/SettingsFragment.kt | 92 ++++------- .../java/org/y20k/trackbook/TrackFragment.kt | 93 +++-------- .../java/org/y20k/trackbook/TrackerService.kt | 151 +++++------------- .../trackbook/TrackingToggleTileService.kt | 36 +++-- .../org/y20k/trackbook/TracklistFragment.kt | 39 ++--- .../java/org/y20k/trackbook/core/WayPoint.kt | 2 +- .../org/y20k/trackbook/dialogs/ErrorDialog.kt | 18 +-- .../org/y20k/trackbook/dialogs/YesNoDialog.kt | 55 +++---- .../extensions/SharedPreferencesExt.kt | 8 +- .../org/y20k/trackbook/helpers/FileHelper.kt | 115 +++++-------- .../y20k/trackbook/helpers/LocationHelper.kt | 90 ++++------- .../org/y20k/trackbook/helpers/LogHelper.kt | 8 +- .../trackbook/helpers/PreferencesHelper.kt | 2 +- .../org/y20k/trackbook/helpers/TrackHelper.kt | 86 +++------- .../org/y20k/trackbook/helpers/UiHelper.kt | 68 ++------ .../trackbook/tracklist/TracklistAdapter.kt | 36 ++--- .../trackbook/ui/TrackFragmentLayoutHolder.kt | 74 +++------ app/src/main/res/values/bools.xml | 2 - 18 files changed, 294 insertions(+), 681 deletions(-) delete mode 100644 app/src/main/res/values/bools.xml diff --git a/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt b/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt index f938087..ed33fc7 100644 --- a/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/SettingsFragment.kt @@ -63,7 +63,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList val screen = preferenceManager.createPreferenceScreen(context) // set up "Restrict to GPS" preference - val preferenceGpsOnly = SwitchPreferenceCompat(activity as Context) + val preferenceGpsOnly: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context) preferenceGpsOnly.title = getString(R.string.pref_gps_only_title) preferenceGpsOnly.setIcon(R.drawable.ic_gps_24dp) preferenceGpsOnly.key = Keys.PREF_GPS_ONLY @@ -72,41 +72,26 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList preferenceGpsOnly.setDefaultValue(false) // set up "Use Imperial Measurements" preference - val preferenceImperialMeasurementUnits = SwitchPreferenceCompat(activity as Context) - preferenceImperialMeasurementUnits.title = - getString(R.string.pref_imperial_measurement_units_title) + val preferenceImperialMeasurementUnits: SwitchPreferenceCompat = SwitchPreferenceCompat(activity as Context) + preferenceImperialMeasurementUnits.title = getString(R.string.pref_imperial_measurement_units_title) preferenceImperialMeasurementUnits.setIcon(R.drawable.ic_square_foot_24px) preferenceImperialMeasurementUnits.key = Keys.PREF_USE_IMPERIAL_UNITS - preferenceImperialMeasurementUnits.summaryOn = - getString(R.string.pref_imperial_measurement_units_summary_imperial) - preferenceImperialMeasurementUnits.summaryOff = - getString(R.string.pref_imperial_measurement_units_summary_metric) + preferenceImperialMeasurementUnits.summaryOn = getString(R.string.pref_imperial_measurement_units_summary_imperial) + preferenceImperialMeasurementUnits.summaryOff = getString(R.string.pref_imperial_measurement_units_summary_metric) preferenceImperialMeasurementUnits.setDefaultValue(LengthUnitHelper.useImperialUnits()) // set up "App Theme" preference - val preferenceThemeSelection = ListPreference(activity as Context) + val preferenceThemeSelection: ListPreference = ListPreference(activity as Context) preferenceThemeSelection.title = getString(R.string.pref_theme_selection_title) preferenceThemeSelection.setIcon(R.drawable.ic_smartphone_24dp) preferenceThemeSelection.key = Keys.PREF_THEME_SELECTION - preferenceThemeSelection.summary = - "${getString(R.string.pref_theme_selection_summary)} ${AppThemeHelper.getCurrentTheme( - activity as Context - )}" - preferenceThemeSelection.entries = arrayOf( - getString(R.string.pref_theme_selection_mode_device_default), - getString(R.string.pref_theme_selection_mode_light), - getString(R.string.pref_theme_selection_mode_dark) - ) - preferenceThemeSelection.entryValues = arrayOf( - Keys.STATE_THEME_FOLLOW_SYSTEM, - Keys.STATE_THEME_LIGHT_MODE, - Keys.STATE_THEME_DARK_MODE - ) + preferenceThemeSelection.summary = "${getString(R.string.pref_theme_selection_summary)} ${AppThemeHelper.getCurrentTheme(activity as Context)}" + preferenceThemeSelection.entries = arrayOf(getString(R.string.pref_theme_selection_mode_device_default), getString(R.string.pref_theme_selection_mode_light), getString(R.string.pref_theme_selection_mode_dark)) + preferenceThemeSelection.entryValues = arrayOf(Keys.STATE_THEME_FOLLOW_SYSTEM, Keys.STATE_THEME_LIGHT_MODE, Keys.STATE_THEME_DARK_MODE) preferenceThemeSelection.setOnPreferenceChangeListener { preference, newValue -> if (preference is ListPreference) { val index: Int = preference.entryValues.indexOf(newValue) - preferenceThemeSelection.summary = - "${getString(R.string.pref_theme_selection_summary)} ${preference.entries[index]}" + preferenceThemeSelection.summary = "${getString(R.string.pref_theme_selection_summary)} ${preference.entries.get(index)}" return@setOnPreferenceChangeListener true } else { return@setOnPreferenceChangeListener false @@ -114,22 +99,17 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList } // set up "Delete Non-Starred" preference - val preferenceDeleteNonStarred = Preference(activity as Context) + val preferenceDeleteNonStarred: Preference = Preference(activity as Context) preferenceDeleteNonStarred.title = getString(R.string.pref_delete_non_starred_title) preferenceDeleteNonStarred.setIcon(R.drawable.ic_delete_24dp) preferenceDeleteNonStarred.summary = getString(R.string.pref_delete_non_starred_summary) - preferenceDeleteNonStarred.setOnPreferenceClickListener { - YesNoDialog(this as YesNoDialog.YesNoDialogListener).show( - context = activity as Context, - type = Keys.DIALOG_DELETE_NON_STARRED, - message = R.string.dialog_yes_no_message_delete_non_starred, - yesButton = R.string.dialog_yes_no_positive_button_delete_non_starred - ) + preferenceDeleteNonStarred.setOnPreferenceClickListener{ + YesNoDialog(this as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_DELETE_NON_STARRED, message = R.string.dialog_yes_no_message_delete_non_starred, yesButton = R.string.dialog_yes_no_positive_button_delete_non_starred) return@setOnPreferenceClickListener true } // set up "Accuracy Threshold" preference - val preferenceAccuracyThreshold = SeekBarPreference(activity as Context) + val preferenceAccuracyThreshold: SeekBarPreference = SeekBarPreference(activity as Context) preferenceAccuracyThreshold.title = getString(R.string.pref_accuracy_threshold_title) preferenceAccuracyThreshold.setIcon(R.drawable.ic_timeline_24dp) preferenceAccuracyThreshold.key = Keys.PREF_LOCATION_ACCURACY_THRESHOLD @@ -139,39 +119,32 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList preferenceAccuracyThreshold.setDefaultValue(Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY) // set up "Reset" preference - val preferenceResetAdvanced = Preference(activity as Context) + val preferenceResetAdvanced: Preference = Preference(activity as Context) preferenceResetAdvanced.title = getString(R.string.pref_reset_advanced_title) preferenceResetAdvanced.setIcon(R.drawable.ic_undo_24dp) preferenceResetAdvanced.summary = getString(R.string.pref_reset_advanced_summary) - preferenceResetAdvanced.setOnPreferenceClickListener { + preferenceResetAdvanced.setOnPreferenceClickListener{ preferenceAccuracyThreshold.value = Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY return@setOnPreferenceClickListener true } // set up "App Version" preference - val preferenceAppVersion = Preference(context) + val preferenceAppVersion: Preference = Preference(context) preferenceAppVersion.title = getString(R.string.pref_app_version_title) preferenceAppVersion.setIcon(R.drawable.ic_info_24dp) - preferenceAppVersion.summary = - "${getString(R.string.pref_app_version_summary)} ${BuildConfig.VERSION_NAME} (${getString( - R.string.app_version_name - )})" + preferenceAppVersion.summary = "${getString(R.string.pref_app_version_summary)} ${BuildConfig.VERSION_NAME} (${getString( + R.string.app_version_name)})" preferenceAppVersion.setOnPreferenceClickListener { // copy to clipboard val clip: ClipData = ClipData.newPlainText("simple text", preferenceAppVersion.summary) - val cm: ClipboardManager = - context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager + val cm: ClipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager cm.setPrimaryClip(clip) - Toast.makeText( - activity as Context, - R.string.toast_message_copied_to_clipboard, - Toast.LENGTH_LONG - ).show() + Toast.makeText(activity as Context, R.string.toast_message_copied_to_clipboard, Toast.LENGTH_LONG).show() return@setOnPreferenceClickListener true } // set up "Report Issue" preference - val preferenceReportIssue = Preference(context) + val preferenceReportIssue: Preference = Preference(context) preferenceReportIssue.title = getString(R.string.pref_report_issue_title) preferenceReportIssue.setIcon(R.drawable.ic_bug_report_24dp) preferenceReportIssue.summary = getString(R.string.pref_report_issue_summary) @@ -186,21 +159,20 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList } // set preference categories - val preferenceCategoryGeneral = PreferenceCategory(activity as Context) + val preferenceCategoryGeneral: PreferenceCategory = PreferenceCategory(activity as Context) preferenceCategoryGeneral.title = getString(R.string.pref_general_title) preferenceCategoryGeneral.contains(preferenceImperialMeasurementUnits) preferenceCategoryGeneral.contains(preferenceGpsOnly) - val preferenceCategoryMaintenance = - PreferenceCategory(activity as Context) + val preferenceCategoryMaintenance: PreferenceCategory = PreferenceCategory(activity as Context) preferenceCategoryMaintenance.title = getString(R.string.pref_maintenance_title) preferenceCategoryMaintenance.contains(preferenceDeleteNonStarred) - val preferenceCategoryAdvanced = PreferenceCategory(activity as Context) + val preferenceCategoryAdvanced: PreferenceCategory = PreferenceCategory(activity as Context) preferenceCategoryAdvanced.title = getString(R.string.pref_advanced_title) preferenceCategoryAdvanced.contains(preferenceAccuracyThreshold) preferenceCategoryAdvanced.contains(preferenceResetAdvanced) - val preferenceCategoryAbout = PreferenceCategory(context) + val preferenceCategoryAbout: PreferenceCategory = PreferenceCategory(context) preferenceCategoryAbout.title = getString(R.string.pref_about_title) preferenceCategoryAbout.contains(preferenceAppVersion) preferenceCategoryAbout.contains(preferenceReportIssue) @@ -223,12 +195,7 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList /* Overrides onYesNoDialog from YesNoDialogListener */ - override fun onYesNoDialog( - type: Int, - dialogResult: Boolean, - payload: Int, - payloadString: String - ) { + override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { when (type) { Keys.DIALOG_DELETE_NON_STARRED -> { when (dialogResult) { @@ -246,13 +213,12 @@ class SettingsFragment : PreferenceFragmentCompat(), YesNoDialog.YesNoDialogList /* Removes track and track files for given position - used by TracklistFragment */ - private fun deleteNonStarred(context: Context) { + fun deleteNonStarred(context: Context) { val backgroundJob = Job() val uiScope = CoroutineScope(Dispatchers.Main + backgroundJob) uiScope.launch { var tracklist: Tracklist = FileHelper.readTracklist(context) - val deferred: Deferred = - async { FileHelper.deleteNonStarredSuspended(context, tracklist) } + val deferred: Deferred = async { FileHelper.deleteNonStarredSuspended(context, tracklist) } // wait for result and store in tracklist tracklist = deferred.await() backgroundJob.cancel() diff --git a/app/src/main/java/org/y20k/trackbook/TrackFragment.kt b/app/src/main/java/org/y20k/trackbook/TrackFragment.kt index debd51d..d33305d 100644 --- a/app/src/main/java/org/y20k/trackbook/TrackFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/TrackFragment.kt @@ -24,9 +24,7 @@ import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.net.Uri -import android.os.Build import android.os.Bundle -import android.os.VibrationEffect import android.os.Vibrator import android.view.LayoutInflater import android.view.View @@ -48,8 +46,7 @@ import org.y20k.trackbook.helpers.TrackHelper import org.y20k.trackbook.ui.TrackFragmentLayoutHolder -class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, - YesNoDialog.YesNoDialogListener, MapOverlay.MarkerListener { +class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDialog.YesNoDialogListener, MapOverlay.MarkerListener { /* Define log tag */ private val TAG: String = LogHelper.makeLogTag(TrackFragment::class.java) @@ -64,30 +61,19 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // get track - val fileUriString: String = - arguments?.getString(Keys.ARG_TRACK_FILE_URI, String()) ?: String() - track = if (fileUriString.isNotBlank()) { - FileHelper.readTrack(Uri.parse(fileUriString)) + val fileUriString: String = arguments?.getString(Keys.ARG_TRACK_FILE_URI, String()) ?: String() + if (fileUriString.isNotBlank()) { + track = FileHelper.readTrack(activity as Context, Uri.parse(fileUriString)) } else { - Track() + track = Track() } } /* Overrides onCreateView from Fragment */ - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // initialize layout - layout = TrackFragmentLayoutHolder( - activity as Context, - this as MapOverlay.MarkerListener, - inflater, - container, - track - ) + layout = TrackFragmentLayoutHolder(activity as Context, this as MapOverlay.MarkerListener, inflater, container, track) // set up share button layout.shareButton.setOnClickListener { @@ -95,31 +81,18 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, } layout.shareButton.setOnLongClickListener { val v = (activity as Context).getSystemService(Context.VIBRATOR_SERVICE) as Vibrator - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - v.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE)) - } else { - v.vibrate(50) - } + v.vibrate(50) shareGpxTrack() return@setOnLongClickListener true } // set up delete button layout.deleteButton.setOnClickListener { - val dialogMessage = - "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n- ${layout.trackNameView.text}" - YesNoDialog(this@TrackFragment as YesNoDialog.YesNoDialogListener).show( - context = activity as Context, - type = Keys.DIALOG_DELETE_TRACK, - messageString = dialogMessage, - yesButton = R.string.dialog_yes_no_positive_button_delete_recording - ) + val dialogMessage: String = "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n- ${layout.trackNameView.text}" + YesNoDialog(this@TrackFragment as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_DELETE_TRACK, messageString = dialogMessage, yesButton = R.string.dialog_yes_no_positive_button_delete_recording) } // set up rename button layout.editButton.setOnClickListener { - RenameTrackDialog(this as RenameTrackDialog.RenameTrackListener).show( - activity as Context, - layout.trackNameView.text.toString() - ) + RenameTrackDialog(this as RenameTrackDialog.RenameTrackListener).show(activity as Context, layout.trackNameView.text.toString()) } return layout.rootView @@ -152,18 +125,8 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, val targetUri: Uri? = data.data if (targetUri != null) { // copy file async (= fire & forget - no return value needed) - GlobalScope.launch { - FileHelper.saveCopyOfFileSuspended( - activity as Context, - originalFileUri = sourceUri, - targetFileUri = targetUri - ) - } - Toast.makeText( - activity as Context, - R.string.toast_message_save_gpx, - Toast.LENGTH_LONG - ).show() + GlobalScope.launch { FileHelper.saveCopyOfFileSuspended( activity as Context, originalFileUri = sourceUri, targetFileUri = targetUri) } + Toast.makeText(activity as Context, R.string.toast_message_save_gpx, Toast.LENGTH_LONG).show() } } } @@ -176,13 +139,7 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, /* Overrides onRenameTrackDialog from RenameTrackDialog */ override fun onRenameTrackDialog(textInput: String) { // rename track async (= fire & forget - no return value needed) - GlobalScope.launch { - FileHelper.renameTrackSuspended( - activity as Context, - layout.track, - textInput - ) - } + GlobalScope.launch { FileHelper.renameTrackSuspended(activity as Context, layout.track, textInput) } // update name in layout layout.track.name = textInput layout.trackNameView.text = textInput @@ -190,12 +147,7 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, /* Overrides onYesNoDialog from YesNoDialogListener */ - override fun onYesNoDialog( - type: Int, - dialogResult: Boolean, - payload: Int, - payloadString: String - ) { + override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { when (type) { Keys.DIALOG_DELETE_TRACK -> { when (dialogResult) { @@ -237,11 +189,7 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, if (packageManager != null && intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, Keys.REQUEST_SAVE_GPX) } else { - Toast.makeText( - activity as Context, - R.string.toast_message_install_file_helper, - Toast.LENGTH_LONG - ).show() + Toast.makeText(activity as Context, R.string.toast_message_install_file_helper, Toast.LENGTH_LONG).show() } } @@ -249,11 +197,7 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, /* Share track as GPX via share sheet */ private fun shareGpxTrack() { val gpxFile = Uri.parse(layout.track.gpxUriString).toFile() - val gpxShareUri = FileProvider.getUriForFile( - this.activity as Context, - "${requireActivity().applicationContext.packageName}.provider", - gpxFile - ) + val gpxShareUri = FileProvider.getUriForFile(this.activity as Context, "${requireActivity().applicationContext.packageName}.provider", gpxFile) val shareIntent: Intent = Intent.createChooser(Intent().apply { action = Intent.ACTION_SEND data = gpxShareUri @@ -267,8 +211,7 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, if (packageManager != null && shareIntent.resolveActivity(packageManager) != null) { startActivity(shareIntent) } else { - Toast.makeText(activity, R.string.toast_message_install_file_helper, Toast.LENGTH_LONG) - .show() + Toast.makeText(activity, R.string.toast_message_install_file_helper, Toast.LENGTH_LONG).show() } } diff --git a/app/src/main/java/org/y20k/trackbook/TrackerService.kt b/app/src/main/java/org/y20k/trackbook/TrackerService.kt index 70ef0b5..224810c 100644 --- a/app/src/main/java/org/y20k/trackbook/TrackerService.kt +++ b/app/src/main/java/org/y20k/trackbook/TrackerService.kt @@ -48,7 +48,7 @@ import kotlin.coroutines.CoroutineContext /* * TrackerService class */ -class TrackerService : Service(), CoroutineScope, SensorEventListener { +class TrackerService(): Service(), CoroutineScope, SensorEventListener { /* Define log tag */ private val TAG: String = LogHelper.makeLogTag(TrackerService::class.java) @@ -58,16 +58,16 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { var trackingState: Int = Keys.STATE_TRACKING_NOT var gpsProviderActive: Boolean = false var networkProviderActive: Boolean = false - private var useImperial: Boolean = false - private var gpsOnly: Boolean = false + var useImperial: Boolean = false + var gpsOnly: Boolean = false var locationAccuracyThreshold: Int = Keys.DEFAULT_THRESHOLD_LOCATION_ACCURACY var currentBestLocation: Location = LocationHelper.getDefaultLocation() - private var stepCountOffset: Float = 0f + var stepCountOffset: Float = 0f var resumed: Boolean = false var track: Track = Track() - private var gpsLocationListenerRegistered: Boolean = false - private var networkLocationListenerRegistered: Boolean = false - private var bound: Boolean = false + var gpsLocationListenerRegistered: Boolean = false + var networkLocationListenerRegistered: Boolean = false + var bound: Boolean = false private val binder = LocalBinder() private val handler: Handler = Handler() private lateinit var locationManager: LocationManager @@ -99,10 +99,9 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { networkLocationListener = createLocationListener() trackingState = PreferencesHelper.loadTrackingState(this) currentBestLocation = LocationHelper.getLastKnownLocation(this) - track = FileHelper.readTrack(FileHelper.getTempFileUri(this)) + track = FileHelper.readTrack(this, FileHelper.getTempFileUri(this)) backgroundJob = Job() - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) } @@ -112,19 +111,16 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { // SERVICE RESTART (via START_STICKY) if (intent == null) { if (trackingState == Keys.STATE_TRACKING_ACTIVE) { - LogHelper.w( - TAG, - "Trackbook has been killed by the operating system. Trying to resume recording." - ) + LogHelper.w(TAG, "Trackbook has been killed by the operating system. Trying to resume recording.") resumeTracking() } - // ACTION STOP + // ACTION STOP } else if (Keys.ACTION_STOP == intent.action) { stopTracking() - // ACTION START + // ACTION START } else if (Keys.ACTION_START == intent.action) { startTracking() - // ACTION RESUME + // ACTION RESUME } else if (Keys.ACTION_RESUME == intent.action) { resumeTracking() } @@ -176,8 +172,7 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { // remove notification stopForeground(true) // stop listening for changes in shared preferences - PreferenceManager.getDefaultSharedPreferences(this) - .unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) // stop receiving location updates removeGpsLocationListener() removeNetworkLocationListener() @@ -194,12 +189,11 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { /* Overrides onSensorChanged from SensorEventListener */ override fun onSensorChanged(sensorEvent: SensorEvent?) { - var steps = 0f + var steps: Float = 0f if (sensorEvent != null) { if (stepCountOffset == 0f) { // store steps previously recorded by the system - stepCountOffset = - (sensorEvent.values[0] - 1) - track.stepCount // subtract any steps recorded during this session in case the app was killed + stepCountOffset = (sensorEvent.values[0] - 1) - track.stepCount // subtract any steps recorded during this session in case the app was killed } // calculate step count - subtract steps previously recorded steps = sensorEvent.values[0] - stepCountOffset @@ -212,17 +206,16 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { /* Resume tracking after stop/pause */ fun resumeTracking() { // load temp track - returns an empty track if not available - track = FileHelper.readTrack(FileHelper.getTempFileUri(this)) + track = FileHelper.readTrack(this, FileHelper.getTempFileUri(this)) // try to mark last waypoint as stopover if (track.wayPoints.size > 0) { val lastWayPointIndex = track.wayPoints.size - 1 - track.wayPoints[lastWayPointIndex].isStopOver = true + track.wayPoints.get(lastWayPointIndex).isStopOver = true } // set resumed flag resumed = true // calculate length of recording break - track.recordingPaused = - track.recordingPaused + TrackHelper.calculateDurationOfPause(track.recordingStop) + track.recordingPaused = track.recordingPaused + TrackHelper.calculateDurationOfPause(track.recordingStop) // start tracking startTracking(newTrack = false) } @@ -308,27 +301,20 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { currentBestLocation = location } } - override fun onProviderEnabled(provider: String) { LogHelper.v(TAG, "onProviderEnabled $provider") when (provider) { - LocationManager.GPS_PROVIDER -> gpsProviderActive = - LocationHelper.isGpsEnabled(locationManager) - LocationManager.NETWORK_PROVIDER -> networkProviderActive = - LocationHelper.isNetworkEnabled(locationManager) + LocationManager.GPS_PROVIDER -> gpsProviderActive = LocationHelper.isGpsEnabled(locationManager) + LocationManager.NETWORK_PROVIDER -> networkProviderActive = LocationHelper.isNetworkEnabled(locationManager) } } - override fun onProviderDisabled(provider: String) { LogHelper.v(TAG, "onProviderDisabled $provider") when (provider) { - LocationManager.GPS_PROVIDER -> gpsProviderActive = - LocationHelper.isGpsEnabled(locationManager) - LocationManager.NETWORK_PROVIDER -> networkProviderActive = - LocationHelper.isNetworkEnabled(locationManager) + LocationManager.GPS_PROVIDER -> gpsProviderActive = LocationHelper.isGpsEnabled(locationManager) + LocationManager.NETWORK_PROVIDER -> networkProviderActive = LocationHelper.isNetworkEnabled(locationManager) } } - override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) { // deprecated method } @@ -343,25 +329,13 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { // check if Network provider is available if (gpsProviderActive) { // check for location permission - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // adds GPS location listener - locationManager.requestLocationUpdates( - LocationManager.GPS_PROVIDER, - 0, - 0f, - gpsLocationListener - ) + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0f,gpsLocationListener) gpsLocationListenerRegistered = true LogHelper.v(TAG, "Added GPS location listener.") } else { - LogHelper.w( - TAG, - "Unable to add GPS location listener. Location permission is not granted." - ) + LogHelper.w(TAG, "Unable to add GPS location listener. Location permission is not granted.") } } else { LogHelper.w(TAG, "Unable to add GPS location listener.") @@ -379,83 +353,50 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { // check if Network provider is available if (networkProviderActive && !gpsOnly) { // check for location permission - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { // adds Network location listener - locationManager.requestLocationUpdates( - LocationManager.NETWORK_PROVIDER, - 0, - 0f, - networkLocationListener - ) + locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, networkLocationListener) networkLocationListenerRegistered = true LogHelper.v(TAG, "Added Network location listener.") } else { - LogHelper.w( - TAG, - "Unable to add Network location listener. Location permission is not granted." - ) + LogHelper.w(TAG, "Unable to add Network location listener. Location permission is not granted.") } } else { LogHelper.w(TAG, "Unable to add Network location listener.") } } else { - LogHelper.v( - TAG, - "Skipping registration. Network location listener has already been added." - ) + LogHelper.v(TAG, "Skipping registration. Network location listener has already been added.") } } /* Adds location listeners to location manager */ fun removeGpsLocationListener() { - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { locationManager.removeUpdates(gpsLocationListener) gpsLocationListenerRegistered = false LogHelper.v(TAG, "Removed GPS location listener.") } else { - LogHelper.w( - TAG, - "Unable to remove GPS location listener. Location permission is needed." - ) + LogHelper.w(TAG, "Unable to remove GPS location listener. Location permission is needed.") } } /* Adds location listeners to location manager */ fun removeNetworkLocationListener() { - if (ContextCompat.checkSelfPermission( - this, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { locationManager.removeUpdates(gpsLocationListener) networkLocationListenerRegistered = false LogHelper.v(TAG, "Removed Network location listener.") } else { - LogHelper.w( - TAG, - "Unable to remove Network location listener. Location permission is needed." - ) + LogHelper.w(TAG, "Unable to remove Network location listener. Location permission is needed.") } } /* Registers a step counter listener */ private fun startStepCounter() { - val stepCounterAvailable = sensorManager.registerListener( - this, - sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), - SensorManager.SENSOR_DELAY_UI - ) + val stepCounterAvailable = sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_UI) if (!stepCounterAvailable) { LogHelper.w(TAG, "Pedometer sensor not available.") track.stepCount = -1f @@ -465,12 +406,7 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { /* Displays / updates notification */ private fun displayNotification(): Notification { - val notification: Notification = notificationHelper.createNotification( - trackingState, - track.length, - track.duration, - useImperial - ) + val notification: Notification = notificationHelper.createNotification(trackingState, track.length, track.duration, useImperial) notificationManager.notify(Keys.TRACKER_SERVICE_NOTIFICATION_ID, notification) return notification } @@ -479,8 +415,7 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { /* * Defines the listener for changes in shared preferences */ - private val sharedPreferenceChangeListener = - SharedPreferences.OnSharedPreferenceChangeListener { _, key -> + private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key -> when (key) { // preference "Restrict to GPS" Keys.PREF_GPS_ONLY -> { @@ -496,8 +431,7 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { } // preference "Accuracy Threshold" Keys.PREF_LOCATION_ACCURACY_THRESHOLD -> { - locationAccuracyThreshold = - PreferencesHelper.loadAccuracyThreshold(this@TrackerService) + locationAccuracyThreshold = PreferencesHelper.loadAccuracyThreshold(this@TrackerService) } } } @@ -523,12 +457,7 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { private val periodicTrackUpdate: Runnable = object : Runnable { override fun run() { // add waypoint to track - step count is continuously updated in onSensorChanged - val result: Pair = TrackHelper.addWayPointToTrack( - track, - currentBestLocation, - locationAccuracyThreshold, - resumed - ) + val result: Pair = TrackHelper.addWayPointToTrack(this@TrackerService, track, currentBestLocation, locationAccuracyThreshold, resumed) // get track from result track = result.first // check if waypoint was successfully added (= result.second) @@ -549,4 +478,4 @@ class TrackerService : Service(), CoroutineScope, SensorEventListener { */ -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt b/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt index cca22aa..3234150 100644 --- a/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt +++ b/app/src/main/java/org/y20k/trackbook/TrackingToggleTileService.kt @@ -31,7 +31,7 @@ import org.y20k.trackbook.helpers.PreferencesHelper /* * TrackingToggleTileService class */ -class TrackingToggleTileService : TileService() { +class TrackingToggleTileService(): TileService() { /* Define log tag */ private val TAG: String = LogHelper.makeLogTag(TrackingToggleTileService::class.java) @@ -52,6 +52,11 @@ class TrackingToggleTileService : TileService() { updateTile() } + /* Overrides onTileRemoved from TileService */ + override fun onTileRemoved() { + super.onTileRemoved() + } + /* Overrides onStartListening from TileService (tile becomes visible) */ override fun onStartListening() { @@ -61,8 +66,7 @@ class TrackingToggleTileService : TileService() { // set up tile updateTile() // register listener for changes in shared preferences - PreferenceManager.getDefaultSharedPreferences(this@TrackingToggleTileService) - .registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + PreferenceManager.getDefaultSharedPreferences(this@TrackingToggleTileService).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) } @@ -80,8 +84,13 @@ class TrackingToggleTileService : TileService() { override fun onStopListening() { super.onStopListening() // unregister listener for changes in shared preferences - PreferenceManager.getDefaultSharedPreferences(this@TrackingToggleTileService) - .unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + PreferenceManager.getDefaultSharedPreferences(this@TrackingToggleTileService).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener) + } + + + /* Overrides onDestroy from Service */ + override fun onDestroy() { + super.onDestroy() } @@ -129,18 +138,19 @@ class TrackingToggleTileService : TileService() { /* * Defines the listener for changes in shared preferences */ - private val sharedPreferenceChangeListener = - SharedPreferences.OnSharedPreferenceChangeListener { _, key -> - when (key) { - Keys.PREF_TRACKING_STATE -> { - trackingState = PreferencesHelper.loadTrackingState(this) - updateTile() - } + private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key -> + when (key) { + Keys.PREF_TRACKING_STATE -> { + trackingState = PreferencesHelper.loadTrackingState(this) + updateTile() } } + } /* * End of declaration */ -} + + +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt b/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt index ed53b1d..b673e8e 100644 --- a/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt +++ b/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt @@ -40,8 +40,7 @@ import org.y20k.trackbook.tracklist.TracklistAdapter /* * TracklistFragment class */ -class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, - YesNoDialog.YesNoDialogListener { +class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, YesNoDialog.YesNoDialogListener { /* Define log tag */ private val TAG: String = LogHelper.makeLogTag(TracklistFragment::class.java) @@ -62,11 +61,7 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, /* Overrides onCreateView from Fragment */ - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // find views val rootView = inflater.inflate(R.layout.fragment_tracklist, container, false) trackElementList = rootView.findViewById(R.id.track_element_list) @@ -82,17 +77,8 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { // ask user val adapterPosition: Int = viewHolder.adapterPosition - val dialogMessage = - "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n- ${tracklistAdapter.getTrackName( - adapterPosition - )}" - YesNoDialog(this@TracklistFragment as YesNoDialog.YesNoDialogListener).show( - context = activity as Context, - type = Keys.DIALOG_DELETE_TRACK, - messageString = dialogMessage, - yesButton = R.string.dialog_yes_no_positive_button_delete_recording, - payload = adapterPosition - ) + val dialogMessage: String = "${getString(R.string.dialog_yes_no_message_delete_recording)}\n\n- ${tracklistAdapter.getTrackName(adapterPosition)}" + YesNoDialog(this@TracklistFragment as YesNoDialog.YesNoDialogListener).show(context = activity as Context, type = Keys.DIALOG_DELETE_TRACK, messageString = dialogMessage, yesButton = R.string.dialog_yes_no_positive_button_delete_recording, payload = adapterPosition) } } val itemTouchHelper = ItemTouchHelper(swipeHandler) @@ -107,7 +93,7 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, /* Overrides onTrackElementTapped from TracklistElementAdapterListener */ override fun onTrackElementTapped(tracklistElement: TracklistElement) { - val bundle = Bundle() + val bundle: Bundle = Bundle() bundle.putString(Keys.ARG_TRACK_TITLE, tracklistElement.name) bundle.putString(Keys.ARG_TRACK_FILE_URI, tracklistElement.trackUriString) bundle.putString(Keys.ARG_GPX_FILE_URI, tracklistElement.gpxUriString) @@ -117,18 +103,13 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, /* Overrides onYesNoDialog from YesNoDialogListener */ - override fun onYesNoDialog( - type: Int, - dialogResult: Boolean, - payload: Int, - payloadString: String - ) { + override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) { when (type) { Keys.DIALOG_DELETE_TRACK -> { when (dialogResult) { // user tapped remove track true -> { - toggleOnboardingLayout(tracklistAdapter.itemCount - 1) + toggleOnboardingLayout(tracklistAdapter.itemCount -1) tracklistAdapter.removeTrack(activity as Context, payload) } // user tapped cancel @@ -158,11 +139,11 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, } + /* * Inner class: custom LinearLayoutManager that overrides onLayoutCompleted */ - inner class CustomLinearLayoutManager(context: Context) : - LinearLayoutManager(context, VERTICAL, false) { + inner class CustomLinearLayoutManager(context: Context): LinearLayoutManager(context, VERTICAL, false) { override fun supportsPredictiveItemAnimations(): Boolean { return true @@ -176,7 +157,7 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener, if (deleteTrackId != -1L) { val position: Int = tracklistAdapter.findPosition(deleteTrackId) tracklistAdapter.removeTrack(this@TracklistFragment.activity as Context, position) - toggleOnboardingLayout(tracklistAdapter.itemCount - 1) + toggleOnboardingLayout(tracklistAdapter.itemCount -1) } } diff --git a/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt b/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt index 23f90f3..d3bf6b0 100644 --- a/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt +++ b/app/src/main/java/org/y20k/trackbook/core/WayPoint.kt @@ -43,7 +43,7 @@ data class WayPoint(@Expose val provider: String, /* Converts WayPoint into Location */ fun toLocation(): Location { - val location = Location(provider) + val location: Location = Location(provider) location.latitude = latitude location.longitude = longitude location.altitude = altitude diff --git a/app/src/main/java/org/y20k/trackbook/dialogs/ErrorDialog.kt b/app/src/main/java/org/y20k/trackbook/dialogs/ErrorDialog.kt index dbc6c06..48864c9 100644 --- a/app/src/main/java/org/y20k/trackbook/dialogs/ErrorDialog.kt +++ b/app/src/main/java/org/y20k/trackbook/dialogs/ErrorDialog.kt @@ -18,6 +18,7 @@ package org.y20k.trackbook.dialogs import android.content.Context +import android.content.DialogInterface import android.text.method.ScrollingMovementMethod import android.view.LayoutInflater import android.view.View @@ -37,14 +38,9 @@ object ErrorDialog { /* Construct and show dialog */ - fun show( - context: Context, - errorTitle: Int, - errorMessage: Int, - errorDetails: String = String() - ) { + fun show(context: Context, errorTitle: Int, errorMessage: Int, errorDetails: String = String()) { // prepare dialog builder - val builder = MaterialAlertDialogBuilder(context, R.style.AlertDialogTheme) + val builder: MaterialAlertDialogBuilder = MaterialAlertDialogBuilder(context, R.style.AlertDialogTheme) // set title builder.setTitle(context.getString(errorTitle)) @@ -85,14 +81,12 @@ object ErrorDialog { errorMessageView.text = context.getString(errorMessage) // add okay button - builder.setPositiveButton( - R.string.dialog_generic_button_okay - ) { _, _ -> + builder.setPositiveButton(R.string.dialog_generic_button_okay, DialogInterface.OnClickListener { _, _ -> // listen for click on okay button // do nothing - } + }) // display error dialog builder.show() } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/dialogs/YesNoDialog.kt b/app/src/main/java/org/y20k/trackbook/dialogs/YesNoDialog.kt index 867acf3..45c8c85 100644 --- a/app/src/main/java/org/y20k/trackbook/dialogs/YesNoDialog.kt +++ b/app/src/main/java/org/y20k/trackbook/dialogs/YesNoDialog.kt @@ -24,7 +24,7 @@ import org.y20k.trackbook.helpers.LogHelper /* * YesNoDialog class */ -class YesNoDialog(private var yesNoDialogListener: YesNoDialogListener) { +class YesNoDialog (private var yesNoDialogListener: YesNoDialogListener) { /* Interface used to communicate back to activity */ interface YesNoDialogListener { @@ -38,44 +38,31 @@ class YesNoDialog(private var yesNoDialogListener: YesNoDialogListener) { /* Construct and show dialog - variant: message from string */ - fun show( - context: Context, - type: Int, - title: Int = Keys.EMPTY_STRING_RESOURCE, - message: Int, - yesButton: Int = R.string.dialog_yes_no_positive_button_default, - noButton: Int = R.string.dialog_generic_button_cancel, - payload: Int = Keys.DIALOG_EMPTY_PAYLOAD_INT, - payloadString: String = Keys.DIALOG_EMPTY_PAYLOAD_STRING - ) { + fun show(context: Context, + type: Int, + title: Int = Keys.EMPTY_STRING_RESOURCE, + message: Int, + yesButton: Int = R.string.dialog_yes_no_positive_button_default, + noButton: Int = R.string.dialog_generic_button_cancel, + payload: Int = Keys.DIALOG_EMPTY_PAYLOAD_INT, + payloadString: String = Keys.DIALOG_EMPTY_PAYLOAD_STRING) { // extract string from message resource and feed into main show method - show( - context, - type, - title, - context.getString(message), - yesButton, - noButton, - payload, - payloadString - ) + show(context, type, title, context.getString(message), yesButton, noButton, payload, payloadString) } /* Construct and show dialog */ - fun show( - context: Context, - type: Int, - title: Int = Keys.EMPTY_STRING_RESOURCE, - messageString: String, - yesButton: Int = R.string.dialog_yes_no_positive_button_default, - noButton: Int = R.string.dialog_generic_button_cancel, - payload: Int = Keys.DIALOG_EMPTY_PAYLOAD_INT, - payloadString: String = Keys.DIALOG_EMPTY_PAYLOAD_STRING - ) { + fun show(context: Context, + type: Int, + title: Int = Keys.EMPTY_STRING_RESOURCE, + messageString: String, + yesButton: Int = R.string.dialog_yes_no_positive_button_default, + noButton: Int = R.string.dialog_generic_button_cancel, + payload: Int = Keys.DIALOG_EMPTY_PAYLOAD_INT, + payloadString: String = Keys.DIALOG_EMPTY_PAYLOAD_STRING) { // prepare dialog builder - val builder = MaterialAlertDialogBuilder(context, R.style.AlertDialogTheme) + val builder: MaterialAlertDialogBuilder = MaterialAlertDialogBuilder(context, R.style.AlertDialogTheme) // set title and message builder.setMessage(messageString) @@ -97,11 +84,11 @@ class YesNoDialog(private var yesNoDialogListener: YesNoDialogListener) { } // handle outside-click as "no" - builder.setOnCancelListener { + builder.setOnCancelListener(){ yesNoDialogListener.onYesNoDialog(type, false, payload, payloadString) } // display dialog builder.show() } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/extensions/SharedPreferencesExt.kt b/app/src/main/java/org/y20k/trackbook/extensions/SharedPreferencesExt.kt index ee6f3ad..b4836eb 100644 --- a/app/src/main/java/org/y20k/trackbook/extensions/SharedPreferencesExt.kt +++ b/app/src/main/java/org/y20k/trackbook/extensions/SharedPreferencesExt.kt @@ -19,15 +19,11 @@ package org.y20k.trackbook.extensions import android.content.SharedPreferences -import java.lang.Double.doubleToRawLongBits -import java.lang.Double.longBitsToDouble /* Puts a Double value in SharedPreferences */ -fun SharedPreferences.Editor.putDouble(key: String, double: Double) = - this.putLong(key, doubleToRawLongBits(double)) +fun SharedPreferences.Editor.putDouble(key: String, double: Double) = putLong(key, java.lang.Double.doubleToRawLongBits(double)) /* gets a Double value from SharedPreferences */ -fun SharedPreferences.getDouble(key: String, default: Double) = - longBitsToDouble(getLong(key, doubleToRawLongBits(default))) +fun SharedPreferences.getDouble(key: String, default: Double) = java.lang.Double.longBitsToDouble(getLong(key, java.lang.Double.doubleToRawLongBits(default))) \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt index 7111788..647ff05 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt @@ -35,8 +35,6 @@ import java.text.NumberFormat import java.util.* import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine -import kotlin.math.ln -import kotlin.math.pow /* @@ -50,10 +48,10 @@ object FileHelper { /* Return an InputStream for given Uri */ fun getTextFileStream(context: Context, uri: Uri): InputStream? { - var stream: InputStream? = null + var stream : InputStream? = null try { stream = context.contentResolver.openInputStream(uri) - } catch (e: Exception) { + } catch (e : Exception) { e.printStackTrace() } return stream @@ -63,14 +61,14 @@ object FileHelper { /* Get file size for given Uri */ fun getFileSize(context: Context, uri: Uri): Long { val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null) - return if (cursor != null) { + if (cursor != null) { val sizeIndex: Int = cursor.getColumnIndex(OpenableColumns.SIZE) cursor.moveToFirst() val size: Long = cursor.getLong(sizeIndex) cursor.close() - size + return size } else { - 0L + return 0L } } @@ -78,14 +76,14 @@ object FileHelper { /* Get file name for given Uri */ fun getFileName(context: Context, uri: Uri): String { val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null) - return if (cursor != null) { + if (cursor != null) { val nameIndex: Int = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) cursor.moveToFirst() val name: String = cursor.getString(nameIndex) cursor.close() - name + return name } else { - String() + return String() } } @@ -112,8 +110,8 @@ object FileHelper { fun readTracklist(context: Context): Tracklist { LogHelper.v(TAG, "Reading Tracklist - Thread: ${Thread.currentThread().name}") // get JSON from text file - val json: String = readTextFile(getTracklistFileUri(context)) - var tracklist = Tracklist() + val json: String = readTextFile(context, getTracklistFileUri(context)) + var tracklist: Tracklist = Tracklist() when (json.isNotBlank()) { // convert JSON and return as tracklist true -> try { @@ -127,10 +125,10 @@ object FileHelper { /* Reads track from storage using GSON */ - fun readTrack(fileUri: Uri): Track { + fun readTrack(context: Context, fileUri: Uri): Track { // get JSON from text file - val json: String = readTextFile(fileUri) - var track = Track() + val json: String = readTextFile(context, fileUri) + var track: Track = Track() when (json.isNotEmpty()) { // convert JSON and return as track true -> try { @@ -156,19 +154,16 @@ object FileHelper { /* Creates Uri for Gpx file of a track */ - fun getGpxFileUri(context: Context, track: Track): Uri = - File(context.getExternalFilesDir(Keys.FOLDER_GPX), getGpxFileName(track)).toUri() + fun getGpxFileUri(context: Context, track: Track): Uri = File(context.getExternalFilesDir(Keys.FOLDER_GPX), getGpxFileName(track)).toUri() /* Creates file name for Gpx file of a track */ - fun getGpxFileName(track: Track): String = - DateTimeHelper.convertToSortableDateString(track.recordingStart) + Keys.GPX_FILE_EXTENSION + fun getGpxFileName(track: Track): String = DateTimeHelper.convertToSortableDateString(track.recordingStart) + Keys.GPX_FILE_EXTENSION /* Creates Uri for json track file */ fun getTrackFileUri(context: Context, track: Track): Uri { - val fileName: String = - DateTimeHelper.convertToSortableDateString(track.recordingStart) + Keys.TRACKBOOK_FILE_EXTENSION + val fileName: String = DateTimeHelper.convertToSortableDateString(track.recordingStart) + Keys.TRACKBOOK_FILE_EXTENSION return File(context.getExternalFilesDir(Keys.FOLDER_TRACKS), fileName).toUri() } @@ -180,11 +175,7 @@ object FileHelper { /* Suspend function: Wrapper for saveTracklist */ - suspend fun addTrackAndSaveTracklistSuspended( - context: Context, - track: Track, - modificationDate: Date = track.recordingStop - ) { + suspend fun addTrackAndSaveTracklistSuspended(context: Context, track: Track, modificationDate: Date = track.recordingStop) { return suspendCoroutine { cont -> val tracklist: Tracklist = readTracklist(context) tracklist.tracklistElements.add(track.toTracklistElement(context)) @@ -202,11 +193,7 @@ object FileHelper { /* Suspend function: Wrapper for saveTracklist */ - suspend fun saveTracklistSuspended( - context: Context, - tracklist: Tracklist, - modificationDate: Date - ) { + suspend fun saveTracklistSuspended(context: Context, tracklist: Tracklist, modificationDate: Date) { return suspendCoroutine { cont -> cont.resume(saveTracklist(context, tracklist, modificationDate)) } @@ -230,11 +217,7 @@ object FileHelper { /* Suspend function: Wrapper for deleteTrack */ - suspend fun deleteTrackSuspended( - context: Context, - position: Int, - tracklist: Tracklist - ): Tracklist { + suspend fun deleteTrackSuspended(context: Context, position: Int, tracklist: Tracklist): Tracklist { return suspendCoroutine { cont -> cont.resume(deleteTrack(context, position, tracklist)) } @@ -257,19 +240,14 @@ object FileHelper { /* Suspend function: Wrapper for readTracklist */ suspend fun readTracklistSuspended(context: Context): Tracklist { - return suspendCoroutine { cont -> + return suspendCoroutine {cont -> cont.resume(readTracklist(context)) } } /* Suspend function: Wrapper for copyFile */ - suspend fun saveCopyOfFileSuspended( - context: Context, - originalFileUri: Uri, - targetFileUri: Uri, - deleteOriginal: Boolean = false - ) { + suspend fun saveCopyOfFileSuspended(context: Context, originalFileUri: Uri, targetFileUri: Uri, deleteOriginal: Boolean = false) { return suspendCoroutine { cont -> cont.resume(copyFile(context, originalFileUri, targetFileUri, deleteOriginal)) } @@ -307,7 +285,7 @@ object FileHelper { tracklist.modificationDate = modificationDate // convert to JSON val gson: Gson = getCustomGson() - var json = String() + var json: String = String() try { json = gson.toJson(tracklist) } catch (e: Exception) { @@ -326,11 +304,12 @@ object FileHelper { } + /* Renames track */ private fun renameTrack(context: Context, track: Track, newName: String) { // search track in tracklist val tracklist: Tracklist = readTracklist(context) - var trackUriString = String() + var trackUriString: String = String() tracklist.tracklistElements.forEach { tracklistElement -> if (tracklistElement.getTrackId() == track.getTrackId()) { // rename tracklist element @@ -350,17 +329,13 @@ object FileHelper { /* Deletes multiple tracks */ - private fun deleteTracks( - context: Context, - tracklistElements: MutableList, - tracklist: Tracklist - ): Tracklist { + private fun deleteTracks(context: Context, tracklistElements: MutableList, tracklist: Tracklist): Tracklist { tracklistElements.forEach { tracklistElement -> // delete track files tracklistElement.trackUriString.toUri().toFile().delete() tracklistElement.gpxUriString.toUri().toFile().delete() } - tracklist.tracklistElements.removeAll { tracklistElements.contains(it) } + tracklist.tracklistElements.removeAll{ tracklistElements.contains(it) } saveTracklist(context, tracklist, GregorianCalendar.getInstance().time) return tracklist } @@ -373,23 +348,14 @@ object FileHelper { tracklistElement.trackUriString.toUri().toFile().delete() tracklistElement.gpxUriString.toUri().toFile().delete() // remove track element from list - tracklist.tracklistElements.removeIf { - TrackHelper.getTrackId(it) == TrackHelper.getTrackId( - tracklistElement - ) - } + tracklist.tracklistElements.removeIf { TrackHelper.getTrackId(it) == TrackHelper.getTrackId(tracklistElement) } saveTracklist(context, tracklist, GregorianCalendar.getInstance().time) return tracklist } /* Copies file to specified target */ - private fun copyFile( - context: Context, - originalFileUri: Uri, - targetFileUri: Uri, - deleteOriginal: Boolean = false - ) { + private fun copyFile(context: Context, originalFileUri: Uri, targetFileUri: Uri, deleteOriginal: Boolean = false) { val inputStream = context.contentResolver.openInputStream(originalFileUri) val outputStream = context.contentResolver.openOutputStream(targetFileUri) if (outputStream != null) { @@ -404,7 +370,7 @@ object FileHelper { /* Converts track to JSON */ private fun getTrackJsonString(track: Track): String { val gson: Gson = getCustomGson() - var json = String() + var json: String = String() try { json = gson.toJson(track) } catch (e: Exception) { @@ -423,6 +389,7 @@ object FileHelper { } + /* Converts byte value into a human readable format */ // Source: https://programming.guide/java/formatting-byte-size-to-human-readable-format.html fun getReadableByteCount(bytes: Long, si: Boolean = true): String { @@ -434,13 +401,13 @@ object FileHelper { if (bytes < unit) return "$bytes B" // calculate exp - val exp: Int = (ln(bytes.toDouble()) / ln(unit.toDouble())).toInt() + val exp: Int = (Math.log(bytes.toDouble()) / Math.log(unit.toDouble())).toInt() // determine prefix symbol val prefix: String = ((if (si) "kMGTPE" else "KMGTPE")[exp - 1] + if (si) "" else "i") // calculate result and set number format - val result: Double = bytes / unit.toDouble().pow(exp.toDouble()) + val result: Double = bytes / Math.pow(unit.toDouble(), exp.toDouble()) val numberFormat = NumberFormat.getNumberInstance() numberFormat.maximumFractionDigits = 1 @@ -449,7 +416,7 @@ object FileHelper { /* Reads InputStream from file uri and returns it as String */ - private fun readTextFile(fileUri: Uri): String { + private fun readTextFile(context: Context, fileUri: Uri): String { // todo read https://commonsware.com/blog/2016/03/15/how-consume-content-uri.html // https://developer.android.com/training/secure-file-sharing/retrieve-info val file: File = fileUri.toFile() @@ -459,12 +426,11 @@ object FileHelper { } // read until last line reached val stream: InputStream = file.inputStream() - val reader = BufferedReader(InputStreamReader(stream)) + val reader: BufferedReader = BufferedReader(InputStreamReader(stream)) val builder: StringBuilder = StringBuilder() reader.forEachLine { builder.append(it) - builder.append("\n") - } + builder.append("\n") } stream.close() return builder.toString() } @@ -478,13 +444,8 @@ object FileHelper { /* Writes given bitmap as image file to storage */ - private fun writeImageFile( - bitmap: Bitmap, - file: File, - format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG, - quality: Int = 75 - ) { - if (file.exists()) file.delete() + private fun writeImageFile(context: Context, bitmap: Bitmap, file: File, format: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG, quality: Int = 75) { + if (file.exists()) file.delete () try { val out = FileOutputStream(file) bitmap.compress(format, quality, out) @@ -495,4 +456,4 @@ object FileHelper { } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt index a810940..3a6584a 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/LocationHelper.kt @@ -40,7 +40,7 @@ object LocationHelper { /* Get default location */ fun getDefaultLocation(): Location { - val defaultLocation = Location(LocationManager.NETWORK_PROVIDER) + val defaultLocation: Location = Location(LocationManager.NETWORK_PROVIDER) defaultLocation.latitude = Keys.DEFAULT_LATITUDE defaultLocation.longitude = Keys.DEFAULT_LONGITUDE defaultLocation.accuracy = Keys.DEFAULT_ACCURACY @@ -62,24 +62,14 @@ object LocationHelper { // get last location that Trackbook has stored var lastKnownLocation: Location = PreferencesHelper.loadCurrentBestLocation(context) // try to get the last location the system has stored - it is probably more recent - if (ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { - val locationManager = - context.getSystemService(Context.LOCATION_SERVICE) as LocationManager - val lastKnownLocationGps: Location = - locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) - ?: lastKnownLocation - val lastKnownLocationNetwork: Location = - locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) - ?: lastKnownLocation - lastKnownLocation = - when (isBetterLocation(lastKnownLocationGps, lastKnownLocationNetwork)) { - true -> lastKnownLocationGps - false -> lastKnownLocationNetwork - } + if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { + val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager + val lastKnownLocationGps: Location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) ?: lastKnownLocation + val lastKnownLocationNetwork: Location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) ?: lastKnownLocation + when (isBetterLocation(lastKnownLocationGps, lastKnownLocationNetwork)) { + true -> lastKnownLocation = lastKnownLocationGps + false -> lastKnownLocation = lastKnownLocationNetwork + } } return lastKnownLocation } @@ -97,7 +87,7 @@ object LocationHelper { // check whether the new location fix is newer or older val timeDelta: Long = location.time - currentBestLocation.time val isSignificantlyNewer: Boolean = timeDelta > Keys.SIGNIFICANT_TIME_DIFFERENCE - val isSignificantlyOlder: Boolean = timeDelta < -Keys.SIGNIFICANT_TIME_DIFFERENCE + val isSignificantlyOlder:Boolean = timeDelta < -Keys.SIGNIFICANT_TIME_DIFFERENCE when { // if it's been more than two minutes since the current location, use the new location because the user has likely moved @@ -128,24 +118,25 @@ object LocationHelper { /* Checks if GPS location provider is available and enabled */ fun isGpsEnabled(locationManager: LocationManager): Boolean { - return if (locationManager.allProviders.contains(LocationManager.GPS_PROVIDER)) { - locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) + if (locationManager.allProviders.contains(LocationManager.GPS_PROVIDER)) { + return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) } else { - false + return false } } /* Checks if Network location provider is available and enabled */ fun isNetworkEnabled(locationManager: LocationManager): Boolean { - return if (locationManager.allProviders.contains(LocationManager.NETWORK_PROVIDER)) { - locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) + if (locationManager.allProviders.contains(LocationManager.NETWORK_PROVIDER)) { + return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) } else { - false + return false } } + /* Checks if given location is new */ fun isRecentEnough(location: Location): Boolean { val locationAge: Long = SystemClock.elapsedRealtimeNanos() - location.elapsedRealtimeNanos @@ -155,35 +146,26 @@ object LocationHelper { /* Checks if given location is accurate */ fun isAccurateEnough(location: Location, locationAccuracyThreshold: Int): Boolean { - return when (location.provider) { - LocationManager.GPS_PROVIDER -> location.accuracy < locationAccuracyThreshold - else -> location.accuracy < locationAccuracyThreshold + 10 // a bit more relaxed when location comes from network provider + val isAccurate: Boolean + when (location.provider) { + LocationManager.GPS_PROVIDER -> isAccurate = location.accuracy < locationAccuracyThreshold + else -> isAccurate = location.accuracy < locationAccuracyThreshold + 10 // a bit more relaxed when location comes from network provider } + return isAccurate } /* Checks if the first location of track is plausible */ fun isFirstLocationPlausible(secondLocation: Location, track: Track): Boolean { // speed in km/h - val speed: Double = calculateSpeed( - firstLocation = track.wayPoints[0].toLocation(), - secondLocation = secondLocation, - firstTimestamp = track.recordingStart.time, - secondTimestamp = GregorianCalendar.getInstance().time.time - ) + val speed: Double = calculateSpeed(firstLocation = track.wayPoints[0].toLocation(), secondLocation = secondLocation, firstTimestamp = track.recordingStart.time, secondTimestamp = GregorianCalendar.getInstance().time.time) // plausible = speed under 250 km/h return speed < Keys.IMPLAUSIBLE_TRACK_START_SPEED } /* Calculates speed */ - private fun calculateSpeed( - firstLocation: Location, - secondLocation: Location, - firstTimestamp: Long, - secondTimestamp: Long, - useImperial: Boolean = false - ): Double { + private fun calculateSpeed(firstLocation: Location, secondLocation: Location, firstTimestamp: Long, secondTimestamp: Long, useImperial: Boolean = false): Double { // time difference in seconds val timeDifference: Long = (secondTimestamp - firstTimestamp) / 1000L // distance in meters @@ -201,10 +183,10 @@ object LocationHelper { val distanceThreshold: Float val averageAccuracy: Float = (previousLocation.accuracy + location.accuracy) / 2 // increase the distance threshold if one or both locations are - distanceThreshold = if (averageAccuracy > Keys.DEFAULT_THRESHOLD_DISTANCE) { - averageAccuracy + if (averageAccuracy > Keys.DEFAULT_THRESHOLD_DISTANCE) { + distanceThreshold = averageAccuracy } else { - Keys.DEFAULT_THRESHOLD_DISTANCE + distanceThreshold = Keys.DEFAULT_THRESHOLD_DISTANCE } // location is different when far enough away from previous location return calculateDistance(previousLocation, location) > distanceThreshold @@ -212,8 +194,8 @@ object LocationHelper { /* Calculates distance in meters between two locations */ - fun calculateDistance(previousLocation: Location?, location: Location): Float { - var distance = 0f + fun calculateDistance(previousLocation: Location?, location: Location): Float { + var distance: Float = 0f // two data points needed to calculate distance if (previousLocation != null) { // add up distance @@ -224,26 +206,20 @@ object LocationHelper { /* Calculate elevation differences */ - fun calculateElevationDifferences( - previousLocation: Location?, - location: Location, - track: Track - ): Pair { + fun calculateElevationDifferences(previousLocation: Location?, location: Location, track: Track): Pair { // store current values var positiveElevation: Double = track.positiveElevation var negativeElevation: Double = track.negativeElevation if (previousLocation != null) { // factor is bigger than 1 if the time stamp difference is larger than the movement recording interval - val timeDifferenceFactor: Long = - (location.time - previousLocation.time) / Keys.ADD_WAYPOINT_TO_TRACK_INTERVAL + val timeDifferenceFactor: Long = (location.time - previousLocation.time) / Keys.ADD_WAYPOINT_TO_TRACK_INTERVAL // get elevation difference and sum it up val altitudeDifference: Double = location.altitude - previousLocation.altitude if (altitudeDifference > 0 && altitudeDifference < Keys.ALTITUDE_MEASUREMENT_ERROR_THRESHOLD * timeDifferenceFactor && location.altitude != Keys.DEFAULT_ALTITUDE) { positiveElevation = track.positiveElevation + altitudeDifference // upwards movement } if (altitudeDifference < 0 && altitudeDifference > -Keys.ALTITUDE_MEASUREMENT_ERROR_THRESHOLD * timeDifferenceFactor && location.altitude != Keys.DEFAULT_ALTITUDE) { - negativeElevation = - track.negativeElevation + altitudeDifference // downwards movement + negativeElevation = track.negativeElevation + altitudeDifference // downwards movement } } return Pair(positiveElevation, negativeElevation) @@ -258,4 +234,4 @@ object LocationHelper { } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/helpers/LogHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/LogHelper.kt index 837ee90..5ca9427 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/LogHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/LogHelper.kt @@ -78,9 +78,9 @@ object LogHelper { private fun log(tag: String, level: Int, t: Throwable?, vararg messages: Any) { val message: String - message = if (t == null && messages.size == 1) { + if (t == null && messages.size == 1) { // handle this common case without the extra cost of creating a stringbuffer: - messages[0].toString() + message = messages[0].toString() } else { val sb = StringBuilder() for (m in messages) { @@ -89,7 +89,7 @@ object LogHelper { if (t != null) { sb.append("\n").append(Log.getStackTraceString(t)) } - sb.toString() + message = sb.toString() } Log.println(level, tag, message) @@ -112,4 +112,4 @@ object LogHelper { // Log.println(level, tag, message) // } } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt index 8b07e5e..40bba24 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/PreferencesHelper.kt @@ -107,7 +107,7 @@ object PreferencesHelper { val settings = PreferenceManager.getDefaultSharedPreferences(context) val provider: String = settings.getString(Keys.PREF_CURRENT_BEST_LOCATION_PROVIDER, LocationManager.NETWORK_PROVIDER) ?: LocationManager.NETWORK_PROVIDER // create location - val currentBestLocation = Location(provider) + val currentBestLocation: Location = Location(provider) // load location attributes currentBestLocation.latitude = settings.getDouble(Keys.PREF_CURRENT_BEST_LOCATION_LATITUDE, Keys.DEFAULT_LATITUDE) currentBestLocation.longitude = settings.getDouble(Keys.PREF_CURRENT_BEST_LOCATION_LONGITUDE, Keys.DEFAULT_LONGITUDE) diff --git a/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt index 5f155ba..9e525cc 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/TrackHelper.kt @@ -47,13 +47,8 @@ object TrackHelper { tracklistElement.date.time - /* Adds given location as waypoint to track */ - fun addWayPointToTrack( - track: Track, - location: Location, - locationAccuracyThreshold: Int, - resumed: Boolean - ): Pair { + /* Adds given locatiom as waypoint to track */ + fun addWayPointToTrack(context: Context, track: Track, location: Location, locationAccuracyThreshold: Int, resumed: Boolean): Pair { // get previous location val previousLocation: Location? var numberOfWayPoints: Int = track.wayPoints.size @@ -63,11 +58,7 @@ object TrackHelper { previousLocation = null } // CASE: Second location - check if first location was plausible & remove implausible location - else if (numberOfWayPoints == 1 && !LocationHelper.isFirstLocationPlausible( - location, - track - ) - ) { + else if (numberOfWayPoints == 1 && !LocationHelper.isFirstLocationPlausible(location, track)) { previousLocation = null numberOfWayPoints = 0 track.wayPoints.removeAt(0) @@ -85,8 +76,8 @@ object TrackHelper { // add only if recent and accurate and different val shouldBeAdded: Boolean = (LocationHelper.isRecentEnough(location) && - LocationHelper.isAccurateEnough(location, locationAccuracyThreshold) && - LocationHelper.isDifferentEnough(previousLocation, location)) + LocationHelper.isAccurateEnough(location, locationAccuracyThreshold) && + LocationHelper.isDifferentEnough(previousLocation, location)) // // Debugging for shouldBeAdded - remove for production // val recentEnough: Boolean = LocationHelper.isRecentEnough(location) @@ -104,8 +95,7 @@ object TrackHelper { if (shouldBeAdded) { // update distance (do not update if resumed -> we do not want to add values calculated during a recording pause) if (!resumed) { - track.length = - track.length + LocationHelper.calculateDistance(previousLocation, location) + track.length = track.length + LocationHelper.calculateDistance(previousLocation, location) } if (location.altitude != 0.0) { @@ -115,23 +105,12 @@ object TrackHelper { track.minAltitude = location.altitude } else { // calculate elevation values (upwards / downwards movements) - val elevationDifferences: Pair = - LocationHelper.calculateElevationDifferences( - previousLocation, - location, - track - ) + val elevationDifferences: Pair = LocationHelper.calculateElevationDifferences(previousLocation, location, track) // check if any differences were calculated - if (elevationDifferences != Pair( - track.positiveElevation, - track.negativeElevation - ) - ) { + if (elevationDifferences != Pair(track.positiveElevation, track.negativeElevation)) { // update altitude values - if (location.altitude > track.maxAltitude) track.maxAltitude = - location.altitude - if (location.altitude < track.minAltitude) track.minAltitude = - location.altitude + if (location.altitude > track.maxAltitude) track.maxAltitude = location.altitude + if (location.altitude < track.minAltitude) track.minAltitude = location.altitude // update elevation values (do not update if resumed -> we do not want to add values calculated during a recording pause) if (!resumed) { track.positiveElevation = elevationDifferences.first @@ -143,17 +122,16 @@ object TrackHelper { // toggle stop over status, if necessary if (track.wayPoints.size < 0) { - track.wayPoints[track.wayPoints.size - 1].isStopOver = - LocationHelper.isStopOver(previousLocation, location) + track.wayPoints[track.wayPoints.size - 1].isStopOver = LocationHelper.isStopOver(previousLocation, location) } // save number of satellites val numberOfSatellites: Int val extras = location.extras - numberOfSatellites = if (extras != null && extras.containsKey("satellites")) { - extras.getInt("satellites", 0) + if (extras != null && extras.containsKey("satellites")) { + numberOfSatellites = extras.getInt("satellites", 0) } else { - 0 + numberOfSatellites = 0 } // add current location as point to center on for later display @@ -161,18 +139,7 @@ object TrackHelper { track.longitude = location.longitude // add location as new waypoint - track.wayPoints.add( - WayPoint( - provider = location.provider, - latitude = location.latitude, - longitude = location.longitude, - altitude = location.altitude, - accuracy = location.accuracy, - time = location.time, - distanceToStartingPoint = track.length, - numberSatellites = numberOfSatellites - ) - ) + track.wayPoints.add(WayPoint(provider = location.provider, latitude = location.latitude, longitude = location.longitude, altitude = location.altitude, accuracy = location.accuracy, time = location.time, distanceToStartingPoint = track.length, numberSatellites = numberOfSatellites)) } return Pair(track, shouldBeAdded) @@ -186,12 +153,13 @@ object TrackHelper { /* Creates GPX string for given track */ fun createGpxString(track: Track): String { + var gpxString: String // add header - var gpxString: String = "\n" + - "\n" + gpxString = "\n" + + "\n" // add track gpxString += createGpxTrk(track) @@ -259,20 +227,12 @@ object TrackHelper { if (waypoint.latitude == latitude && waypoint.longitude == longitude) { waypoint.starred = !waypoint.starred when (waypoint.starred) { - true -> Toast.makeText( - context, - R.string.toast_message_poi_added, - Toast.LENGTH_LONG - ).show() - false -> Toast.makeText( - context, - R.string.toast_message_poi_removed, - Toast.LENGTH_LONG - ).show() + true -> Toast.makeText(context, R.string.toast_message_poi_added, Toast.LENGTH_LONG).show() + false -> Toast.makeText(context, R.string.toast_message_poi_removed, Toast.LENGTH_LONG).show() } } } return track } -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/helpers/UiHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/UiHelper.kt index 0e2af28..540ecf0 100644 --- a/app/src/main/java/org/y20k/trackbook/helpers/UiHelper.kt +++ b/app/src/main/java/org/y20k/trackbook/helpers/UiHelper.kt @@ -41,14 +41,7 @@ object UiHelper { /* Sets layout margins for given view in DP */ - private fun setViewMargins( - context: Context, - view: View, - left: Int = 0, - right: Int = 0, - top: Int = 0, - bottom: Int = 0 - ) { + fun setViewMargins(context: Context, view: View, left: Int = 0, right: Int = 0, top: Int= 0, bottom: Int = 0) { val scalingFactor: Float = context.resources.displayMetrics.density val l: Int = (left * scalingFactor).toInt() val r: Int = (right * scalingFactor).toInt() @@ -63,16 +56,7 @@ object UiHelper { /* Sets layout margins for given view in percent */ - fun setViewMarginsPercentage( - context: Context, - view: View, - height: Int, - width: Int, - left: Int = 0, - right: Int = 0, - top: Int = 0, - bottom: Int = 0 - ) { + fun setViewMarginsPercentage(context: Context, view: View, height: Int, width: Int, left: Int = 0, right: Int = 0, top: Int= 0, bottom: Int = 0) { val l: Int = ((width / 100.0f) * left).toInt() val r: Int = ((width / 100.0f) * right).toInt() val t: Int = ((height / 100.0f) * top).toInt() @@ -85,58 +69,28 @@ object UiHelper { * Inner class: Callback that detects a left swipe * Credit: https://github.com/kitek/android-rv-swipe-delete/blob/master/app/src/main/java/pl/kitek/rvswipetodelete/SwipeToDeleteCallback.kt */ - abstract class SwipeToDeleteCallback(context: Context) : - ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { + abstract class SwipeToDeleteCallback(context: Context): ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) { - private val deleteIcon = - ContextCompat.getDrawable(context, R.drawable.ic_remove_circle_24dp) + private val deleteIcon = ContextCompat.getDrawable(context, R.drawable.ic_remove_circle_24dp) private val intrinsicWidth: Int = deleteIcon?.intrinsicWidth ?: 0 private val intrinsicHeight: Int = deleteIcon?.intrinsicHeight ?: 0 private val background: ColorDrawable = ColorDrawable() - private val backgroundColor = - context.resources.getColor(R.color.list_card_delete_background, null) - private val clearPaint: Paint = - Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) } + private val backgroundColor = context.resources.getColor(R.color.list_card_delete_background, null) + private val clearPaint: Paint = Paint().apply { xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) } - override fun onMove( - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - target: RecyclerView.ViewHolder - ): Boolean { + override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean { // do nothing return false } - override fun onChildDraw( - c: Canvas, - recyclerView: RecyclerView, - viewHolder: RecyclerView.ViewHolder, - dX: Float, - dY: Float, - actionState: Int, - isCurrentlyActive: Boolean - ) { + override fun onChildDraw(c: Canvas, recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, dX: Float, dY: Float, actionState: Int, isCurrentlyActive: Boolean) { val itemView = viewHolder.itemView val itemHeight = itemView.bottom - itemView.top val isCanceled = dX == 0f && !isCurrentlyActive if (isCanceled) { - clearCanvas( - c, - itemView.right + dX, - itemView.top.toFloat(), - itemView.right.toFloat(), - itemView.bottom.toFloat() - ) - super.onChildDraw( - c, - recyclerView, - viewHolder, - dX, - dY, - actionState, - isCurrentlyActive - ) + clearCanvas(c, itemView.right + dX, itemView.top.toFloat(), itemView.right.toFloat(), itemView.bottom.toFloat()) + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive) return } @@ -172,4 +126,4 @@ object UiHelper { * End of inner class */ -} +} \ No newline at end of file diff --git a/app/src/main/java/org/y20k/trackbook/tracklist/TracklistAdapter.kt b/app/src/main/java/org/y20k/trackbook/tracklist/TracklistAdapter.kt index 8f3307f..aace758 100644 --- a/app/src/main/java/org/y20k/trackbook/tracklist/TracklistAdapter.kt +++ b/app/src/main/java/org/y20k/trackbook/tracklist/TracklistAdapter.kt @@ -39,8 +39,7 @@ import java.util.* /* * TracklistAdapter class */ -class TracklistAdapter(private val fragment: Fragment) : - RecyclerView.Adapter() { +class TracklistAdapter(private val fragment: Fragment) : RecyclerView.Adapter() { /* Define log tag */ private val TAG: String = LogHelper.makeLogTag(TracklistAdapter::class.java) @@ -55,7 +54,7 @@ class TracklistAdapter(private val fragment: Fragment) : /* Listener Interface */ interface TracklistAdapterListener { - fun onTrackElementTapped(tracklistElement: TracklistElement) {} + fun onTrackElementTapped(tracklistElement: TracklistElement) { } // fun onTrackElementStarred(trackId: Long, starred: Boolean) } @@ -66,7 +65,7 @@ class TracklistAdapter(private val fragment: Fragment) : tracklistListener = fragment as TracklistAdapterListener // load tracklist tracklist = FileHelper.readTracklist(context) - tracklist.tracklistElements.sortByDescending { tracklistElement -> tracklistElement.date } + tracklist.tracklistElements.sortByDescending { tracklistElement -> tracklistElement.date } } @@ -112,8 +111,7 @@ class TracklistAdapter(private val fragment: Fragment) : val backgroundJob = Job() val uiScope = CoroutineScope(Dispatchers.Main + backgroundJob) uiScope.launch { - val deferred: Deferred = - async { FileHelper.deleteTrackSuspended(context, position, tracklist) } + val deferred: Deferred = async { FileHelper.deleteTrackSuspended(context, position, tracklist) } // wait for result and store in tracklist tracklist = deferred.await() notifyItemRemoved(position) @@ -124,7 +122,7 @@ class TracklistAdapter(private val fragment: Fragment) : /* Finds current position of track element in adapter list */ fun findPosition(trackId: Long): Int { - tracklist.tracklistElements.forEachIndexed { index, tracklistElement -> + tracklist.tracklistElements.forEachIndexed {index, tracklistElement -> if (tracklistElement.getTrackId() == trackId) return index } return -1 @@ -145,11 +143,7 @@ class TracklistAdapter(private val fragment: Fragment) : } } GlobalScope.launch { - FileHelper.saveTracklistSuspended( - context, - tracklist, - GregorianCalendar.getInstance().time - ) + FileHelper.saveTracklistSuspended(context, tracklist, GregorianCalendar.getInstance().time) } } @@ -158,17 +152,11 @@ class TracklistAdapter(private val fragment: Fragment) : private fun createTrackDataString(position: Int): String { val tracklistElement: TracklistElement = tracklist.tracklistElements[position] val trackDataString: String - trackDataString = when (tracklistElement.name == tracklistElement.dateString) { + when (tracklistElement.name == tracklistElement.dateString) { // CASE: no individual name set - exclude date - true -> "${LengthUnitHelper.convertDistanceToString( - tracklistElement.length, - useImperial - )} • ${tracklistElement.durationString}" + true -> trackDataString = "${LengthUnitHelper.convertDistanceToString(tracklistElement.length, useImperial)} • ${tracklistElement.durationString}" // CASE: no individual name set - include date - false -> "${tracklistElement.dateString} • ${LengthUnitHelper.convertDistanceToString( - tracklistElement.length, - useImperial - )} • ${tracklistElement.durationString}" + false -> trackDataString = "${tracklistElement.dateString} • ${LengthUnitHelper.convertDistanceToString(tracklistElement.length, useImperial)} • ${tracklistElement.durationString}" } return trackDataString } @@ -177,8 +165,7 @@ class TracklistAdapter(private val fragment: Fragment) : /* * Inner class: DiffUtil.Callback that determines changes in data - improves list performance */ - private inner class DiffCallback(val oldList: Tracklist, val newList: Tracklist) : - DiffUtil.Callback() { + private inner class DiffCallback(val oldList: Tracklist, val newList: Tracklist): DiffUtil.Callback() { override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { val oldItem = oldList.tracklistElements[oldItemPosition] @@ -208,8 +195,7 @@ class TracklistAdapter(private val fragment: Fragment) : /* * Inner class: ViewHolder for a track element */ - private inner class TrackElementViewHolder(trackElementLayout: View) : - RecyclerView.ViewHolder(trackElementLayout) { + private inner class TrackElementViewHolder (trackElementLayout: View): RecyclerView.ViewHolder(trackElementLayout) { val trackElement: ConstraintLayout = trackElementLayout.findViewById(R.id.track_element) val trackNameView: TextView = trackElementLayout.findViewById(R.id.track_name) val trackDataView: TextView = trackElementLayout.findViewById(R.id.track_data) diff --git a/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt b/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt index d418fda..5609dac 100644 --- a/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt +++ b/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt @@ -50,20 +50,14 @@ import kotlin.math.roundToInt /* * TrackFragmentLayoutHolder class */ -data class TrackFragmentLayoutHolder( - private var context: Context, - private var markerListener: MapOverlay.MarkerListener, - private var inflater: LayoutInflater, - private var container: ViewGroup?, - var track: Track -) { +data class TrackFragmentLayoutHolder(private var context: Context, private var markerListener: MapOverlay.MarkerListener, private var inflater: LayoutInflater, private var container: ViewGroup?, var track: Track) { /* Define log tag */ private val TAG: String = LogHelper.makeLogTag(TrackFragmentLayoutHolder::class.java) /* Main class variables */ - val rootView: View = inflater.inflate(R.layout.fragment_track, container, false) + val rootView: View val shareButton: ImageButton val deleteButton: ImageButton val editButton: ImageButton @@ -96,6 +90,7 @@ data class TrackFragmentLayoutHolder( /* Init block */ init { // find views + rootView = inflater.inflate(R.layout.fragment_track, container, false) mapView = rootView.findViewById(R.id.map) shareButton = rootView.findViewById(R.id.save_button) deleteButton = rootView.findViewById(R.id.delete_button) @@ -139,15 +134,13 @@ data class TrackFragmentLayoutHolder( } // add compass to map - val compassOverlay = - CompassOverlay(context, InternalCompassOrientationProvider(context), mapView) + val compassOverlay = CompassOverlay(context, InternalCompassOrientationProvider(context), mapView) compassOverlay.enableCompass() compassOverlay.setCompassCenter(36f, 60f) mapView.overlays.add(compassOverlay) // create map overlay - trackOverlay = - MapOverlay(markerListener).createTrackOverlay(context, track, Keys.STATE_TRACKING_NOT) + trackOverlay = MapOverlay(markerListener).createTrackOverlay(context, track, Keys.STATE_TRACKING_NOT) if (track.wayPoints.isNotEmpty()) { mapView.overlays.add(trackOverlay) } @@ -175,11 +168,7 @@ data class TrackFragmentLayoutHolder( mapView.overlays.remove(trackOverlay) } if (track.wayPoints.isNotEmpty()) { - trackOverlay = MapOverlay(markerListener).createTrackOverlay( - context, - track, - Keys.STATE_TRACKING_NOT - ) + trackOverlay = MapOverlay(markerListener).createTrackOverlay(context, track, Keys.STATE_TRACKING_NOT) mapView.overlays.add(trackOverlay) } } @@ -201,9 +190,9 @@ data class TrackFragmentLayoutHolder( private fun setupStatisticsViews() { // get step count string - val steps: String = - if (track.stepCount == -1f) context.getString(R.string.statistics_sheet_p_steps_no_pedometer) - else track.stepCount.roundToInt().toString() + val steps: String + if (track.stepCount == -1f) steps = context.getString(R.string.statistics_sheet_p_steps_no_pedometer) + else steps = track.stepCount.roundToInt().toString() // populate views trackNameView.text = track.name @@ -211,29 +200,19 @@ data class TrackFragmentLayoutHolder( stepsView.text = steps waypointsView.text = track.wayPoints.size.toString() durationView.text = DateTimeHelper.convertToReadableTime(context, track.duration) - velocityView.text = LengthUnitHelper.convertToVelocityString( - track.duration, - track.recordingPaused, - track.length, - useImperialUnits - ) + velocityView.text = LengthUnitHelper.convertToVelocityString(track.duration, track.recordingPaused, track.length, useImperialUnits) recordingStartView.text = DateTimeHelper.convertToReadableDateAndTime(track.recordingStart) recordingStopView.text = DateTimeHelper.convertToReadableDateAndTime(track.recordingStart) - maxAltitudeView.text = - LengthUnitHelper.convertDistanceToString(track.maxAltitude, useImperialUnits) - minAltitudeView.text = - LengthUnitHelper.convertDistanceToString(track.minAltitude, useImperialUnits) - positiveElevationView.text = - LengthUnitHelper.convertDistanceToString(track.positiveElevation, useImperialUnits) - negativeElevationView.text = - LengthUnitHelper.convertDistanceToString(track.negativeElevation, useImperialUnits) + maxAltitudeView.text = LengthUnitHelper.convertDistanceToString(track.maxAltitude, useImperialUnits) + minAltitudeView.text = LengthUnitHelper.convertDistanceToString(track.minAltitude, useImperialUnits) + positiveElevationView.text = LengthUnitHelper.convertDistanceToString(track.positiveElevation, useImperialUnits) + negativeElevationView.text = LengthUnitHelper.convertDistanceToString(track.negativeElevation, useImperialUnits) // show / hide recording pause if (track.recordingPaused != 0L) { recordingPausedLabelView.visibility = View.VISIBLE recordingPausedView.visibility = View.VISIBLE - recordingPausedView.text = - DateTimeHelper.convertToReadableTime(context, track.recordingPaused) + recordingPausedView.text = DateTimeHelper.convertToReadableTime(context, track.recordingPaused) } else { recordingPausedLabelView.visibility = View.GONE recordingPausedView.visibility = View.GONE @@ -241,9 +220,8 @@ data class TrackFragmentLayoutHolder( // inform user about possible accuracy issues with altitude measurements elevationDataViews.referencedIds.forEach { id -> - (rootView.findViewById(id) as View).setOnClickListener { - Toast.makeText(context, R.string.toast_message_elevation_info, Toast.LENGTH_LONG) - .show() + (rootView.findViewById(id) as View).setOnClickListener{ + Toast.makeText(context, R.string.toast_message_elevation_info, Toast.LENGTH_LONG).show() } } // make track name on statistics sheet clickable @@ -256,8 +234,7 @@ data class TrackFragmentLayoutHolder( /* Shows/hides the statistics sheet */ private fun toggleStatisticsSheetVisibility() { when (statisticsSheetBehavior.state) { - BottomSheetBehavior.STATE_EXPANDED -> statisticsSheetBehavior.state = - BottomSheetBehavior.STATE_COLLAPSED + BottomSheetBehavior.STATE_EXPANDED -> statisticsSheetBehavior.state = BottomSheetBehavior.STATE_COLLAPSED else -> statisticsSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED } } @@ -269,31 +246,26 @@ data class TrackFragmentLayoutHolder( override fun onStateChanged(bottomSheet: View, newState: Int) { when (newState) { BottomSheetBehavior.STATE_EXPANDED -> { - statisticsSheet.background = - context.getDrawable(R.drawable.shape_statistics_background_expanded) + statisticsSheet.background = context.getDrawable(R.drawable.shape_statistics_background_expanded) trackManagementViews.visibility = View.VISIBLE shareButton.visibility = View.GONE // bottomSheet.setPadding(0,24,0,0) } else -> { - statisticsSheet.background = - context.getDrawable(R.drawable.shape_statistics_background_collapsed) + statisticsSheet.background = context.getDrawable(R.drawable.shape_statistics_background_collapsed) trackManagementViews.visibility = View.GONE shareButton.visibility = View.VISIBLE // bottomSheet.setPadding(0,0,0,0) } } } - override fun onSlide(bottomSheet: View, slideOffset: Float) { if (slideOffset < 0.125f) { - statisticsSheet.background = - context.getDrawable(R.drawable.shape_statistics_background_collapsed) + statisticsSheet.background = context.getDrawable(R.drawable.shape_statistics_background_collapsed) trackManagementViews.visibility = View.GONE shareButton.visibility = View.VISIBLE } else { - statisticsSheet.background = - context.getDrawable(R.drawable.shape_statistics_background_expanded) + statisticsSheet.background = context.getDrawable(R.drawable.shape_statistics_background_expanded) trackManagementViews.visibility = View.VISIBLE shareButton.visibility = View.GONE } @@ -302,4 +274,4 @@ data class TrackFragmentLayoutHolder( } -} +} \ No newline at end of file diff --git a/app/src/main/res/values/bools.xml b/app/src/main/res/values/bools.xml deleted file mode 100644 index 545704f..0000000 --- a/app/src/main/res/values/bools.xml +++ /dev/null @@ -1,2 +0,0 @@ - -