New Theme setting (Dark Mode)

master
y20k 2020-01-28 17:39:45 +01:00
parent 97b64dfd59
commit bdc13cfd61
No known key found for this signature in database
GPG Key ID: 824D4259F41FAFF6
23 changed files with 191 additions and 226 deletions

View File

@ -64,8 +64,8 @@ dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0"
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.1.0'
implementation "androidx.core:core-ktx:1.1.0" implementation "androidx.core:core-ktx:1.1.0"
@ -74,8 +74,8 @@ dependencies {
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation "androidx.preference:preference-ktx:1.1.0" implementation "androidx.preference:preference-ktx:1.1.0"
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.2.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0' implementation 'androidx.navigation:navigation-ui-ktx:2.2.0'
implementation "com.google.android.material:material:1.1.0-beta01" implementation "com.google.android.material:material:1.1.0-beta01"

View File

@ -51,7 +51,7 @@ object Keys {
// preferences // preferences
const val PREF_ONE_TIME_HOUSEKEEPING_NECESSARY = "ONE_TIME_HOUSEKEEPING_NECESSARY_VERSIONCODE_37" // increment to current app version code to trigger housekeeping that runs only once const val PREF_ONE_TIME_HOUSEKEEPING_NECESSARY = "ONE_TIME_HOUSEKEEPING_NECESSARY_VERSIONCODE_37" // increment to current app version code to trigger housekeeping that runs only once
const val PREF_NIGHT_MODE_STATE: String= "prefNightModeState" const val PREF_THEME_SELECTION: String= "prefThemeSelection"
const val PREF_CURRENT_BEST_LOCATION_PROVIDER: String = "prefCurrentBestLocationProvider" const val PREF_CURRENT_BEST_LOCATION_PROVIDER: String = "prefCurrentBestLocationProvider"
const val PREF_CURRENT_BEST_LOCATION_LATITUDE: String = "prefCurrentBestLocationLatitude" const val PREF_CURRENT_BEST_LOCATION_LATITUDE: String = "prefCurrentBestLocationLatitude"
const val PREF_CURRENT_BEST_LOCATION_LONGITUDE: String = "prefCurrentBestLocationLongitude" const val PREF_CURRENT_BEST_LOCATION_LONGITUDE: String = "prefCurrentBestLocationLongitude"
@ -66,9 +66,12 @@ object Keys {
const val PREF_LOCATION_AGE_THRESHOLD: String = "prefLocationAgeThreshold" const val PREF_LOCATION_AGE_THRESHOLD: String = "prefLocationAgeThreshold"
// states // states
const val STATE_NOT_TRACKING: Int = 0 const val STATE_TRACKING_NOT: Int = 0
const val STATE_TRACKING_ACTIVE: Int = 1 const val STATE_TRACKING_ACTIVE: Int = 1
const val STATE_TRACKING_STOPPED: Int = 2 const val STATE_TRACKING_STOPPED: Int = 2
const val STATE_THEME_FOLLOW_SYSTEM: String = "stateFollowSystem"
const val STATE_THEME_LIGHT_MODE: String = "stateLightMode"
const val STATE_THEME_DARK_MODE: String = "stateDarkMode"
// dialog types // dialog types
const val DIALOG_EMPTY_RECORDING: Int = 0 const val DIALOG_EMPTY_RECORDING: Int = 0

View File

@ -17,12 +17,16 @@
package org.y20k.trackbook package org.y20k.trackbook
import android.content.Context
import android.content.SharedPreferences
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.fragment.NavHostFragment import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import org.osmdroid.config.Configuration import org.osmdroid.config.Configuration
import org.y20k.trackbook.helpers.AppThemeHelper
import org.y20k.trackbook.helpers.ImportHelper import org.y20k.trackbook.helpers.ImportHelper
import org.y20k.trackbook.helpers.LogHelper import org.y20k.trackbook.helpers.LogHelper
import org.y20k.trackbook.helpers.PreferencesHelper import org.y20k.trackbook.helpers.PreferencesHelper
@ -80,6 +84,29 @@ class MainActivity : AppCompatActivity() {
PreferencesHelper.saveHouseKeepingNecessaryState(this) PreferencesHelper.saveHouseKeepingNecessaryState(this)
} }
// register listener for changes in shared preferences
PreferenceManager.getDefaultSharedPreferences(this as Context).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
} }
override fun onDestroy() {
super.onDestroy()
// unregister listener for changes in shared preferences
PreferenceManager.getDefaultSharedPreferences(this as Context).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
}
/*
* Defines the listener for changes in shared preferences
*/
private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
when (key) {
Keys.PREF_THEME_SELECTION -> {
AppThemeHelper.setTheme(PreferencesHelper.loadThemeSelection(this@MainActivity))
}
}
}
/*
* End of declaration
*/
} }

