diff --git a/app/build.gradle b/app/build.gradle
index d9e0633..9bc36ac 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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"
}
diff --git a/app/src/main/java/org/y20k/trackbook/Keys.kt b/app/src/main/java/org/y20k/trackbook/Keys.kt
index dc971dc..277f191 100644
--- a/app/src/main/java/org/y20k/trackbook/Keys.kt
+++ b/app/src/main/java/org/y20k/trackbook/Keys.kt
@@ -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"
-
}
diff --git a/app/src/main/java/org/y20k/trackbook/TrackFragment.kt b/app/src/main/java/org/y20k/trackbook/TrackFragment.kt
index 706fbe1..b124ed7 100644
--- a/app/src/main/java/org/y20k/trackbook/TrackFragment.kt
+++ b/app/src/main/java/org/y20k/trackbook/TrackFragment.kt
@@ -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
diff --git a/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt b/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt
index 4c52350..fa3f544 100644
--- a/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt
+++ b/app/src/main/java/org/y20k/trackbook/TracklistFragment.kt
@@ -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
+ }
}
}
diff --git a/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt b/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt
index 049e317..39e832a 100644
--- a/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt
+++ b/app/src/main/java/org/y20k/trackbook/helpers/FileHelper.kt
@@ -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))
}
}
diff --git a/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt b/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt
index c171a3a..d73f911 100644
--- a/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt
+++ b/app/src/main/java/org/y20k/trackbook/ui/TrackFragmentLayoutHolder.kt
@@ -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)
diff --git a/app/src/main/res/drawable/ic_delete_24dp.xml b/app/src/main/res/drawable/ic_delete_24dp.xml
old mode 100755
new mode 100644
index 651f304..8698fa6
--- a/app/src/main/res/drawable/ic_delete_24dp.xml
+++ b/app/src/main/res/drawable/ic_delete_24dp.xml
@@ -1,9 +1,9 @@
-
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
diff --git a/app/src/main/res/drawable/ic_edit_24dp.xml b/app/src/main/res/drawable/ic_edit_24dp.xml
index 1a9a294..6c65efa 100644
--- a/app/src/main/res/drawable/ic_edit_24dp.xml
+++ b/app/src/main/res/drawable/ic_edit_24dp.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24.0">
+ 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"/>
diff --git a/app/src/main/res/drawable/ic_save_24dp.xml b/app/src/main/res/drawable/ic_save_24dp.xml
new file mode 100644
index 0000000..14e3ad6
--- /dev/null
+++ b/app/src/main/res/drawable/ic_save_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_share_24dp.xml b/app/src/main/res/drawable/ic_share_24dp.xml
deleted file mode 100755
index 24bf669..0000000
--- a/app/src/main/res/drawable/ic_share_24dp.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_speed_24px.xml b/app/src/main/res/drawable/ic_speed_24px.xml
deleted file mode 100644
index 0eb105b..0000000
--- a/app/src/main/res/drawable/ic_speed_24px.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/layout/fragment_tracklist.xml b/app/src/main/res/layout/fragment_tracklist.xml
index 4b8fea5..cc535b7 100644
--- a/app/src/main/res/layout/fragment_tracklist.xml
+++ b/app/src/main/res/layout/fragment_tracklist.xml
@@ -23,12 +23,11 @@
-
diff --git a/app/src/main/res/layout/track_statistics.xml b/app/src/main/res/layout/track_statistics.xml
index 118a42e..a86f81d 100755
--- a/app/src/main/res/layout/track_statistics.xml
+++ b/app/src/main/res/layout/track_statistics.xml
@@ -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" />
+ app:srcCompat="@drawable/ic_save_24dp" />
Ryd knap
Fortsæt knap
Slet tur knap
- Del eksport som GPX knap
+ Del eksport som GPX knap
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 229f740..92ecba2 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -55,5 +55,5 @@
Zurücksetzen-Knopf
Fortsetzen-Knopf
Schaltfläche „Aufzeichnung löschen”
- Share-Taste, die den Export als GPX anbietet
+ Share-Taste, die den Export als GPX anbietet
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 938c895..31f7963 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -55,7 +55,7 @@
Bouton « Sauvegarder »
Affichage du parcours actuel
Affichage du dernier parcours
- Bouton « Partager au format GPX »
+ Bouton « Partager au format GPX »
Itinéraires
Paramètres
Permission manquante. Le suivi ne fonctionnera pas.
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 3413d27..ad6b56a 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -55,7 +55,7 @@
Pulsante Cancella
Pulsante Riprendi
Pulsante Elimina traccia
- Pulsante Condividi che permette di esportare come GPX
+ Pulsante Condividi che permette di esportare come GPX
Tracce
Impostazioni
Permesso alla posizione non concesso. Trackbook non funzionerà.
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 340ffd1..f41c2d8 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -55,5 +55,5 @@
クリアボタン
再開ボタン
トレース削除ボタン
- GPX としてエクスポートする共有ボタン
+ GPX としてエクスポートする共有ボタン
\ No newline at end of file
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index 59b9986..7572ae5 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -55,7 +55,7 @@
Tøm-knapp
Fortsett-knapp
Sporslettingsknapp
- Delingsknapp som muliggjør eksport som GPX
+ Delingsknapp som muliggjør eksport som GPX
Spor
Innstillinger
Plasseringstilgang ikke innvilget. Trackbook vil ikke fungere.
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 1777ed4..b89899d 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -55,7 +55,7 @@
Wissen-knop
Voortzetten-knop
Track verwijderknop
- Deelknop met ondersteuning voor het exporteren naar GPX
+ Deelknop met ondersteuning voor het exporteren naar GPX
Routes
Instellingen
Locatiemachtiging niet verleend. Trackbook zal niet werken.
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index d89b48e..09dd8ca 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -87,7 +87,7 @@
加星按钮
删除记录按钮
记录编辑按钮
- 以GPX文件分享按钮
+ 以GPX文件分享按钮
23.0 km • 5 时 23 分 42 秒
1969年7月20日
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 853a101..70a4c07 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -39,6 +39,7 @@
Hint: The accuracy of elevation data depends on your device. The uphill and downhill elevation of the whole route is measured.
Please install a file manager or a GPX track viewer first.
+ Saving recording as GPX.
Time
Accuracy
@@ -64,7 +65,7 @@
Your recorded tracks
… will show up here.
- Discard location fixes with an accuracy larger than
+ Discard location fixes with an accuracy larger than:
Accuracy Threshold
Advanced
General
@@ -97,7 +98,7 @@
Stop Recording
Track delete button
Track edit button
- Share as GPX button
+ Save as GPX button
23.0 km • 5 hrs 23 min 42 sec
July 20, 1969