parent
d61a228268
commit
2944273a01
58 changed files with 440 additions and 629 deletions
|
@ -1,9 +0,0 @@
|
||||||
# editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
indent_style = space
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
|
@ -44,8 +44,7 @@ object Keys {
|
||||||
const val ARG_TRACK_ID: String = "ArgTrackId"
|
const val ARG_TRACK_ID: String = "ArgTrackId"
|
||||||
|
|
||||||
// preferences
|
// preferences
|
||||||
const val PREF_ONE_TIME_HOUSEKEEPING_NECESSARY =
|
const val PREF_ONE_TIME_HOUSEKEEPING_NECESSARY = "ONE_TIME_HOUSEKEEPING_NECESSARY_VERSIONCODE_38" // increment to current app version code to trigger housekeeping that runs only once
|
||||||
"ONE_TIME_HOUSEKEEPING_NECESSARY_VERSIONCODE_38" // increment to current app version code to trigger housekeeping that runs only once
|
|
||||||
const val PREF_THEME_SELECTION: String= "prefThemeSelection"
|
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"
|
||||||
|
@ -96,29 +95,21 @@ object Keys {
|
||||||
const val DEFAULT_RFC2822_DATE: String = "Thu, 01 Jan 1970 01:00:00 +0100" // --> Date(0)
|
const val DEFAULT_RFC2822_DATE: String = "Thu, 01 Jan 1970 01:00:00 +0100" // --> Date(0)
|
||||||
const val ONE_HOUR_IN_MILLISECONDS: Int = 3600000
|
const val ONE_HOUR_IN_MILLISECONDS: Int = 3600000
|
||||||
const val EMPTY_STRING_RESOURCE: Int = 0
|
const val EMPTY_STRING_RESOURCE: Int = 0
|
||||||
const val REQUEST_CURRENT_LOCATION_INTERVAL: Long =
|
const val REQUEST_CURRENT_LOCATION_INTERVAL: Long = 1000L // 1 second in milliseconds
|
||||||
1000L // 1 second in milliseconds
|
const val ADD_WAYPOINT_TO_TRACK_INTERVAL: Long = 15000L // 15 seconds in milliseconds
|
||||||
const val ADD_WAYPOINT_TO_TRACK_INTERVAL: Long =
|
const val SIGNIFICANT_TIME_DIFFERENCE: Long = 120000L // 2 minutes in milliseconds
|
||||||
15000L // 15 seconds in milliseconds
|
const val STOP_OVER_THRESHOLD: Long = 300000L // 5 minutes in milliseconds
|
||||||
const val SIGNIFICANT_TIME_DIFFERENCE: Long =
|
|
||||||
120000L // 2 minutes in milliseconds
|
|
||||||
const val STOP_OVER_THRESHOLD: Long =
|
|
||||||
300000L // 5 minutes in milliseconds
|
|
||||||
const val IMPLAUSIBLE_TRACK_START_SPEED: Double = 250.0 // 250 km/h
|
const val IMPLAUSIBLE_TRACK_START_SPEED: Double = 250.0 // 250 km/h
|
||||||
const val DEFAULT_LATITUDE: Double =
|
const val DEFAULT_LATITUDE: Double = 71.172500 // latitude Nordkapp, Norway
|
||||||
71.172500 // latitude Nordkapp, Norway
|
const val DEFAULT_LONGITUDE: Double = 25.784444 // longitude Nordkapp, Norway
|
||||||
const val DEFAULT_LONGITUDE: Double =
|
|
||||||
25.784444 // longitude Nordkapp, Norway
|
|
||||||
const val DEFAULT_ACCURACY: Float = 300f // in meters
|
const val DEFAULT_ACCURACY: Float = 300f // in meters
|
||||||
const val DEFAULT_ALTITUDE: Double = 0.0
|
const val DEFAULT_ALTITUDE: Double = 0.0
|
||||||
const val DEFAULT_TIME: Long = 0L
|
const val DEFAULT_TIME: Long = 0L
|
||||||
const val DEFAULT_THRESHOLD_LOCATION_ACCURACY: Int = 30 // 30 meters
|
const val DEFAULT_THRESHOLD_LOCATION_ACCURACY: Int = 30 // 30 meters
|
||||||
const val DEFAULT_THRESHOLD_LOCATION_AGE: Long =
|
const val DEFAULT_THRESHOLD_LOCATION_AGE: Long = 60000000000L // one minute in nanoseconds
|
||||||
60000000000L // one minute in nanoseconds
|
|
||||||
const val DEFAULT_THRESHOLD_DISTANCE: Float = 15f // 15 meters
|
const val DEFAULT_THRESHOLD_DISTANCE: Float = 15f // 15 meters
|
||||||
const val DEFAULT_ZOOM_LEVEL: Double = 16.0
|
const val DEFAULT_ZOOM_LEVEL: Double = 16.0
|
||||||
const val ALTITUDE_MEASUREMENT_ERROR_THRESHOLD =
|
const val ALTITUDE_MEASUREMENT_ERROR_THRESHOLD = 10 // altitude changes of 10 meter or more (per 15 seconds) are being discarded
|
||||||
10 // altitude changes of 10 meter or more (per 15 seconds) are being discarded
|
|
||||||
const val REQUEST_CODE_FOREGROUND = 42
|
const val REQUEST_CODE_FOREGROUND = 42
|
||||||
|
|
||||||
// requests
|
// requests
|
||||||
|
|
|
@ -69,8 +69,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
// set up views
|
// set up views
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
navHostFragment =
|
navHostFragment = supportFragmentManager.findFragmentById(R.id.main_container) as NavHostFragment
|
||||||
supportFragmentManager.findFragmentById(R.id.main_container) as NavHostFragment
|
|
||||||
bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_navigation_view)
|
bottomNavigationView = findViewById<BottomNavigationView>(R.id.bottom_navigation_view)
|
||||||
bottomNavigationView.setupWithNavController(navController = navHostFragment.navController)
|
bottomNavigationView.setupWithNavController(navController = navHostFragment.navController)
|
||||||
|
|
||||||
|
@ -78,13 +77,12 @@ class MainActivity : AppCompatActivity() {
|
||||||
navHostFragment.navController.addOnDestinationChangedListener { _, destination, _ ->
|
navHostFragment.navController.addOnDestinationChangedListener { _, destination, _ ->
|
||||||
when (destination.id) {
|
when (destination.id) {
|
||||||
R.id.fragment_track -> {
|
R.id.fragment_track -> {
|
||||||
runOnUiThread {
|
runOnUiThread( Runnable() {
|
||||||
run {
|
run(){
|
||||||
// mark menu item "Tracks" as checked
|
// mark menu item "Tracks" as checked
|
||||||
bottomNavigationView.menu.findItem(R.id.tracklist_fragment)
|
bottomNavigationView.menu.findItem(R.id.tracklist_fragment).setChecked(true)
|
||||||
.setChecked(true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
@ -93,8 +91,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// register listener for changes in shared preferences
|
// register listener for changes in shared preferences
|
||||||
PreferenceManager.getDefaultSharedPreferences(this as Context)
|
PreferenceManager.getDefaultSharedPreferences(this as Context).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
||||||
.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,16 +99,14 @@ class MainActivity : AppCompatActivity() {
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
// unregister listener for changes in shared preferences
|
// unregister listener for changes in shared preferences
|
||||||
PreferenceManager.getDefaultSharedPreferences(this as Context)
|
PreferenceManager.getDefaultSharedPreferences(this as Context).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
||||||
.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Defines the listener for changes in shared preferences
|
* Defines the listener for changes in shared preferences
|
||||||
*/
|
*/
|
||||||
private val sharedPreferenceChangeListener =
|
private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
|
|
||||||
when (key) {
|
when (key) {
|
||||||
Keys.PREF_THEME_SELECTION -> {
|
Keys.PREF_THEME_SELECTION -> {
|
||||||
AppThemeHelper.setTheme(PreferencesHelper.loadThemeSelection(this@MainActivity))
|
AppThemeHelper.setTheme(PreferencesHelper.loadThemeSelection(this@MainActivity))
|
||||||
|
|
|
@ -73,20 +73,9 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
|
|
||||||
|
|
||||||
/* Overrides onStop from Fragment */
|
/* Overrides onStop from Fragment */
|
||||||
override fun onCreateView(
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
// initialize layout
|
// initialize layout
|
||||||
layout = MapFragmentLayoutHolder(
|
layout = MapFragmentLayoutHolder(activity as Context, this as MapOverlay.MarkerListener, inflater, container, currentBestLocation, trackingState)
|
||||||
activity as Context,
|
|
||||||
this as MapOverlay.MarkerListener,
|
|
||||||
inflater,
|
|
||||||
container,
|
|
||||||
currentBestLocation,
|
|
||||||
trackingState
|
|
||||||
)
|
|
||||||
|
|
||||||
// set up buttons
|
// set up buttons
|
||||||
layout.currentLocationButton.setOnClickListener {
|
layout.currentLocationButton.setOnClickListener {
|
||||||
|
@ -115,22 +104,11 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
// request location permission if denied
|
// request location permission if denied
|
||||||
if (ContextCompat.checkSelfPermission(
|
if (ContextCompat.checkSelfPermission(activity as Context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
|
||||||
activity as Context,
|
this.requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), Keys.REQUEST_CODE_FOREGROUND)
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION
|
|
||||||
) == PackageManager.PERMISSION_DENIED
|
|
||||||
) {
|
|
||||||
this.requestPermissions(
|
|
||||||
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
|
|
||||||
Keys.REQUEST_CODE_FOREGROUND
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
// bind to TrackerService
|
// bind to TrackerService
|
||||||
activity?.bindService(
|
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
|
||||||
Intent(activity, TrackerService::class.java),
|
|
||||||
connection,
|
|
||||||
Context.BIND_AUTO_CREATE
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -164,22 +142,14 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
|
|
||||||
|
|
||||||
/* Overrides onRequestPermissionsResult from Fragment */
|
/* Overrides onRequestPermissionsResult from Fragment */
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||||
requestCode: Int,
|
|
||||||
permissions: Array<String>,
|
|
||||||
grantResults: IntArray
|
|
||||||
) {
|
|
||||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||||
when (requestCode) {
|
when (requestCode) {
|
||||||
Keys.REQUEST_CODE_FOREGROUND -> {
|
Keys.REQUEST_CODE_FOREGROUND -> {
|
||||||
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
|
||||||
// permission was granted - re-bind service
|
// permission was granted - re-bind service
|
||||||
activity?.unbindService(connection)
|
activity?.unbindService(connection)
|
||||||
activity?.bindService(
|
activity?.bindService(Intent(activity, TrackerService::class.java), connection, Context.BIND_AUTO_CREATE)
|
||||||
Intent(activity, TrackerService::class.java),
|
|
||||||
connection,
|
|
||||||
Context.BIND_AUTO_CREATE
|
|
||||||
)
|
|
||||||
LogHelper.i(TAG, "Request result: Location permission has been granted.")
|
LogHelper.i(TAG, "Request result: Location permission has been granted.")
|
||||||
} else {
|
} else {
|
||||||
// permission denied - unbind service
|
// permission denied - unbind service
|
||||||
|
@ -193,12 +163,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
|
|
||||||
|
|
||||||
/* Overrides onYesNoDialog from YesNoDialogListener */
|
/* Overrides onYesNoDialog from YesNoDialogListener */
|
||||||
override fun onYesNoDialog(
|
override fun onYesNoDialog(type: Int, dialogResult: Boolean, payload: Int, payloadString: String) {
|
||||||
type: Int,
|
|
||||||
dialogResult: Boolean,
|
|
||||||
payload: Int,
|
|
||||||
payloadString: String
|
|
||||||
) {
|
|
||||||
super.onYesNoDialog(type, dialogResult, payload, payloadString)
|
super.onYesNoDialog(type, dialogResult, payload, payloadString)
|
||||||
when (type) {
|
when (type) {
|
||||||
Keys.DIALOG_EMPTY_RECORDING -> {
|
Keys.DIALOG_EMPTY_RECORDING -> {
|
||||||
|
@ -253,18 +218,11 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
/* Saves track - shows dialog, if recording is still empty */
|
/* Saves track - shows dialog, if recording is still empty */
|
||||||
private fun saveTrack() {
|
private fun saveTrack() {
|
||||||
if (track.wayPoints.isEmpty()) {
|
if (track.wayPoints.isEmpty()) {
|
||||||
YesNoDialog(this as YesNoDialog.YesNoDialogListener).show(
|
YesNoDialog(this as YesNoDialog.YesNoDialogListener).show(activity as Context, type = Keys.DIALOG_EMPTY_RECORDING, title = R.string.dialog_error_empty_recording_title, message = R.string.dialog_error_empty_recording_message, yesButton = R.string.dialog_error_empty_recording_action_resume)
|
||||||
activity as Context,
|
|
||||||
type = Keys.DIALOG_EMPTY_RECORDING,
|
|
||||||
title = R.string.dialog_error_empty_recording_title,
|
|
||||||
message = R.string.dialog_error_empty_recording_message,
|
|
||||||
yesButton = R.string.dialog_error_empty_recording_action_resume
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
GlobalScope.launch {
|
GlobalScope.launch {
|
||||||
// step 1: create and store filenames for json and gpx files
|
// step 1: create and store filenames for json and gpx files
|
||||||
track.trackUriString =
|
track.trackUriString = FileHelper.getTrackFileUri(activity as Context, track).toString()
|
||||||
FileHelper.getTrackFileUri(activity as Context, track).toString()
|
|
||||||
track.gpxUriString = FileHelper.getGpxFileUri(activity as Context, track).toString()
|
track.gpxUriString = FileHelper.getGpxFileUri(activity as Context, track).toString()
|
||||||
// step 2: save track
|
// step 2: save track
|
||||||
FileHelper.saveTrackSuspended(track, saveGpxToo = true)
|
FileHelper.saveTrackSuspended(track, saveGpxToo = true)
|
||||||
|
@ -281,7 +239,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
|
|
||||||
/* Opens a track in TrackFragment */
|
/* Opens a track in TrackFragment */
|
||||||
private fun openTrack(tracklistElement: TracklistElement) {
|
private fun openTrack(tracklistElement: TracklistElement) {
|
||||||
val bundle = Bundle()
|
val bundle: Bundle = Bundle()
|
||||||
bundle.putString(Keys.ARG_TRACK_TITLE, tracklistElement.name)
|
bundle.putString(Keys.ARG_TRACK_TITLE, tracklistElement.name)
|
||||||
bundle.putString(Keys.ARG_TRACK_FILE_URI, tracklistElement.trackUriString)
|
bundle.putString(Keys.ARG_TRACK_FILE_URI, tracklistElement.trackUriString)
|
||||||
bundle.putString(Keys.ARG_GPX_FILE_URI, tracklistElement.gpxUriString)
|
bundle.putString(Keys.ARG_GPX_FILE_URI, tracklistElement.gpxUriString)
|
||||||
|
@ -293,8 +251,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
/*
|
/*
|
||||||
* Defines the listener for changes in shared preferences
|
* Defines the listener for changes in shared preferences
|
||||||
*/
|
*/
|
||||||
private val sharedPreferenceChangeListener =
|
private val sharedPreferenceChangeListener = SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
|
|
||||||
when (key) {
|
when (key) {
|
||||||
Keys.PREF_TRACKING_STATE -> {
|
Keys.PREF_TRACKING_STATE -> {
|
||||||
if (activity != null) {
|
if (activity != null) {
|
||||||
|
@ -322,18 +279,15 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
trackingState = trackerService.trackingState
|
trackingState = trackerService.trackingState
|
||||||
layout.updateRecordingButton(trackingState)
|
layout.updateRecordingButton(trackingState)
|
||||||
// register listener for changes in shared preferences
|
// register listener for changes in shared preferences
|
||||||
PreferenceManager.getDefaultSharedPreferences(activity as Context)
|
PreferenceManager.getDefaultSharedPreferences(activity as Context).registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
||||||
.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
|
||||||
// start listening for location updates
|
// start listening for location updates
|
||||||
handler.removeCallbacks(periodicLocationRequestRunnable)
|
handler.removeCallbacks(periodicLocationRequestRunnable)
|
||||||
handler.postDelayed(periodicLocationRequestRunnable, 0)
|
handler.postDelayed(periodicLocationRequestRunnable, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onServiceDisconnected(arg0: ComponentName) {
|
override fun onServiceDisconnected(arg0: ComponentName) {
|
||||||
bound = false
|
bound = false
|
||||||
// unregister listener for changes in shared preferences
|
// unregister listener for changes in shared preferences
|
||||||
PreferenceManager.getDefaultSharedPreferences(activity as Context)
|
PreferenceManager.getDefaultSharedPreferences(activity as Context).unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
||||||
.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener)
|
|
||||||
// stop receiving location updates
|
// stop receiving location updates
|
||||||
handler.removeCallbacks(periodicLocationRequestRunnable)
|
handler.removeCallbacks(periodicLocationRequestRunnable)
|
||||||
}
|
}
|
||||||
|
@ -358,9 +312,7 @@ class MapFragment : Fragment(), YesNoDialog.YesNoDialogListener, MapOverlay.Mark
|
||||||
layout.markCurrentPosition(currentBestLocation, trackingState)
|
layout.markCurrentPosition(currentBestLocation, trackingState)
|
||||||
layout.overlayCurrentTrack(track, trackingState)
|
layout.overlayCurrentTrack(track, trackingState)
|
||||||
// center map, if it had not been dragged/zoomed before
|
// center map, if it had not been dragged/zoomed before
|
||||||
if (!layout.userInteraction) {
|
if (!layout.userInteraction) { layout.centerMap(currentBestLocation, true)}
|
||||||
layout.centerMap(currentBestLocation, true)
|
|
||||||
}
|
|
||||||
// show error snackbar if necessary
|
// show error snackbar if necessary
|
||||||
layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive)
|
layout.toggleLocationErrorBar(gpsProviderActive, networkProviderActive)
|
||||||
// use the handler to start runnable again after specified delay
|
// use the handler to start runnable again after specified delay
|
||||||
|
|
|
@ -32,8 +32,7 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Track(
|
data class Track (@Expose var trackFormatVersion: Int = Keys.CURRENT_TRACK_FORMAT_VERSION,
|
||||||
@Expose var trackFormatVersion: Int = Keys.CURRENT_TRACK_FORMAT_VERSION,
|
|
||||||
@Expose val wayPoints: MutableList<WayPoint> = mutableListOf<WayPoint>(),
|
@Expose val wayPoints: MutableList<WayPoint> = mutableListOf<WayPoint>(),
|
||||||
@Expose var length: Float = 0f,
|
@Expose var length: Float = 0f,
|
||||||
@Expose var duration: Long = 0L,
|
@Expose var duration: Long = 0L,
|
||||||
|
@ -50,8 +49,7 @@ data class Track(
|
||||||
@Expose var latitude: Double = Keys.DEFAULT_LATITUDE,
|
@Expose var latitude: Double = Keys.DEFAULT_LATITUDE,
|
||||||
@Expose var longitude: Double = Keys.DEFAULT_LONGITUDE,
|
@Expose var longitude: Double = Keys.DEFAULT_LONGITUDE,
|
||||||
@Expose var zoomLevel: Double = Keys.DEFAULT_ZOOM_LEVEL,
|
@Expose var zoomLevel: Double = Keys.DEFAULT_ZOOM_LEVEL,
|
||||||
@Expose var name: String = String()
|
@Expose var name: String = String()): Parcelable {
|
||||||
) : Parcelable {
|
|
||||||
|
|
||||||
|
|
||||||
/* Creates a TracklistElement */
|
/* Creates a TracklistElement */
|
||||||
|
|
|
@ -31,11 +31,9 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class Tracklist(
|
data class Tracklist (@Expose val tracklistFormatVersion: Int = Keys.CURRENT_TRACKLIST_FORMAT_VERSION,
|
||||||
@Expose val tracklistFormatVersion: Int = Keys.CURRENT_TRACKLIST_FORMAT_VERSION,
|
|
||||||
@Expose val tracklistElements: MutableList<TracklistElement> = mutableListOf<TracklistElement>(),
|
@Expose val tracklistElements: MutableList<TracklistElement> = mutableListOf<TracklistElement>(),
|
||||||
@Expose var modificationDate: Date = Date()
|
@Expose var modificationDate: Date = Date()): Parcelable {
|
||||||
) : Parcelable {
|
|
||||||
|
|
||||||
/* Return trackelement for given track id */
|
/* Return trackelement for given track id */
|
||||||
fun getTrackElement(trackId: Long): TracklistElement? {
|
fun getTrackElement(trackId: Long): TracklistElement? {
|
||||||
|
@ -49,11 +47,7 @@ data class Tracklist(
|
||||||
|
|
||||||
/* Create a deep copy */
|
/* Create a deep copy */
|
||||||
fun deepCopy(): Tracklist {
|
fun deepCopy(): Tracklist {
|
||||||
return Tracklist(
|
return Tracklist(tracklistFormatVersion, mutableListOf<TracklistElement>().apply { addAll(tracklistElements) }, modificationDate)
|
||||||
tracklistFormatVersion,
|
|
||||||
mutableListOf<TracklistElement>().apply { addAll(tracklistElements) },
|
|
||||||
modificationDate
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -29,16 +29,14 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class TracklistElement(
|
data class TracklistElement(@Expose var name: String,
|
||||||
@Expose var name: String,
|
|
||||||
@Expose val date: Date,
|
@Expose val date: Date,
|
||||||
@Expose val dateString: String,
|
@Expose val dateString: String,
|
||||||
@Expose val durationString: String,
|
@Expose val durationString: String,
|
||||||
@Expose val length: Float,
|
@Expose val length: Float,
|
||||||
@Expose val trackUriString: String,
|
@Expose val trackUriString: String,
|
||||||
@Expose val gpxUriString: String,
|
@Expose val gpxUriString: String,
|
||||||
@Expose var starred: Boolean = false
|
@Expose var starred: Boolean = false): Parcelable {
|
||||||
) : Parcelable {
|
|
||||||
|
|
||||||
/* Returns unique ID for TracklistElement - currently the start date */
|
/* Returns unique ID for TracklistElement - currently the start date */
|
||||||
fun getTrackId(): Long {
|
fun getTrackId(): Long {
|
||||||
|
|
|
@ -29,8 +29,7 @@ import kotlinx.android.parcel.Parcelize
|
||||||
*/
|
*/
|
||||||
@Keep
|
@Keep
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class WayPoint(
|
data class WayPoint(@Expose val provider: String,
|
||||||
@Expose val provider: String,
|
|
||||||
@Expose val latitude: Double,
|
@Expose val latitude: Double,
|
||||||
@Expose val longitude: Double,
|
@Expose val longitude: Double,
|
||||||
@Expose val altitude: Double,
|
@Expose val altitude: Double,
|
||||||
|
@ -39,8 +38,7 @@ data class WayPoint(
|
||||||
@Expose val distanceToStartingPoint: Float = 0f,
|
@Expose val distanceToStartingPoint: Float = 0f,
|
||||||
@Expose val numberSatellites: Int = 0,
|
@Expose val numberSatellites: Int = 0,
|
||||||
@Expose var isStopOver: Boolean = false,
|
@Expose var isStopOver: Boolean = false,
|
||||||
@Expose var starred: Boolean = false
|
@Expose var starred: Boolean = false): Parcelable {
|
||||||
) : Parcelable {
|
|
||||||
|
|
||||||
|
|
||||||
/* Converts WayPoint into Location */
|
/* Converts WayPoint into Location */
|
||||||
|
|
|
@ -45,7 +45,7 @@ class RenameTrackDialog(private var renameTrackListener: RenameTrackListener) {
|
||||||
/* Construct and show dialog */
|
/* Construct and show dialog */
|
||||||
fun show(context: Context, trackName: String) {
|
fun show(context: Context, trackName: String) {
|
||||||
// prepare dialog builder
|
// prepare dialog builder
|
||||||
val builder = MaterialAlertDialogBuilder(context)
|
val builder: MaterialAlertDialogBuilder = MaterialAlertDialogBuilder(context)
|
||||||
|
|
||||||
// get input field
|
// get input field
|
||||||
val inflater = LayoutInflater.from(context)
|
val inflater = LayoutInflater.from(context)
|
||||||
|
|
|
@ -99,4 +99,6 @@ object AppThemeHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -34,24 +34,22 @@ object DateTimeHelper {
|
||||||
|
|
||||||
/* Converts milliseconds to mm:ss or hh:mm:ss */
|
/* Converts milliseconds to mm:ss or hh:mm:ss */
|
||||||
fun convertToReadableTime(context: Context, milliseconds: Long): String {
|
fun convertToReadableTime(context: Context, milliseconds: Long): String {
|
||||||
val timeString: String
|
var timeString: String = String()
|
||||||
val hours: Long = TimeUnit.MILLISECONDS.toHours(milliseconds)
|
val hours: Long = TimeUnit.MILLISECONDS.toHours(milliseconds)
|
||||||
val minutes: Long =
|
val minutes: Long = TimeUnit.MILLISECONDS.toMinutes(milliseconds) % TimeUnit.HOURS.toMinutes(1)
|
||||||
TimeUnit.MILLISECONDS.toMinutes(milliseconds) % TimeUnit.HOURS.toMinutes(1)
|
val seconds: Long = TimeUnit.MILLISECONDS.toSeconds(milliseconds) % TimeUnit.MINUTES.toSeconds(1)
|
||||||
val seconds: Long =
|
|
||||||
TimeUnit.MILLISECONDS.toSeconds(milliseconds) % TimeUnit.MINUTES.toSeconds(1)
|
|
||||||
val h: String = context.getString(R.string.abbreviation_hours)
|
val h: String = context.getString(R.string.abbreviation_hours)
|
||||||
val m: String = context.getString(R.string.abbreviation_minutes)
|
val m: String = context.getString(R.string.abbreviation_minutes)
|
||||||
val s: String = context.getString(R.string.abbreviation_seconds)
|
val s: String = context.getString(R.string.abbreviation_seconds)
|
||||||
|
|
||||||
timeString = when (milliseconds >= Keys.ONE_HOUR_IN_MILLISECONDS) {
|
when (milliseconds >= Keys.ONE_HOUR_IN_MILLISECONDS) {
|
||||||
// CASE: format hh:mm:ss
|
// CASE: format hh:mm:ss
|
||||||
true -> {
|
true -> {
|
||||||
"$hours $h $minutes $m $seconds $s"
|
timeString = "$hours $h $minutes $m $seconds $s"
|
||||||
}
|
}
|
||||||
// CASE: format mm:ss
|
// CASE: format mm:ss
|
||||||
false -> {
|
false -> {
|
||||||
"$minutes $m $seconds $s"
|
timeString = "$minutes $m $seconds $s"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return timeString
|
return timeString
|
||||||
|
@ -60,7 +58,7 @@ object DateTimeHelper {
|
||||||
|
|
||||||
/* Create sortable string for date - used for filenames */
|
/* Create sortable string for date - used for filenames */
|
||||||
fun convertToSortableDateString(date: Date): String {
|
fun convertToSortableDateString(date: Date): String {
|
||||||
val dateFormat = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US)
|
val dateFormat: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US)
|
||||||
return dateFormat.format(date)
|
return dateFormat.format(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,20 +70,14 @@ object DateTimeHelper {
|
||||||
|
|
||||||
|
|
||||||
/* Creates a readable string date and time - used in the UI */
|
/* Creates a readable string date and time - used in the UI */
|
||||||
fun convertToReadableDateAndTime(
|
fun convertToReadableDateAndTime(date: Date, dateStyle: Int = DateFormat.SHORT, timeStyle: Int = DateFormat.SHORT): String {
|
||||||
date: Date,
|
return "${DateFormat.getDateInstance(dateStyle, Locale.getDefault()).format(date)} ${DateFormat.getTimeInstance(timeStyle, Locale.getDefault()).format(date)}"
|
||||||
dateStyle: Int = DateFormat.SHORT,
|
|
||||||
timeStyle: Int = DateFormat.SHORT
|
|
||||||
): String {
|
|
||||||
return "${DateFormat.getDateInstance(dateStyle, Locale.getDefault())
|
|
||||||
.format(date)} ${DateFormat.getTimeInstance(timeStyle, Locale.getDefault())
|
|
||||||
.format(date)}"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Calculates time difference between two locations */
|
/* Calculates time difference between two locations */
|
||||||
fun calculateTimeDistance(previousLocation: Location?, location: Location): Long {
|
fun calculateTimeDistance(previousLocation: Location?, location: Location): Long {
|
||||||
var timeDifference = 0L
|
var timeDifference: Long = 0L
|
||||||
// two data points needed to calculate time difference
|
// two data points needed to calculate time difference
|
||||||
if (previousLocation != null) {
|
if (previousLocation != null) {
|
||||||
// get time difference
|
// get time difference
|
||||||
|
|
|
@ -89,49 +89,43 @@ object LengthUnitHelper {
|
||||||
/* Determines which unit system the device is using (metric or imperial) */
|
/* Determines which unit system the device is using (metric or imperial) */
|
||||||
fun useImperialUnits(): Boolean {
|
fun useImperialUnits(): Boolean {
|
||||||
// America (US), Liberia (LR), Myanmar(MM) use the imperial system
|
// America (US), Liberia (LR), Myanmar(MM) use the imperial system
|
||||||
val imperialSystemCountries = listOf("US", "LR", "MM")
|
val imperialSystemCountries = Arrays.asList("US", "LR", "MM")
|
||||||
val countryCode = Locale.getDefault().country
|
val countryCode = Locale.getDefault().country
|
||||||
return imperialSystemCountries.contains(countryCode)
|
return imperialSystemCountries.contains(countryCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Converts for the given unit System distance and duration values to a readable velocity string */
|
/* Converts for the given unit System distance and duration values to a readable velocity string */
|
||||||
fun convertToVelocityString(
|
fun convertToVelocityString(trackDuration: Long, trackRecordingPause: Long, trackLength: Float, useImperialUnits: Boolean = false) : String {
|
||||||
trackDuration: Long,
|
var speed: String = "0"
|
||||||
trackRecordingPause: Long,
|
|
||||||
trackLength: Float,
|
|
||||||
useImperialUnits: Boolean = false
|
|
||||||
): String {
|
|
||||||
var speed = "0"
|
|
||||||
|
|
||||||
// duration minus pause in seconds
|
// duration minus pause in seconds
|
||||||
val duration: Long = (trackDuration - trackRecordingPause) / 1000L
|
val duration: Long = (trackDuration - trackRecordingPause) / 1000L
|
||||||
|
|
||||||
if (duration > 0L) {
|
if (duration > 0L) {
|
||||||
// speed in km/h / mph
|
// speed in km/h / mph
|
||||||
val velocity: Double =
|
val velocity: Double = convertMetersPerSecond((trackLength / duration), useImperialUnits)
|
||||||
convertMetersPerSecond((trackLength / duration), useImperialUnits)
|
|
||||||
// create readable speed string
|
// create readable speed string
|
||||||
var bd: BigDecimal = BigDecimal.valueOf(velocity)
|
var bd: BigDecimal = BigDecimal.valueOf(velocity)
|
||||||
bd = bd.setScale(1, RoundingMode.HALF_UP)
|
bd = bd.setScale(1, RoundingMode.HALF_UP)
|
||||||
speed = bd.toPlainString()
|
speed = bd.toPlainString()
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (useImperialUnits) {
|
when (useImperialUnits) {
|
||||||
true -> "$speed mph"
|
true -> return "$speed mph"
|
||||||
false -> "$speed km/h"
|
false -> return "$speed km/h"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Coverts meters per second to either km/h or mph */
|
/* Coverts meters per second to either km/h or mph */
|
||||||
fun convertMetersPerSecond(metersPerSecond: Float, useImperial: Boolean = false): Double {
|
fun convertMetersPerSecond(metersPerSecond: Float, useImperial: Boolean = false): Double {
|
||||||
return if (useImperial) {
|
if (useImperial) {
|
||||||
// mph
|
// mph
|
||||||
metersPerSecond * 2.2369362920544
|
return metersPerSecond * 2.2369362920544
|
||||||
} else {
|
} else {
|
||||||
// km/h
|
// km/h
|
||||||
metersPerSecond * 3.6
|
return metersPerSecond * 3.6
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@ package org.y20k.trackbook.helpers
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.os.Build
|
|
||||||
import android.os.VibrationEffect
|
|
||||||
import android.os.Vibrator
|
import android.os.Vibrator
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
@ -53,11 +51,7 @@ class MapOverlay(private var markerListener: MarkerListener) {
|
||||||
|
|
||||||
|
|
||||||
/* Creates icon overlay for current position (used in MapFragment) */
|
/* Creates icon overlay for current position (used in MapFragment) */
|
||||||
fun createMyLocationOverlay(
|
fun createMyLocationOverlay(context: Context, location: Location, trackingState: Int): ItemizedIconOverlay<OverlayItem> {
|
||||||
context: Context,
|
|
||||||
location: Location,
|
|
||||||
trackingState: Int
|
|
||||||
): ItemizedIconOverlay<OverlayItem> {
|
|
||||||
|
|
||||||
val overlayItems = ArrayList<OverlayItem>()
|
val overlayItems = ArrayList<OverlayItem>()
|
||||||
val locationIsOld = LocationHelper.isOldLocation(location)
|
val locationIsOld = LocationHelper.isOldLocation(location)
|
||||||
|
@ -67,41 +61,22 @@ class MapOverlay(private var markerListener: MarkerListener) {
|
||||||
when (trackingState) {
|
when (trackingState) {
|
||||||
// CASE: Tracking active
|
// CASE: Tracking active
|
||||||
Keys.STATE_TRACKING_ACTIVE -> {
|
Keys.STATE_TRACKING_ACTIVE -> {
|
||||||
newMarker = when (locationIsOld) {
|
when (locationIsOld) {
|
||||||
true -> ContextCompat.getDrawable(
|
true -> newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_red_grey_24dp)!!
|
||||||
context,
|
false -> newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_red_24dp)!!
|
||||||
R.drawable.ic_marker_location_red_grey_24dp
|
|
||||||
)!!
|
|
||||||
false -> ContextCompat.getDrawable(
|
|
||||||
context,
|
|
||||||
R.drawable.ic_marker_location_red_24dp
|
|
||||||
)!!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CASE. Tracking is NOT active
|
// CASE. Tracking is NOT active
|
||||||
else -> {
|
else -> {
|
||||||
newMarker = when (locationIsOld) {
|
when (locationIsOld) {
|
||||||
true -> ContextCompat.getDrawable(
|
true -> newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_blue_grey_24dp)!!
|
||||||
context,
|
false -> newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_location_blue_24dp)!!
|
||||||
R.drawable.ic_marker_location_blue_grey_24dp
|
|
||||||
)!!
|
|
||||||
false -> ContextCompat.getDrawable(
|
|
||||||
context,
|
|
||||||
R.drawable.ic_marker_location_blue_24dp
|
|
||||||
)!!
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add marker to list of overlay items
|
// add marker to list of overlay items
|
||||||
val overlayItem = createOverlayItem(
|
val overlayItem = createOverlayItem(context, location.latitude, location.longitude, location.accuracy, location.provider, location.time)
|
||||||
context,
|
|
||||||
location.latitude,
|
|
||||||
location.longitude,
|
|
||||||
location.accuracy,
|
|
||||||
location.provider,
|
|
||||||
location.time
|
|
||||||
)
|
|
||||||
overlayItem.setMarker(newMarker)
|
overlayItem.setMarker(newMarker)
|
||||||
overlayItems.add(overlayItem)
|
overlayItems.add(overlayItem)
|
||||||
|
|
||||||
|
@ -111,11 +86,7 @@ class MapOverlay(private var markerListener: MarkerListener) {
|
||||||
|
|
||||||
|
|
||||||
/* Creates icon overlay for track */
|
/* Creates icon overlay for track */
|
||||||
fun createTrackOverlay(
|
fun createTrackOverlay(context: Context, track: Track, trackingState: Int): ItemizedIconOverlay<OverlayItem> {
|
||||||
context: Context,
|
|
||||||
track: Track,
|
|
||||||
trackingState: Int
|
|
||||||
): ItemizedIconOverlay<OverlayItem> {
|
|
||||||
|
|
||||||
val overlayItems = ArrayList<OverlayItem>()
|
val overlayItems = ArrayList<OverlayItem>()
|
||||||
val wayPoints = track.wayPoints
|
val wayPoints = track.wayPoints
|
||||||
|
@ -128,55 +99,28 @@ class MapOverlay(private var markerListener: MarkerListener) {
|
||||||
when (trackingState) {
|
when (trackingState) {
|
||||||
// CASE: Recording is active
|
// CASE: Recording is active
|
||||||
Keys.STATE_TRACKING_ACTIVE -> {
|
Keys.STATE_TRACKING_ACTIVE -> {
|
||||||
newMarker = when {
|
if (wayPoint.starred) {
|
||||||
wayPoint.starred -> {
|
newMarker = ContextCompat.getDrawable(context, R.drawable.ic_star_red_24dp)!!
|
||||||
ContextCompat.getDrawable(context, R.drawable.ic_star_red_24dp)!!
|
} else if (wayPoint.isStopOver) {
|
||||||
}
|
newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_track_location_grey_24dp)!!
|
||||||
wayPoint.isStopOver -> {
|
} else {
|
||||||
ContextCompat.getDrawable(
|
newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_track_location_red_24dp)!!
|
||||||
context,
|
|
||||||
R.drawable.ic_marker_track_location_grey_24dp
|
|
||||||
)!!
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
ContextCompat.getDrawable(
|
|
||||||
context,
|
|
||||||
R.drawable.ic_marker_track_location_red_24dp
|
|
||||||
)!!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CASE: Recording is paused/stopped
|
// CASE: Recording is paused/stopped
|
||||||
else -> {
|
else -> {
|
||||||
newMarker = when {
|
if (wayPoint.starred) {
|
||||||
wayPoint.starred -> {
|
newMarker = ContextCompat.getDrawable(context, R.drawable.ic_star_blue_24dp)!!
|
||||||
ContextCompat.getDrawable(context, R.drawable.ic_star_blue_24dp)!!
|
} else if (wayPoint.isStopOver) {
|
||||||
}
|
newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_track_location_grey_24dp)!!
|
||||||
wayPoint.isStopOver -> {
|
} else {
|
||||||
ContextCompat.getDrawable(
|
newMarker = ContextCompat.getDrawable(context, R.drawable.ic_marker_track_location_blue_24dp)!!
|
||||||
context,
|
|
||||||
R.drawable.ic_marker_track_location_grey_24dp
|
|
||||||
)!!
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
ContextCompat.getDrawable(
|
|
||||||
context,
|
|
||||||
R.drawable.ic_marker_track_location_blue_24dp
|
|
||||||
)!!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create overlay item and add to list of overlay items
|
// create overlay item and add to list of overlay items
|
||||||
val overlayItem = createOverlayItem(
|
val overlayItem = createOverlayItem(context, wayPoint.latitude, wayPoint.longitude, wayPoint.accuracy, wayPoint.provider, wayPoint.time)
|
||||||
context,
|
|
||||||
wayPoint.latitude,
|
|
||||||
wayPoint.longitude,
|
|
||||||
wayPoint.accuracy,
|
|
||||||
wayPoint.provider,
|
|
||||||
wayPoint.time
|
|
||||||
)
|
|
||||||
overlayItem.setMarker(newMarker)
|
overlayItem.setMarker(newMarker)
|
||||||
overlayItems.add(overlayItem)
|
overlayItems.add(overlayItem)
|
||||||
}
|
}
|
||||||
|
@ -187,56 +131,26 @@ class MapOverlay(private var markerListener: MarkerListener) {
|
||||||
|
|
||||||
|
|
||||||
/* Creates a marker overlay item */
|
/* Creates a marker overlay item */
|
||||||
private fun createOverlayItem(
|
private fun createOverlayItem(context: Context, latitude: Double, longitude: Double, accuracy: Float, provider: String, time: Long): OverlayItem {
|
||||||
context: Context,
|
val title: String = "${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault()).format(time)}"
|
||||||
latitude: Double,
|
|
||||||
longitude: Double,
|
|
||||||
accuracy: Float,
|
|
||||||
provider: String,
|
|
||||||
time: Long
|
|
||||||
): OverlayItem {
|
|
||||||
val title =
|
|
||||||
"${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(
|
|
||||||
SimpleDateFormat.MEDIUM,
|
|
||||||
Locale.getDefault()
|
|
||||||
).format(time)}"
|
|
||||||
//val description: String = "${context.getString(R.string.marker_description_accuracy)}: ${DecimalFormat("#0.00").format(accuracy)} (${provider})"
|
//val description: String = "${context.getString(R.string.marker_description_accuracy)}: ${DecimalFormat("#0.00").format(accuracy)} (${provider})"
|
||||||
val description =
|
val description: String = "${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(SimpleDateFormat.MEDIUM, Locale.getDefault()).format(time)} | ${context.getString(R.string.marker_description_accuracy)}: ${DecimalFormat("#0.00").format(accuracy)} (${provider})"
|
||||||
"${context.getString(R.string.marker_description_time)}: ${SimpleDateFormat.getTimeInstance(
|
val position: GeoPoint = GeoPoint(latitude, longitude)
|
||||||
SimpleDateFormat.MEDIUM,
|
|
||||||
Locale.getDefault()
|
|
||||||
)
|
|
||||||
.format(time)} | ${context.getString(R.string.marker_description_accuracy)}: ${DecimalFormat(
|
|
||||||
"#0.00"
|
|
||||||
).format(accuracy)} (${provider})"
|
|
||||||
val position = GeoPoint(latitude, longitude)
|
|
||||||
return OverlayItem(title, description, position)
|
return OverlayItem(title, description, position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Creates an overlay */
|
/* Creates an overlay */
|
||||||
private fun createOverlay(
|
private fun createOverlay(context: Context, overlayItems: ArrayList<OverlayItem>): ItemizedIconOverlay<OverlayItem> {
|
||||||
context: Context,
|
|
||||||
overlayItems: ArrayList<OverlayItem>
|
|
||||||
): ItemizedIconOverlay<OverlayItem> {
|
|
||||||
return ItemizedIconOverlay<OverlayItem>(context, overlayItems,
|
return ItemizedIconOverlay<OverlayItem>(context, overlayItems,
|
||||||
object : ItemizedIconOverlay.OnItemGestureListener<OverlayItem> {
|
object : ItemizedIconOverlay.OnItemGestureListener<OverlayItem> {
|
||||||
override fun onItemSingleTapUp(index: Int, item: OverlayItem): Boolean {
|
override fun onItemSingleTapUp(index: Int, item: OverlayItem): Boolean {
|
||||||
markerListener.onMarkerTapped(item.point.latitude, item.point.longitude)
|
markerListener.onMarkerTapped(item.point.latitude, item.point.longitude)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemLongPress(index: Int, item: OverlayItem): Boolean {
|
override fun onItemLongPress(index: Int, item: OverlayItem): Boolean {
|
||||||
val v = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
val v = 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)
|
||||||
}
|
|
||||||
Toast.makeText(context, item.snippet, Toast.LENGTH_LONG).show()
|
Toast.makeText(context, item.snippet, Toast.LENGTH_LONG).show()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_white"
|
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"
|
||||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z" />
|
android:fillColor="@color/trackbook_white" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#DC2B00"
|
android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"
|
||||||
android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" />
|
android:fillColor="#DC2B00"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -4,6 +4,6 @@
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:viewportHeight="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_white"
|
android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"
|
||||||
android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0" />
|
android:fillColor="@color/trackbook_white" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillAlpha="0.33"
|
android:fillAlpha="0.33"
|
||||||
android:fillColor="@color/trackbook_blue"
|
android:fillColor="@color/trackbook_blue"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillAlpha="0.33"
|
android:fillAlpha="0.33"
|
||||||
android:fillColor="@color/trackbook_red"
|
android:fillColor="@color/trackbook_red"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillAlpha="0.33"
|
android:fillAlpha="0.33"
|
||||||
android:fillColor="@color/trackbook_red"
|
android:fillColor="@color/trackbook_red"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:width="24dp">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_blue"
|
android:fillColor="@color/trackbook_blue"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:viewportHeight="96.0"
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:width="24dp">
|
||||||
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_grey_light"
|
android:fillColor="@color/trackbook_grey_light"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:viewportHeight="96.0"
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:height="24dp"
|
||||||
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_black"
|
android:fillColor="@color/trackbook_black"
|
||||||
android:pathData="M44,12.99L20.69,8.74L5.12,5.89C2.29,5.38 0,7.44 0,10.49v67.38c0,3.06 2.29,5.96 5.12,6.47l15.57,2.85l22.19,4.05L44,91.46V12.99z"/>
|
android:pathData="M44,12.99L20.69,8.74L5.12,5.89C2.29,5.38 0,7.44 0,10.49v67.38c0,3.06 2.29,5.96 5.12,6.47l15.57,2.85l22.19,4.05L44,91.46V12.99z"/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="36dp"
|
|
||||||
android:height="36dp"
|
android:height="36dp"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:width="36dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_black"
|
android:fillColor="@color/trackbook_black"
|
||||||
android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
|
android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="36dp"
|
|
||||||
android:height="36dp"
|
android:height="36dp"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:width="36dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_black"
|
android:fillColor="@color/trackbook_black"
|
||||||
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"/>
|
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="36dp"
|
|
||||||
android:height="36dp"
|
android:height="36dp"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0"
|
android:viewportWidth="24.0"
|
||||||
android:viewportHeight="24.0">
|
android:width="36dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_black"
|
android:fillColor="@color/trackbook_black"
|
||||||
android:pathData="M6,6h12v12H6z"/>
|
android:pathData="M6,6h12v12H6z"/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="48dp"
|
|
||||||
android:height="48dp"
|
android:height="48dp"
|
||||||
|
android:viewportHeight="192.0"
|
||||||
android:viewportWidth="192.0"
|
android:viewportWidth="192.0"
|
||||||
android:viewportHeight="192.0">
|
android:width="48dp" >
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_blue"
|
android:fillColor="@color/trackbook_blue"
|
||||||
android:pathData="M96,96m-96,0a96,96 0,1 1,192 0a96,96 0,1 1,-192 0"/>
|
android:pathData="M96,96m-96,0a96,96 0,1 1,192 0a96,96 0,1 1,-192 0"/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="48dp"
|
|
||||||
android:height="48dp"
|
android:height="48dp"
|
||||||
|
android:viewportHeight="192.0"
|
||||||
android:viewportWidth="192.0"
|
android:viewportWidth="192.0"
|
||||||
android:viewportHeight="192.0">
|
android:width="48dp" >
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_blue"
|
android:fillColor="@color/trackbook_blue"
|
||||||
android:pathData="M96,96m-96,0a96,96 0,1 1,192 0a96,96 0,1 1,-192 0"/>
|
android:pathData="M96,96m-96,0a96,96 0,1 1,192 0a96,96 0,1 1,-192 0"/>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:viewportHeight="96.0"
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="96.0"
|
android:viewportWidth="96.0"
|
||||||
android:viewportHeight="96.0">
|
android:height="24dp"
|
||||||
|
android:width="24dp">
|
||||||
<path
|
<path
|
||||||
android:fillColor="@color/trackbook_white"
|
android:fillColor="@color/trackbook_white"
|
||||||
android:pathData="M44,12.99L20.69,8.74L5.12,5.89C2.29,5.38 0,7.44 0,10.49v67.38c0,3.06 2.29,5.96 5.12,6.47l15.57,2.85l22.19,4.05L44,91.46V12.99z"/>
|
android:pathData="M44,12.99L20.69,8.74L5.12,5.89C2.29,5.38 0,7.44 0,10.49v67.38c0,3.06 2.29,5.96 5.12,6.47l15.57,2.85l22.19,4.05L44,91.46V12.99z"/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:color="@color/bottom_navigation_element" android:state_checked="false" />
|
<item android:state_checked="false" android:color="@color/bottom_navigation_element" />
|
||||||
<item android:color="@color/bottom_navigation_element_selected" android:state_checked="true" />
|
<item android:state_checked="true" android:color="@color/bottom_navigation_element_selected" />
|
||||||
</selector>
|
</selector>
|
||||||
|
|
|
@ -2,20 +2,17 @@
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:bottom="-2dp"
|
android:top="0dp"
|
||||||
android:left="-2dp"
|
android:left="-2dp"
|
||||||
android:right="-2dp"
|
android:right="-2dp"
|
||||||
android:top="0dp">
|
android:bottom="-2dp">
|
||||||
|
|
||||||
<shape android:shape="rectangle">
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
<solid android:color="@color/statistic_sheet_background_collapsed" />
|
<solid android:color="@color/statistic_sheet_background_collapsed" />
|
||||||
<corners
|
<corners android:topLeftRadius="20dp" android:topRightRadius="20dp" />
|
||||||
android:topLeftRadius="20dp"
|
<stroke android:width="1dp" android:color="@color/statistic_sheet_background_border"/>
|
||||||
android:topRightRadius="20dp" />
|
|
||||||
<stroke
|
|
||||||
android:width="1dp"
|
|
||||||
android:color="@color/statistic_sheet_background_border" />
|
|
||||||
|
|
||||||
</shape>
|
</shape>
|
||||||
|
|
||||||
|
|
|
@ -2,20 +2,17 @@
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:bottom="-2dp"
|
android:top="0dp"
|
||||||
android:left="-2dp"
|
android:left="-2dp"
|
||||||
android:right="-2dp"
|
android:right="-2dp"
|
||||||
android:top="0dp">
|
android:bottom="-2dp">
|
||||||
|
|
||||||
<shape android:shape="rectangle">
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
|
||||||
<solid android:color="@color/statistic_sheet_background_expanded" />
|
<solid android:color="@color/statistic_sheet_background_expanded" />
|
||||||
<corners
|
<corners android:topLeftRadius="20dp" android:topRightRadius="20dp" />
|
||||||
android:topLeftRadius="20dp"
|
<stroke android:width="1dp" android:color="@color/statistic_sheet_background_border"/>
|
||||||
android:topRightRadius="20dp" />
|
|
||||||
<stroke
|
|
||||||
android:width="1dp"
|
|
||||||
android:color="@color/statistic_sheet_background_border" />
|
|
||||||
|
|
||||||
</shape>
|
</shape>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/track_list_onboarding"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:id="@+id/track_list_onboarding">
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -49,8 +49,8 @@
|
||||||
tools:layout="@layout/fragment_track" >
|
tools:layout="@layout/fragment_track" >
|
||||||
<argument
|
<argument
|
||||||
android:name="delete_track_id"
|
android:name="delete_track_id"
|
||||||
android:defaultValue="-1L"
|
app:argType="long"
|
||||||
app:argType="long" />
|
android:defaultValue="-1L" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
</navigation>
|
</navigation>
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||||
|
<item name="custom_match_parent" type="dimen">-1</item> <!-- CUSTOM MATCH_PARENT - see https://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#MATCH_PARENT -->
|
||||||
<!-- CUSTOM MATCH_PARENT - see https://developer.android.com/reference/android/view/ViewGroup.LayoutParams.html#MATCH_PARENT -->
|
|
||||||
<item name="custom_match_parent" type="dimen">-1</item>
|
|
||||||
|
|
||||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||||
<dimen name="bottom_sheet_width">@dimen/custom_match_parent</dimen>
|
<dimen name="bottom_sheet_width">@dimen/custom_match_parent</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -20,11 +20,9 @@
|
||||||
<item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
|
<item name="buttonBarNegativeButtonStyle">@style/NegativeButtonStyle</item>
|
||||||
<item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
|
<item name="buttonBarPositiveButtonStyle">@style/PositiveButtonStyle</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="NegativeButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
|
<style name="NegativeButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
|
||||||
<item name="android:textColor">@color/text_default</item>
|
<item name="android:textColor">@color/text_default</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="PositiveButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
|
<style name="PositiveButtonStyle" parent="Widget.MaterialComponents.Button.TextButton.Dialog">
|
||||||
<item name="android:textColor">@color/text_default</item>
|
<item name="android:textColor">@color/text_default</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<paths>
|
<paths>
|
||||||
<external-path
|
<external-path name="external_files" path="."/>
|
||||||
name="external_files"
|
|
||||||
path="." />
|
|
||||||
</paths>
|
</paths>
|
Loading…
Reference in a new issue