gpx export now uses file picker (instead of share sheet)

master
y20k 2020-02-13 17:12:34 +01:00
parent 063d84e39f
commit beb0d2f236
No known key found for this signature in database
GPG Key ID: 824D4259F41FAFF6
22 changed files with 117 additions and 89 deletions

View File

@ -11,7 +11,7 @@ android {
applicationId 'org.y20k.trackbook'
minSdkVersion 25
targetSdkVersion 27
versionCode 27
versionCode 37
versionName '2.0.0'
resConfigs "en", "da", "de", "fr", "id", "it", "ja", "nb-rNO", "nl", "sv", "zh-rCN"
}

View File

@ -32,12 +32,6 @@ object Keys {
const val CURRENT_TRACK_FORMAT_VERSION: Int = 4
const val CURRENT_TRACKLIST_FORMAT_VERSION: Int = 0
// other values
const val MAXIMUM_TRACK_FILES: Int = 25
const val FIFTY_METER_RADIUS: Int = 50
const val UNIT_METRIC: Int = 1
const val UNIT_IMPERIAL: Int = -1
// intent actions
const val ACTION_START: String = "org.y20k.trackbooks.action.START"
const val ACTION_STOP: String = "org.y20k.trackbooks.action.STOP"
@ -78,14 +72,8 @@ object Keys {
const val DIALOG_REMOVE_TRACK: Int = 1
// dialog results
const val DIALOG_RESULT_DEFAULT: Int = -1
const val DIALOG_EMPTY_PAYLOAD_STRING: String = ""
const val DIALOG_EMPTY_PAYLOAD_INT: Int = -1
const val DIALOG_RESULT_SAVE_DIALOG: Int = 1
const val DIALOG_RESULT_CLEAR_DIALOG: Int = 2
const val DIALOG_RESULT_DELETE_DIALOG: Int = 3
const val DIALOG_RESULT_EXPORT_DIALOG: Int = 4
const val DIALOG_RESULT_EMPTY_RECORDING_DIALOG: Int = 5
// folder names
const val FOLDER_TEMP: String = "temp"
@ -93,16 +81,12 @@ object Keys {
const val FOLDER_GPX: String = "gpx"
// file names and extensions
const val MIME_TYPE_GPX: String = "application/gpx+xml"
const val GPX_FILE_EXTENSION: String = ".gpx"
const val TRACKBOOK_LEGACY_FILE_EXTENSION: String = ".trackbook"
const val TRACKBOOK_FILE_EXTENSION: String = ".json"
const val TEMP_FILE: String = "temp.json"
const val TRACKLIST_FILE: String = "tracklist.json"
const val PODCAST_COVER_FILE: String = "cover.jpg"
const val PODCAST_SMALL_COVER_FILE: String = "cover-small.jpg"
const val DEBUG_LOG_FILE: String = "log-can-be-deleted.txt"
const val FILE_TYPE_TEMP: Int = 0
const val FILE_TYPE_TRACK: Int = 1
// default values
@ -127,11 +111,9 @@ object Keys {
const val REQUEST_CODE_FOREGROUND = 42
// requests
// results
const val REQUEST_SAVE_GPX: Int = 23
// notification
const val TRACKER_SERVICE_NOTIFICATION_ID: Int = 1
const val NOTIFICATION_CHANNEL_RECORDING: String = "notificationChannelIdRecordingChannel"
}

View File

@ -19,11 +19,13 @@ package org.y20k.trackbook
import YesNoDialog
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Vibrator
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -36,6 +38,7 @@ import androidx.navigation.fragment.findNavController
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.y20k.trackbook.Keys.ARG_TRACK_ID
import org.y20k.trackbook.core.Track
import org.y20k.trackbook.dialogs.RenameTrackDialog
import org.y20k.trackbook.helpers.FileHelper
import org.y20k.trackbook.helpers.LogHelper
@ -48,17 +51,37 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi
/* Main class variables */
private lateinit var layout:TrackFragmentLayoutHolder
private lateinit var layout: TrackFragmentLayoutHolder
private lateinit var track: Track
/* Overrides onCreate from Fragment */
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// get track
val fileUriString: String = arguments?.getString(Keys.ARG_TRACK_FILE_URI, String()) ?: String()
if (fileUriString.isNotBlank()) {
track = FileHelper.readTrack(activity as Context, Uri.parse(fileUriString))
} else {
track = Track()
}
}
/* Overrides onCreateView from Fragment */
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
// initialize layout
layout = TrackFragmentLayoutHolder(activity as Context, inflater, container, arguments)
layout = TrackFragmentLayoutHolder(activity as Context, inflater, container, track)
// set up share button
layout.shareButton.setOnClickListener {
shareGpXTrack()
openSaveGpxDialog()
}
layout.shareButton.setOnLongClickListener {
val v = (activity as Context).getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
v.vibrate(50)
shareGpxTrack()
return@setOnLongClickListener true
}
// set up delete button
layout.deleteButton.setOnClickListener {
@ -90,6 +113,27 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi
}
/* Overrides onActivityResult from Fragment */
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
when (requestCode) {
// save GPX file to result file location
Keys.REQUEST_SAVE_GPX -> {
if (resultCode == Activity.RESULT_OK && data != null) {
val sourceUri: Uri = Uri.parse(track.gpxUriString)
val targetUri: Uri? = data.data
if (targetUri != null) {
// copy file async (= fire & forget - no return value needed)
GlobalScope.launch { FileHelper.saveCopyOfFileSuspended( activity as Context, originalFileUri = sourceUri, targetFileUri = targetUri) }
Toast.makeText(activity as Context, R.string.toast_message_save_gpx, Toast.LENGTH_LONG).show()
}
}
}
// let activity handle result
else -> super.onActivityResult(requestCode, resultCode, data)
}
}
/* Overrides onRenameTrackDialog from RenameTrackDialog */
override fun onRenameTrackDialog(textInput: String) {
// rename track async (= fire & forget - no return value needed)
@ -118,17 +162,28 @@ class TrackFragment : Fragment(), RenameTrackDialog.RenameTrackListener, YesNoDi
}
/* Opens up a file picker to select the save location */
private fun openSaveGpxDialog() {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = Keys.MIME_TYPE_GPX
putExtra(Intent.EXTRA_TITLE, FileHelper.getGpxFileName(track))
}
// file gets saved in onActivityResult
startActivityForResult(intent, Keys.REQUEST_SAVE_GPX)
}
/* Share track as GPX via share sheet */
private fun shareGpXTrack() {
private fun shareGpxTrack() {
val gpxFile = Uri.parse(layout.track.gpxUriString).toFile()
val gpxShareUri = FileProvider.getUriForFile(this.activity as Context, "${activity!!.applicationContext.packageName}.provider", gpxFile)
val shareIntent: Intent = Intent.createChooser(Intent().apply {
action = Intent.ACTION_SEND
data = gpxShareUri
type = "application/gpx+xml"
type = Keys.MIME_TYPE_GPX
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
putExtra(Intent.EXTRA_STREAM, gpxShareUri)
putExtra(Intent.EXTRA_TITLE, getString(R.string.dialog_share_gpx))
}, null)
// show share sheet - if file helper is available

View File

@ -125,8 +125,16 @@ class TracklistFragment : Fragment(), TracklistAdapter.TracklistAdapterListener,
// toggle onboarding layout
private fun toggleOnboardingLayout(trackCount: Int) {
when (trackCount == 0) {
true -> tracklistOnboarding.visibility = View.VISIBLE // show onboarding layout
false -> tracklistOnboarding.visibility = View.GONE // hide onboarding layout
true -> {
// show onboarding layout
tracklistOnboarding.visibility = View.VISIBLE
trackElementList.visibility = View.GONE
}
false -> {
// hide onboarding layout
tracklistOnboarding.visibility = View.GONE
trackElementList.visibility = View.VISIBLE
}
}
}

View File

@ -154,10 +154,11 @@ object FileHelper {
/* Creates Uri for Gpx file of a track */
fun getGpxFileUri(context: Context, track: Track): Uri {
val fileName: String = DateTimeHelper.convertToSortableDateString(track.recordingStart) + Keys.GPX_FILE_EXTENSION
return File(context.getExternalFilesDir(Keys.FOLDER_GPX), fileName).toUri()
}
fun getGpxFileUri(context: Context, track: Track): Uri = File(context.getExternalFilesDir(Keys.FOLDER_GPX), getGpxFileName(track)).toUri()
/* Creates file name for Gpx file of a track */
fun getGpxFileName(track: Track): String = DateTimeHelper.convertToSortableDateString(track.recordingStart) + Keys.GPX_FILE_EXTENSION
/* Creates Uri for json track file */
@ -232,9 +233,9 @@ object FileHelper {
/* Suspend function: Wrapper for copyFile */
suspend fun saveCopyOfFileSuspended(context: Context, originalFileUri: Uri, targetFileUri: Uri) {
suspend fun saveCopyOfFileSuspended(context: Context, originalFileUri: Uri, targetFileUri: Uri, deleteOriginal: Boolean = false) {
return suspendCoroutine { cont ->
cont.resume(copyFile(context, originalFileUri, targetFileUri, deleteOriginal = true))
cont.resume(copyFile(context, originalFileUri, targetFileUri, deleteOriginal))
}
}

View File

@ -19,8 +19,6 @@ package org.y20k.trackbook.ui
import android.app.Activity
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -52,7 +50,7 @@ import kotlin.math.roundToInt
/*
* TrackFragmentLayoutHolder class
*/
data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutInflater, var container: ViewGroup?, var arguments: Bundle?) {
data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutInflater, var container: ViewGroup?, var track: Track) {
/* Define log tag */
private val TAG: String = LogHelper.makeLogTag(TrackFragmentLayoutHolder::class.java)
@ -60,7 +58,6 @@ data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutI
/* Main class variables */
val rootView: View
val track: Track
val shareButton: ImageButton
val deleteButton: ImageButton
val editButton: ImageButton
@ -92,7 +89,7 @@ data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutI
// find views
rootView = inflater.inflate(R.layout.fragment_track, container, false)
mapView = rootView.findViewById(R.id.map)
shareButton = rootView.findViewById(R.id.share_button)
shareButton = rootView.findViewById(R.id.save_button)
deleteButton = rootView.findViewById(R.id.delete_button)
editButton = rootView.findViewById(R.id.edit_button)
trackNameView = rootView.findViewById(R.id.statistics_track_name_headline)
@ -136,13 +133,7 @@ data class TrackFragmentLayoutHolder(var context: Context, var inflater: LayoutI
compassOverlay.setCompassCenter(36f, 60f)
mapView.overlays.add(compassOverlay)
// get track and create map overlay
val fileUriString: String = arguments?.getString(Keys.ARG_TRACK_FILE_URI, String()) ?: String()
if (fileUriString.isNotBlank()) {
track = FileHelper.readTrack(context, Uri.parse(fileUriString))
} else {
track = Track()
}
// create map overlay
trackOverlay = MapHelper.createTrackOverlay(context, track, Keys.STATE_TRACKING_NOT)
if (track.wayPoints.isNotEmpty()) {
mapView.overlays.add(trackOverlay)

14
app/src/main/res/drawable/ic_delete_24dp.xml Executable file → Normal file
View File

@ -1,9 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2L18,7L6,7v12zM8.46,11.88l1.41,-1.41L12,12.59l2.12,-2.12 1.41,1.41L13.41,14l2.12,2.12 -1.41,1.41L12,15.41l-2.12,2.12 -1.41,-1.41L10.59,14l-2.13,-2.12zM15.5,4l-1,-1h-5l-1,1L5,4v2h14L19,4z"
android:fillColor="@color/icon_default" />
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/icon_default"
android:pathData="M16,9v10H8V9h8m-1.5,-6h-5l-1,1H5v2h14V4h-3.5l-1,-1zM18,7H6v12c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7z"/>
</vector>

View File

@ -5,5 +5,5 @@
android:viewportHeight="24.0">
<path
android:fillColor="@color/icon_default"
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
android:pathData="M14.06,9.02l0.92,0.92L5.92,19L5,19v-0.92l9.06,-9.06M17.66,3c-0.25,0 -0.51,0.1 -0.7,0.29l-1.83,1.83 3.75,3.75 1.83,-1.83c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.2,-0.2 -0.45,-0.29 -0.71,-0.29zM14.06,6.19L3,17.25L3,21h3.75L17.81,9.94l-3.75,-3.75z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/icon_default"
android:pathData="M19,12v7L5,19v-7L3,12v7c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2zM13,12.67l2.59,-2.58L17,11.5l-5,5 -5,-5 1.41,-1.41L11,12.67L11,3h2z"/>
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"
android:fillColor="@color/icon_default" />
</vector>

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@color/icon_default"
android:pathData="M20.38,8.57l-1.23,1.85a8,8 0,0 1,-0.22 7.58L5.07,18A8,8 0,0 1,15.58 6.85l1.85,-1.23A10,10 0,0 0,3.35 19a2,2 0,0 0,1.72 1h13.85a2,2 0,0 0,1.74 -1,10 10,0 0,0 -0.27,-10.44zM10.59,15.41a2,2 0,0 0,2.83 0l5.66,-8.49 -8.49,5.66a2,2 0,0 0,0 2.83z"/>
</vector>

View File

@ -23,12 +23,11 @@
<include
layout="@layout/track_onboarding"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/track_element_list"
tools:visibility="gone" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -46,7 +46,7 @@
android:backgroundTint="@color/trackbook_transparent"
android:contentDescription="@string/descr_statistics_sheet_delete_button"
app:layout_constraintBottom_toBottomOf="@+id/edit_button"
app:layout_constraintEnd_toStartOf="@+id/share_button"
app:layout_constraintEnd_toStartOf="@+id/save_button"
app:layout_constraintTop_toTopOf="@+id/edit_button"
app:srcCompat="@drawable/ic_delete_24dp" />
@ -62,16 +62,16 @@
app:srcCompat="@drawable/ic_edit_24dp" />
<ImageButton
android:id="@+id/share_button"
android:id="@+id/save_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="@color/trackbook_transparent"
android:contentDescription="@string/descr_statistics_sheet_share_button"
android:contentDescription="@string/descr_statistics_sheet_save_button"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="@+id/statistics_track_name_headline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/statistics_track_name_headline"
app:srcCompat="@drawable/ic_share_24dp" />
app:srcCompat="@drawable/ic_save_24dp" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/statistics_p_distance"

View File

@ -54,5 +54,5 @@
<string name="descr_fab_sub_menu_button_clear">Ryd knap</string>
<string name="descr_fab_sub_menu_button_resume">Fortsæt knap</string>
<string name="descr_statistics_sheet_delete_button">Slet tur knap</string>
<string name="descr_statistics_sheet_share_button">Del eksport som GPX knap</string>
<string name="descr_statistics_sheet_save_button">Del eksport som GPX knap</string>
</resources>

View File

@ -55,5 +55,5 @@
<string name="descr_fab_sub_menu_button_clear">Zurücksetzen-Knopf</string>
<string name="descr_fab_sub_menu_button_resume">Fortsetzen-Knopf</string>
<string name="descr_statistics_sheet_delete_button">Schaltfläche „Aufzeichnung löschen”</string>
<string name="descr_statistics_sheet_share_button">Share-Taste, die den Export als GPX anbietet</string>
<string name="descr_statistics_sheet_save_button">Share-Taste, die den Export als GPX anbietet</string>
</resources>

View File

@ -55,7 +55,7 @@
<string name="descr_fab_sub_menu_button_save">Bouton « Sauvegarder »</string>
<string name="descr_map_current_track">Affichage du parcours actuel</string>
<string name="descr_map_last_track">Affichage du dernier parcours</string>
<string name="descr_statistics_sheet_share_button">Bouton « Partager au format GPX »</string>
<string name="descr_statistics_sheet_save_button">Bouton « Partager au format GPX »</string>
<string name="tab_tracks">Itinéraires</string>
<string name="tab_settings">Paramètres</string>
<string name="snackbar_message_location_permission_denied">Permission manquante. Le suivi ne fonctionnera pas.</string>

View File

@ -55,7 +55,7 @@
<string name="descr_fab_sub_menu_button_clear">Pulsante Cancella</string>
<string name="descr_fab_sub_menu_button_resume">Pulsante Riprendi</string>
<string name="descr_statistics_sheet_delete_button">Pulsante Elimina traccia</string>
<string name="descr_statistics_sheet_share_button">Pulsante Condividi che permette di esportare come GPX</string>
<string name="descr_statistics_sheet_save_button">Pulsante Condividi che permette di esportare come GPX</string>
<string name="tab_tracks">Tracce</string>
<string name="tab_settings">Impostazioni</string>
<string name="snackbar_message_location_permission_denied">Permesso alla posizione non concesso. Trackbook non funzionerà.</string>

View File

@ -55,5 +55,5 @@
<string name="descr_fab_sub_menu_button_clear">クリアボタン</string>
<string name="descr_fab_sub_menu_button_resume">再開ボタン</string>
<string name="descr_statistics_sheet_delete_button">トレース削除ボタン</string>
<string name="descr_statistics_sheet_share_button">GPX としてエクスポートする共有ボタン</string>
<string name="descr_statistics_sheet_save_button">GPX としてエクスポートする共有ボタン</string>
</resources>

View File

@ -55,7 +55,7 @@
<string name="descr_fab_sub_menu_button_clear">Tøm-knapp</string>
<string name="descr_fab_sub_menu_button_resume">Fortsett-knapp</string>
<string name="descr_statistics_sheet_delete_button">Sporslettingsknapp</string>
<string name="descr_statistics_sheet_share_button">Delingsknapp som muliggjør eksport som GPX</string>
<string name="descr_statistics_sheet_save_button">Delingsknapp som muliggjør eksport som GPX</string>
<string name="tab_tracks">Spor</string>
<string name="tab_settings">Innstillinger</string>
<string name="snackbar_message_location_permission_denied">Plasseringstilgang ikke innvilget. Trackbook vil ikke fungere.</string>

View File

@ -55,7 +55,7 @@
<string name="descr_fab_sub_menu_button_clear">Wissen-knop</string>
<string name="descr_fab_sub_menu_button_resume">Voortzetten-knop</string>
<string name="descr_statistics_sheet_delete_button">Track verwijderknop</string>
<string name="descr_statistics_sheet_share_button">Deelknop met ondersteuning voor het exporteren naar GPX</string>
<string name="descr_statistics_sheet_save_button">Deelknop met ondersteuning voor het exporteren naar GPX</string>
<string name="tab_tracks">Routes</string>
<string name="tab_settings">Instellingen</string>
<string name="snackbar_message_location_permission_denied">Locatiemachtiging niet verleend. Trackbook zal niet werken.</string>

View File

@ -87,7 +87,7 @@
<string name="descr_mark_starred_button">加星按钮</string>
<string name="descr_statistics_sheet_delete_button">删除记录按钮</string>
<string name="descr_statistics_sheet_edit_button">记录编辑按钮</string>
<string name="descr_statistics_sheet_share_button">以GPX文件分享按钮</string>
<string name="descr_statistics_sheet_save_button">以GPX文件分享按钮</string>
<!-- Sample Text -->
<string name="sample_text_track_data" translatable="false">23.0 km • 5 时 23 分 42 秒</string>
<string name="sample_text_track_name" translatable="false">1969年7月20日</string>

View File

@ -39,6 +39,7 @@
<!-- 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_install_file_helper">Please install a file manager or a GPX track viewer first.</string>
<string name="toast_message_save_gpx">Saving recording as GPX.</string>
<!-- Map Markers -->
<string name="marker_description_time">Time</string>
<string name="marker_description_accuracy">Accuracy</string>
@ -64,7 +65,7 @@
<string name="track_list_onboarding_h1_part_1">Your recorded tracks</string>
<string name="track_list_onboarding_h1_part_2">… will show up here.</string>
<!-- Settings -->
<string name="pref_accuracy_threshold_summary">Discard location fixes with an accuracy larger than</string>
<string name="pref_accuracy_threshold_summary">Discard location fixes with an accuracy larger than:</string>
<string name="pref_accuracy_threshold_title">Accuracy Threshold</string>
<string name="pref_advanced_title">Advanced</string>
<string name="pref_general_title">General</string>
@ -97,7 +98,7 @@
<string name="descr_quick_settings_tile_title_stop">Stop Recording</string>
<string name="descr_statistics_sheet_delete_button">Track delete button</string>
<string name="descr_statistics_sheet_edit_button">Track edit button</string>
<string name="descr_statistics_sheet_share_button">Share as GPX button</string>
<string name="descr_statistics_sheet_save_button">Save as GPX button</string>
<!-- Sample Text -->
<string name="sample_text_track_data" translatable="false">23.0 km • 5 hrs 23 min 42 sec</string>
<string name="sample_text_track_name" translatable="false">July 20, 1969</string>