View File

@ -53,7 +53,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener {
/* Main class variables */ /* Main class variables */
private var bound: Boolean = false private var bound: Boolean = false
private val handler: Handler = Handler() private val handler: Handler = Handler()
private var trackingState: Int = Keys.STATE_NOT_TRACKING private var trackingState: Int = Keys.STATE_TRACKING_NOT
private var gpsProviderActive: Boolean = false private var gpsProviderActive: Boolean = false
private var networkProviderActive: Boolean = false private var networkProviderActive: Boolean = false
private var track: Track = Track() private var track: Track = Track()
@ -191,7 +191,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener {
when (trackingState) { when (trackingState) {
Keys.STATE_TRACKING_STOPPED -> layout.toggleRecordingButtonSubMenu() Keys.STATE_TRACKING_STOPPED -> layout.toggleRecordingButtonSubMenu()
Keys.STATE_TRACKING_ACTIVE -> trackerService.stopTracking() Keys.STATE_TRACKING_ACTIVE -> trackerService.stopTracking()
Keys.STATE_NOT_TRACKING -> { Keys.STATE_TRACKING_NOT -> {
// start service via intent so that it keeps running after unbind // start service via intent so that it keeps running after unbind
startTrackerService() startTrackerService()
trackerService.startTracking() trackerService.startTracking()
@ -291,7 +291,6 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener {
// update location and track // update location and track
layout.markCurrentPosition(currentBestLocation, trackingState) layout.markCurrentPosition(currentBestLocation, trackingState)
layout.overlayCurrentTrack(track, trackingState) layout.overlayCurrentTrack(track, trackingState)
layout.updateRecordingButton(trackingState)
// center map, if it had not been dragged/zoomed before // center map, if it had not been dragged/zoomed before
if (!layout.userInteraction) { layout.centerMap(currentBestLocation, true)} if (!layout.userInteraction) { layout.centerMap(currentBestLocation, true)}
// show error snackbar if necessary // show error snackbar if necessary

View File

@ -22,6 +22,7 @@ import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.preference.* import androidx.preference.*
import org.y20k.trackbook.helpers.AppThemeHelper
import org.y20k.trackbook.helpers.LengthUnitHelper import org.y20k.trackbook.helpers.LengthUnitHelper
import org.y20k.trackbook.helpers.LogHelper import org.y20k.trackbook.helpers.LogHelper
@ -68,6 +69,29 @@ class SettingsFragment : PreferenceFragmentCompat() {
preferenceImperialMeasurementUnits.summaryOff = getString(R.string.pref_imperial_measurement_units_summary_metric) preferenceImperialMeasurementUnits.summaryOff = getString(R.string.pref_imperial_measurement_units_summary_metric)
preferenceImperialMeasurementUnits.setDefaultValue(LengthUnitHelper.useImperialUnits()) preferenceImperialMeasurementUnits.setDefaultValue(LengthUnitHelper.useImperialUnits())
// set up "App Theme" preference
val preferenceThemeSelection: ListPreference = ListPreference(activity as Context)
preferenceThemeSelection.title = getString(R.string.pref_theme_selection_title)
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.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.get(index)}"
return@setOnPreferenceChangeListener true
} else {
return@setOnPreferenceChangeListener false
}
}
// preferenceThemeSelection.setOnPreferenceClickListener {
// preferenceThemeSelection.summary = "${getString(R.string.pref_theme_selection_theme_summary)} ${AppThemeHelper.getCurrentTheme(activity as Context)}"
// return@setOnPreferenceClickListener true
// }
// set up "Accuracy Threshold" preference // set up "Accuracy Threshold" preference
val preferenceAccuracyThreshold: SeekBarPreference = SeekBarPreference(activity as Context) val preferenceAccuracyThreshold: SeekBarPreference = SeekBarPreference(activity as Context)
preferenceAccuracyThreshold.title = getString(R.string.pref_accuracy_threshold_title) preferenceAccuracyThreshold.title = getString(R.string.pref_accuracy_threshold_title)
@ -100,6 +124,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
screen.addPreference(preferenceCategoryGeneral) screen.addPreference(preferenceCategoryGeneral)
screen.addPreference(preferenceGpsOnly) screen.addPreference(preferenceGpsOnly)
screen.addPreference(preferenceImperialMeasurementUnits) screen.addPreference(preferenceImperialMeasurementUnits)
screen.addPreference(preferenceThemeSelection)
screen.addPreference(preferenceCategoryAdvanced) screen.addPreference(preferenceCategoryAdvanced)
screen.addPreference(preferenceAccuracyThreshold) screen.addPreference(preferenceAccuracyThreshold)
screen.addPreference(preferenceResetAdvanced) screen.addPreference(preferenceResetAdvanced)

View File

@ -19,8 +19,9 @@
package org.y20k.trackbook package org.y20k.trackbook
import android.app.Application import android.app.Application
import org.y20k.trackbook.helpers.AppThemeHelper
import org.y20k.trackbook.helpers.LogHelper import org.y20k.trackbook.helpers.LogHelper
import org.y20k.trackbook.helpers.NightModeHelper import org.y20k.trackbook.helpers.PreferencesHelper
/* /*
@ -38,7 +39,7 @@ class Trackbook: Application() {
super.onCreate() super.onCreate()
LogHelper.v(TAG, "Trackbook application started.") LogHelper.v(TAG, "Trackbook application started.")
// set Day / Night theme state // set Day / Night theme state
NightModeHelper.restoreSavedState(this) AppThemeHelper.setTheme(PreferencesHelper.loadThemeSelection(this))
} }

View File

@ -55,7 +55,7 @@ class TrackerService(): Service(), CoroutineScope, SensorEventListener {
/* Main class variables */ /* Main class variables */
var trackingState: Int = Keys.STATE_NOT_TRACKING var trackingState: Int = Keys.STATE_TRACKING_NOT
var gpsProviderActive: Boolean = false var gpsProviderActive: Boolean = false
var networkProviderActive: Boolean = false var networkProviderActive: Boolean = false
var useImperial: Boolean = false var useImperial: Boolean = false
@ -215,7 +215,7 @@ class TrackerService(): Service(), CoroutineScope, SensorEventListener {
fun clearTrack() { fun clearTrack() {
track = Track() track = Track()
FileHelper.deleteTempFile(this) FileHelper.deleteTempFile(this)
trackingState = Keys.STATE_NOT_TRACKING trackingState = Keys.STATE_TRACKING_NOT
PreferencesHelper.saveTrackingState(this, trackingState) PreferencesHelper.saveTrackingState(this, trackingState)
stopForeground(true) stopForeground(true)
} }

View File

@ -38,7 +38,7 @@ class TrackingToggleTileService(): TileService() {
/* Main class variables */ /* Main class variables */
private var bound: Boolean = false private var bound: Boolean = false
private var trackingState: Int = Keys.STATE_NOT_TRACKING private var trackingState: Int = Keys.STATE_TRACKING_NOT
private lateinit var trackerService: TrackerService private lateinit var trackerService: TrackerService

View File

@ -0,0 +1,104 @@
/*
* AppThemeHelper.kt
* Implements the AppThemeHelper object
* A AppThemeHelper can set the differnt app themes: Light Mode, Dark Mode, Follow System
*
* This file is part of
* TRACKBOOK - Movement Recorder for Android
*
* Copyright (c) 2016-20 - Y20K.org
* Licensed under the MIT-License
* http://opensource.org/licenses/MIT
*
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
* https://github.com/osmdroid/osmdroid
*/
package org.y20k.trackbook.helpers
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.view.View
import androidx.appcompat.app.AppCompatDelegate
import org.y20k.trackbook.Keys
import org.y20k.trackbook.R
/*
* AppThemeHelper object
*/
object AppThemeHelper {
/* Define log tag */
private val TAG: String = LogHelper.makeLogTag(AppThemeHelper::class.java)
/* Sets app theme */
fun setTheme(nightModeState: String) {
when (nightModeState) {
Keys.STATE_THEME_DARK_MODE -> {
if (AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_YES) {
// turn on dark mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
LogHelper.i(TAG, "Dark Mode activated.")
}
}
Keys.STATE_THEME_LIGHT_MODE -> {
if (AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_NO) {
// turn on light mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
LogHelper.i(TAG, "Theme: Light Mode activated.")
}
}
Keys.STATE_THEME_FOLLOW_SYSTEM -> {
if (AppCompatDelegate.getDefaultNightMode() != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) {
// turn on mode "follow system"
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
LogHelper.i(TAG, "Theme: Follow System Mode activated.")
}
}
else -> {
// turn on mode "follow system"
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
LogHelper.i(TAG, "Theme: Follow System Mode activated.")
}
}
}
/* Return weather Night Mode is on, or not */
fun isDarkModeOn(context: Context): Boolean {
val nightMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return nightMode == Configuration.UI_MODE_NIGHT_YES
}
/* Returns a readable String for currently selected App Theme */
fun getCurrentTheme(context: Context): String {
return when (PreferencesHelper.loadThemeSelection(context)) {
Keys.STATE_THEME_LIGHT_MODE -> context.getString(R.string.pref_theme_selection_mode_light)
Keys.STATE_THEME_DARK_MODE -> context.getString(R.string.pref_theme_selection_mode_dark)
else -> context.getString(R.string.pref_theme_selection_mode_device_default)
}
}
/* Displays the default status bar */
private fun displayDefaultStatusBar(activity: Activity) {
val decorView = activity.window.decorView
decorView.systemUiVisibility = 0
}
/* Displays the light (inverted) status bar */
private fun displayLightStatusBar(activity: Activity) {
val decorView = activity.window.decorView
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
}

View File

@ -1,150 +0,0 @@
/*
* NightModeHelper.kt
* Implements the NightModeHelper object
* A NightModeHelper can toggle and restore the state of the theme's Night Mode
*
* This file is part of
* TRACKBOOK - Movement Recorder for Android
*
* Copyright (c) 2016-20 - Y20K.org
* Licensed under the MIT-License
* http://opensource.org/licenses/MIT
*
* Trackbook uses osmdroid - OpenStreetMap-Tools for Android
* https://github.com/osmdroid/osmdroid
*/
package org.y20k.trackbook.helpers
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import org.y20k.trackbook.R
/*
* NightModeHelper object
*/
object NightModeHelper {
/* Define log tag */
private val TAG: String = LogHelper.makeLogTag(NightModeHelper::class.java)
/* Switches between modes: day, night, undefined */
@SuppressLint("SwitchIntDef")
fun switchMode(activity: Activity) {
// SWITCH: undefined -> night / night -> day / day - undefined
when (AppCompatDelegate.getDefaultNightMode()) {
AppCompatDelegate.MODE_NIGHT_NO -> {
// currently: day mode -> switch to: follow system
// displayDefaultStatusBar(activity) // necessary hack :-/
activateFollowSystemMode(activity, true)
}
AppCompatDelegate.MODE_NIGHT_YES -> {
// currently: night mode -> switch to: day mode
// displayLightStatusBar(activity) // necessary hack :-/
activateDayMode(activity, true)
}
else -> {
// currently: follow system / undefined -> switch to: day mode
// displayLightStatusBar(activity) // necessary hack :-/
activateNightMode(activity, true)
}
}
}
/* Sets night mode / dark theme */
fun restoreSavedState(context: Context) {
val savedNightModeState = PreferencesHelper.loadNightModeState(context)
val currentNightModeState = AppCompatDelegate.getDefaultNightMode()
if (savedNightModeState != currentNightModeState) {
when (savedNightModeState) {
AppCompatDelegate.MODE_NIGHT_NO ->
// turn on day mode
activateDayMode(context, false)
AppCompatDelegate.MODE_NIGHT_YES ->
// turn on night mode
activateNightMode(context, false)
else ->
// turn on mode "follow system"
activateFollowSystemMode(context, false)
}
}
}
/* Return weather Night Mode is on, or not */
fun isNightModeOn(context: Context): Boolean {
val nightMode = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
return nightMode == Configuration.UI_MODE_NIGHT_YES
}
/* Activates Night Mode */
private fun activateNightMode(context: Context, notifyUser: Boolean) {
PreferencesHelper.saveNightModeState(context, AppCompatDelegate.MODE_NIGHT_YES)
// switch to Night Mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
// notify user
if (notifyUser) {
Toast.makeText(context, context.getText(R.string.toast_message_theme_night), Toast.LENGTH_LONG).show()
}
}
/* Activates Day Mode */
private fun activateDayMode(context: Context, notifyUser: Boolean) {
// save the new state
PreferencesHelper.saveNightModeState(context, AppCompatDelegate.MODE_NIGHT_NO)
// switch to Day Mode
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
// notify user
if (notifyUser) {
Toast.makeText(context, context.getText(R.string.toast_message_theme_day), Toast.LENGTH_LONG).show()
}
}
/* Activate Mode "Follow System" */
private fun activateFollowSystemMode(context: Context, notifyUser: Boolean) {
// save the new state
PreferencesHelper.saveNightModeState(context, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
// switch to Undefined Mode / Follow System
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
// notify user
if (notifyUser) {
Toast.makeText(context, context.getText(R.string.toast_message_theme_follow_system), Toast.LENGTH_LONG).show()
}
}
/* Displays the default status bar */
private fun displayDefaultStatusBar(activity: Activity) {
val decorView = activity.window.decorView
decorView.systemUiVisibility = 0
}
/* Displays the light (inverted) status bar */
private fun displayLightStatusBar(activity: Activity) {
val decorView = activity.window.decorView
decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
}
}

View File

@ -20,7 +20,6 @@ package org.y20k.trackbook.helpers
import android.content.Context import android.content.Context
import android.location.Location import android.location.Location
import android.location.LocationManager import android.location.LocationManager
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import org.y20k.trackbook.Keys import org.y20k.trackbook.Keys
import org.y20k.trackbook.extensions.getDouble import org.y20k.trackbook.extensions.getDouble
@ -61,7 +60,7 @@ object PreferencesHelper {
// get preferences // get preferences
val settings = PreferenceManager.getDefaultSharedPreferences(context) val settings = PreferenceManager.getDefaultSharedPreferences(context)
// load tracking state // load tracking state
return settings.getInt(Keys.PREF_TRACKING_STATE, Keys.STATE_NOT_TRACKING) return settings.getInt(Keys.PREF_TRACKING_STATE, Keys.STATE_TRACKING_NOT)
} }
@ -134,18 +133,9 @@ object PreferencesHelper {
} }
/* Load state of Night Mode */ /* Load currently selected app theme */
fun loadNightModeState(context: Context): Int { fun loadThemeSelection(context: Context): String {
return PreferenceManager.getDefaultSharedPreferences(context).getInt(Keys.PREF_NIGHT_MODE_STATE, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) return PreferenceManager.getDefaultSharedPreferences(context).getString(Keys.PREF_THEME_SELECTION, Keys.STATE_THEME_FOLLOW_SYSTEM) ?: Keys.STATE_THEME_FOLLOW_SYSTEM
}
/* Save state of night mode */
fun saveNightModeState(context: Context, currentState: Int) {
val settings = PreferenceManager.getDefaultSharedPreferences(context)
val editor = settings.edit()
editor.putInt(Keys.PREF_NIGHT_MODE_STATE, currentState)
editor.apply()
} }

View File

@ -42,9 +42,9 @@ import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider
import org.y20k.trackbook.Keys import org.y20k.trackbook.Keys
import org.y20k.trackbook.R import org.y20k.trackbook.R
import org.y20k.trackbook.core.Track import org.y20k.trackbook.core.Track
import org.y20k.trackbook.helpers.AppThemeHelper
import org.y20k.trackbook.helpers.LogHelper import org.y20k.trackbook.helpers.LogHelper
import org.y20k.trackbook.helpers.MapHelper import org.y20k.trackbook.helpers.MapHelper
import org.y20k.trackbook.helpers.NightModeHelper
import org.y20k.trackbook.helpers.PreferencesHelper import org.y20k.trackbook.helpers.PreferencesHelper
@ -97,7 +97,7 @@ data class MapFragmentLayoutHolder(var context: Context, var inflater: LayoutInf
controller.setZoom(zoomLevel) controller.setZoom(zoomLevel)
// set dark map tiles, if necessary // set dark map tiles, if necessary
if (NightModeHelper.isNightModeOn(context as Activity)) { if (AppThemeHelper.isDarkModeOn(context as Activity)) {
mapView.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS) mapView.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS)
} }
@ -119,9 +119,6 @@ data class MapFragmentLayoutHolder(var context: Context, var inflater: LayoutInf
// initialize recording button state // initialize recording button state
updateRecordingButton(trackingState) updateRecordingButton(trackingState)
// add touch listeners
addTouchListeners()
// listen for user interaction // listen for user interaction
addInteractionListener() addInteractionListener()
} }
@ -158,7 +155,7 @@ data class MapFragmentLayoutHolder(var context: Context, var inflater: LayoutInf
/* Mark current position on map */ /* Mark current position on map */
fun markCurrentPosition(location: Location, trackingState: Int = Keys.STATE_NOT_TRACKING) { fun markCurrentPosition(location: Location, trackingState: Int = Keys.STATE_TRACKING_NOT) {
mapView.overlays.remove(currentPositionOverlay) mapView.overlays.remove(currentPositionOverlay)
currentPositionOverlay = MapHelper.createMyLocationOverlay(context, location, trackingState) currentPositionOverlay = MapHelper.createMyLocationOverlay(context, location, trackingState)
mapView.overlays.add(currentPositionOverlay) mapView.overlays.add(currentPositionOverlay)
@ -180,7 +177,7 @@ data class MapFragmentLayoutHolder(var context: Context, var inflater: LayoutInf
/* Toggles state of recording button and sub menu_bottom_navigation */ /* Toggles state of recording button and sub menu_bottom_navigation */
fun updateRecordingButton(trackingState: Int) { fun updateRecordingButton(trackingState: Int) {
when (trackingState) { when (trackingState) {
Keys.STATE_NOT_TRACKING -> { Keys.STATE_TRACKING_NOT -> {
recordingButton.setImageResource(R.drawable.ic_fiber_manual_record_white_24dp) recordingButton.setImageResource(R.drawable.ic_fiber_manual_record_white_24dp)
recordingButtonSubMenu.visibility = View.GONE recordingButtonSubMenu.visibility = View.GONE
} }
@ -221,13 +218,4 @@ data class MapFragmentLayoutHolder(var context: Context, var inflater: LayoutInf
} }
} }
/* Sets up views - adds touch listeners */
private fun addTouchListeners() {
currentLocationButton.setOnLongClickListener {
NightModeHelper.switchMode(context as Activity)
return@setOnLongClickListener true
}
}
} }

View File

@ -126,8 +126,8 @@ data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutI
useImperialUnits = PreferencesHelper.loadUseImperialUnits(context) useImperialUnits = PreferencesHelper.loadUseImperialUnits(context)
// set dark map tiles, if necessary // set dark map tiles, if necessary
if (NightModeHelper.isNightModeOn(context as Activity)) { if (AppThemeHelper.isDarkModeOn(context as Activity)) {
mapView.getOverlayManager().getTilesOverlay().setColorFilter(TilesOverlay.INVERT_COLORS) mapView.overlayManager.tilesOverlay.setColorFilter(TilesOverlay.INVERT_COLORS)
} }
// add compass to map // add compass to map
@ -143,7 +143,7 @@ data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutI
} else { } else {
track = Track() track = Track()
} }
trackOverlay = MapHelper.createTrackOverlay(context, track, Keys.STATE_NOT_TRACKING) trackOverlay = MapHelper.createTrackOverlay(context, track, Keys.STATE_TRACKING_NOT)
if (track.wayPoints.isNotEmpty()) { if (track.wayPoints.isNotEmpty()) {
mapView.overlays.add(trackOverlay) mapView.overlays.add(trackOverlay)
} }

View File

@ -26,9 +26,6 @@
<!-- toast messages --> <!-- toast messages -->
<string name="toast_message_elevation_info">Tip: nøjagtigheden af højde målingerne afhænger af din enhed. Op ad og nedadgående højder på hele ruten måles.</string> <string name="toast_message_elevation_info">Tip: nøjagtigheden af højde målingerne afhænger af din enhed. Op ad og nedadgående højder på hele ruten måles.</string>
<string name="toast_message_install_file_helper">Installer filhåndtering eller GPX læser først.</string> <string name="toast_message_install_file_helper">Installer filhåndtering eller GPX læser først.</string>
<string name="toast_message_theme_night">Skifter til nat tilstand (langt tryk genkendt)</string>
<string name="toast_message_theme_day">Skifter til dag tilstand (langt tryk genkendt)</string>
<string name="toast_message_theme_follow_system">Skifter til at følge telefonens indstillinger (langt tryk genkendt)</string>
<!-- map markers --> <!-- map markers -->
<string name="marker_description_time">Tid</string> <string name="marker_description_time">Tid</string>
<string name="marker_description_accuracy">Nøjagtighed</string> <string name="marker_description_accuracy">Nøjagtighed</string>

View File

@ -27,9 +27,6 @@
<!-- toast messages --> <!-- toast messages -->
<string name="toast_message_elevation_info">Hinweis: Die Genauogkeit der Höhenmeter-Werte ist geräteabhängig. Gemessen werden die Steigungen und Gefälle der Gesamtstrecke.</string> <string name="toast_message_elevation_info">Hinweis: Die Genauogkeit der Höhenmeter-Werte ist geräteabhängig. Gemessen werden die Steigungen und Gefälle der Gesamtstrecke.</string>
<string name="toast_message_install_file_helper">Bitte zunächst einen Dateimanager oder GPX-Betrachter installieren.</string> <string name="toast_message_install_file_helper">Bitte zunächst einen Dateimanager oder GPX-Betrachter installieren.</string>
<string name="toast_message_theme_night">Nachtmodus aktiviert (Längeres Drücken erkannt)</string>
<string name="toast_message_theme_day">Tagmodus aktiviert (Längeres Drücken erkannt)</string>
<string name="toast_message_theme_follow_system">Modus Systemeinstellung Beachten aktiviert (Längeres Drücken erkannt)</string>
<!-- map markers --> <!-- map markers -->
<string name="marker_description_time">Uhrzeit</string> <string name="marker_description_time">Uhrzeit</string>
<string name="marker_description_accuracy">Genauigkeit</string> <string name="marker_description_accuracy">Genauigkeit</string>

View File

@ -27,9 +27,6 @@
<!-- toast messages --> <!-- toast messages -->
<string name="toast_message_elevation_info">Astuce : La précision des données d\'altitude dépend de votre appareil. La dénivellation globale du parcours est mesurée.</string> <string name="toast_message_elevation_info">Astuce : La précision des données d\'altitude dépend de votre appareil. La dénivellation globale du parcours est mesurée.</string>
<string name="toast_message_install_file_helper">Veuillez installer un gestionnaire de fichiers ou un visualiseur de fichier GPX.</string> <string name="toast_message_install_file_helper">Veuillez installer un gestionnaire de fichiers ou un visualiseur de fichier GPX.</string>
<string name="toast_message_theme_day">Passage au mode Jour (appui long détecté)</string>
<string name="toast_message_theme_follow_system">Passage au mode Système (appui long détecté)</string>
<string name="toast_message_theme_night">Passage au mode Nuit (appui long détecté)</string>
<!-- map markers --> <!-- map markers -->
<string name="marker_description_accuracy">Précision</string> <string name="marker_description_accuracy">Précision</string>
<string name="marker_description_time">Heure</string> <string name="marker_description_time">Heure</string>

View File

@ -27,9 +27,6 @@
<!-- toast messages --> <!-- toast messages -->
<string name="toast_message_elevation_info">Suggerimento: L\'accuratezza dei dati dell\'altitudine dipende dal tuo dispositivo. Sono misurate la salita e la discesa di tutto il percorso.</string> <string name="toast_message_elevation_info">Suggerimento: L\'accuratezza dei dati dell\'altitudine dipende dal tuo dispositivo. Sono misurate la salita e la discesa di tutto il percorso.</string>
<string name="toast_message_install_file_helper">Per favore installa prima un gestore di file o un visualizzatore di tracce GPX.</string> <string name="toast_message_install_file_helper">Per favore installa prima un gestore di file o un visualizzatore di tracce GPX.</string>
<string name="toast_message_theme_night">Passaggio alla modalità notturna (pressione prolungata rilevata)</string>
<string name="toast_message_theme_day">Passaggio alla modalità diurna (pressione prolungata rilevata)</string>
<string name="toast_message_theme_follow_system">Passaggio alla modalità Segui Impostazione di Sistema (pressione prolungata rilevata)</string>
<!-- map markers --> <!-- map markers -->
<string name="marker_description_time">Ora</string> <string name="marker_description_time">Ora</string>
<string name="marker_description_accuracy">Precisione</string> <string name="marker_description_accuracy">Precisione</string>

View File

@ -56,7 +56,4 @@
<string name="descr_fab_sub_menu_button_resume">再開ボタン</string> <string name="descr_fab_sub_menu_button_resume">再開ボタン</string>
<string name="descr_statistics_sheet_delete_button">トレース削除ボタン</string> <string name="descr_statistics_sheet_delete_button">トレース削除ボタン</string>
<string name="descr_statistics_sheet_share_button">GPX としてエクスポートする共有ボタン</string> <string name="descr_statistics_sheet_share_button">GPX としてエクスポートする共有ボタン</string>
<string name="toast_message_theme_night">夜間モードに切り替えています (長押しを検出しました)</string>
<string name="toast_message_theme_day">日中モードに切り替えています (長押しを検出しました)</string>
<string name="toast_message_theme_follow_system">システム設定モードにしたがって切り替えています (長押しを検出しました)</string>
</resources> </resources>

View File

@ -27,9 +27,6 @@
<!-- toast messages --> <!-- toast messages -->
<string name="toast_message_elevation_info">Hint: Høydedataens nøyaktighet avhenger av enheten din. Opp og ned-stigningen for hele ruten måles.</string> <string name="toast_message_elevation_info">Hint: Høydedataens nøyaktighet avhenger av enheten din. Opp og ned-stigningen for hele ruten måles.</string>
<string name="toast_message_install_file_helper">Installer en filbehandler eller en GPX-sporviser først.</string> <string name="toast_message_install_file_helper">Installer en filbehandler eller en GPX-sporviser først.</string>
<string name="toast_message_theme_night">Bytter til nattmodus (oppdaget langt trykk)</string>
<string name="toast_message_theme_day">Bytter til dagmodus (oppdaget langt trykk)</string>
<string name="toast_message_theme_follow_system">Bytter til å følge systeminnstilling (oppdaget langt trykk)</string>
<!-- map markers --> <!-- map markers -->
<string name="marker_description_time">Tid</string> <string name="marker_description_time">Tid</string>
<string name="marker_description_accuracy">Nøyaktighet</string> <string name="marker_description_accuracy">Nøyaktighet</string>

View File

@ -27,9 +27,6 @@
<!-- toast messages --> <!-- toast messages -->
<string name="toast_message_elevation_info">Tip: de nauwkeurigheid van de hoogtegegevens hangt af van uw apparaat. Het gemiddelde van de gehele route wordt genomen.</string> <string name="toast_message_elevation_info">Tip: de nauwkeurigheid van de hoogtegegevens hangt af van uw apparaat. Het gemiddelde van de gehele route wordt genomen.</string>
<string name="toast_message_install_file_helper">Installeer eerst een bestandsbeheerder of GPX-viewer.</string> <string name="toast_message_install_file_helper">Installeer eerst een bestandsbeheerder of GPX-viewer.</string>
<string name="toast_message_theme_night">Nachtmodus geactiveerd (lange druk gedetecteerd)</string>
<string name="toast_message_theme_day">Dagmodus geactiveerd (lange druk gedetecteerd)</string>
<string name="toast_message_theme_follow_system">Systeeminstellingen worden toegepast (lange druk gedetecteerd)</string>
<!-- map markers --> <!-- map markers -->
<string name="marker_description_time">Tijd</string> <string name="marker_description_time">Tijd</string>
<string name="marker_description_accuracy">Nauwkeurigheid</string> <string name="marker_description_accuracy">Nauwkeurigheid</string>

View File

@ -39,9 +39,6 @@
<!-- Toast Messages --> <!-- Toast Messages -->
<string name="toast_message_elevation_info">提示:海拔数据的准确性取决于您的设备.测量整个路线的上坡和下坡海拔.</string> <string name="toast_message_elevation_info">提示:海拔数据的准确性取决于您的设备.测量整个路线的上坡和下坡海拔.</string>
<string name="toast_message_install_file_helper">请先安装一个文件管理器或GPX轨迹查看器.</string> <string name="toast_message_install_file_helper">请先安装一个文件管理器或GPX轨迹查看器.</string>
<string name="toast_message_theme_night">切换到夜间模式(检测到长按)</string>
<string name="toast_message_theme_day">切换到白日模式(检测到长按)</string>
<string name="toast_message_theme_follow_system">切换到跟随系统设置模式(检测到长按)</string>
<!-- Map Markers --> <!-- Map Markers -->
<string name="marker_description_time">时间</string> <string name="marker_description_time">时间</string>
<string name="marker_description_accuracy">误差</string> <string name="marker_description_accuracy">误差</string>

View File

@ -39,9 +39,6 @@
<!-- Toast Messages --> <!-- Toast Messages -->
<string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string> <string name="toast_message_elevation_info">Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.</string>
<string name="toast_message_install_file_helper">Please install a file manager or a GPX track viewer first.</string> <string name="toast_message_install_file_helper">Please install a file manager or a GPX track viewer first.</string>
<string name="toast_message_theme_night">Switching to Night mode (long press detected)</string>
<string name="toast_message_theme_day">Switching to Day mode (long press detected)</string>
<string name="toast_message_theme_follow_system">Switching to Follow System Setting mode (long press detected)</string>
<!-- Map Markers --> <!-- Map Markers -->
<string name="marker_description_time">Time</string> <string name="marker_description_time">Time</string>
<string name="marker_description_accuracy">Accuracy</string> <string name="marker_description_accuracy">Accuracy</string>
@ -79,6 +76,11 @@
<string name="pref_imperial_measurement_units_title">Use Imperial Measurements</string> <string name="pref_imperial_measurement_units_title">Use Imperial Measurements</string>
<string name="pref_reset_advanced_summary">Reset advanced settings to defaults.</string> <string name="pref_reset_advanced_summary">Reset advanced settings to defaults.</string>
<string name="pref_reset_advanced_title">Reset</string> <string name="pref_reset_advanced_title">Reset</string>
<string name="pref_theme_selection_mode_dark">Dark mode</string>
<string name="pref_theme_selection_mode_device_default">Same as device</string>
<string name="pref_theme_selection_mode_light">Light mode</string>
<string name="pref_theme_selection_summary">Current theme:</string>
<string name="pref_theme_selection_title">App Theme</string>
<!-- Abbreviations --> <!-- Abbreviations -->
<string name="abbreviation_hours">hrs</string> <string name="abbreviation_hours">hrs</string>
<string name="abbreviation_minutes">min</string> <string name="abbreviation_minutes">min</string>

View File

@ -10,7 +10,7 @@ buildscript {
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.3' classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.1.0" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.2.0"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
} }