Save new GPX files from the Receiver and OpenTracks into gpx subdir

This commit is contained in:
Arjan Schrijver
2025-07-26 22:22:00 +02:00
committed by Arjan Schrijver
parent 3840595b35
commit d4e917b5cd
3 changed files with 43 additions and 35 deletions
@@ -17,7 +17,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>. */ along with this program. If not, see <https://www.gnu.org/licenses/>. */
package nodomain.freeyourgadget.gadgetbridge.activities; package nodomain.freeyourgadget.gadgetbridge.activities;
import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.*; import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.INTERNAL_HAS_GPS;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
@@ -42,10 +42,6 @@ import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.appcompat.app.ActionBar;
import androidx.gridlayout.widget.GridLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
@@ -54,8 +50,10 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.gridlayout.widget.GridLayout;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
@@ -70,8 +68,7 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -108,7 +105,8 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
List<String> filesGpxList = new ArrayList<>(); List<String> filesGpxList = new ArrayList<>();
int selectedGpxIndex; int selectedGpxIndex;
String selectedGpxFile; String selectedGpxFile;
File export_path = null; File export_path_root = null; // original gpx file location, could still contain old gpx files
File export_path_gpx = null; // new gpx file location
private ActivitySummariesChartFragment activitySummariesChartFragment; private ActivitySummariesChartFragment activitySummariesChartFragment;
private ActivitySummariesGpsFragment activitySummariesGpsFragment; private ActivitySummariesGpsFragment activitySummariesGpsFragment;
@@ -308,35 +306,31 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
} }
private List<String> get_gpx_file_list() { private List<String> get_gpx_file_list() {
List<String> list = new ArrayList<>(); List<File> files = new ArrayList<>();
FileFilter gpxFileFilter = file -> file.isFile() && file.getPath().toLowerCase().endsWith(".gpx");
if (export_path_root.isDirectory()) {
File[] rootFiles = export_path_root.listFiles(gpxFileFilter);
if (rootFiles != null)
Collections.addAll(files, rootFiles);
}
if (export_path_gpx.isDirectory()) {
File[] gpxFiles = export_path_gpx.listFiles(gpxFileFilter);
if (gpxFiles != null)
Collections.addAll(files, gpxFiles);
}
File[] fileListing = export_path.listFiles(new FileFilter() { files.sort((file1, file2) -> {
@Override long lastModified1 = file1.lastModified();
public boolean accept(File file) { long lastModified2 = file2.lastModified();
return file.getPath().toLowerCase().endsWith(".gpx"); return Long.compare(lastModified2, lastModified1); // Descending order
}
}); });
if (fileListing != null && fileListing.length > 1) { List<String> list = new ArrayList<>();
Arrays.sort(fileListing, new Comparator<File>() {
@Override
public int compare(File fileA, File fileB) {
if (fileA.lastModified() < fileB.lastModified()) {
return 1;
}
if (fileA.lastModified() > fileB.lastModified()) {
return -1;
}
return 0;
}
});
}
list.add(getString(R.string.activity_summary_detail_clear_gpx_track)); list.add(getString(R.string.activity_summary_detail_clear_gpx_track));
for (File file : files) {
for (File file : fileListing) {
list.add(file.getName()); list.add(file.getName());
} }
return list; return list;
} }
@@ -505,7 +499,8 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
} }
private void editGps() { private void editGps() {
export_path = get_path(); export_path_root = get_path();
export_path_gpx = new File(get_path(), "gpx");
filesGpxList = get_gpx_file_list(); filesGpxList = get_gpx_file_list();
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ActivitySummaryDetail.this); MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(ActivitySummaryDetail.this);
@@ -513,7 +508,16 @@ public class ActivitySummaryDetail extends AbstractGBActivity {
ArrayAdapter<String> directory_listing = new ArrayAdapter<>(ActivitySummaryDetail.this, android.R.layout.simple_list_item_1, filesGpxList); ArrayAdapter<String> directory_listing = new ArrayAdapter<>(ActivitySummaryDetail.this, android.R.layout.simple_list_item_1, filesGpxList);
builder.setSingleChoiceItems(directory_listing, 0, (dialog, which) -> { builder.setSingleChoiceItems(directory_listing, 0, (dialog, which) -> {
selectedGpxIndex = which; selectedGpxIndex = which;
selectedGpxFile = export_path + "/" + filesGpxList.get(selectedGpxIndex); String selectedFilename = filesGpxList.get(selectedGpxIndex);
if (new File(export_path_gpx, selectedFilename).isFile()) {
// Note: if selectedFilename exists in both export_path_gpx and export_path_root,
// this code will always choose the one in export_path_gpx. This is acceptable
// because export_path_gpx is where all new files end up, and gpx files tend to
// have a unique name anyway because it usually contains some timestamp.
selectedGpxFile = new File(export_path_gpx, selectedFilename).getPath();
} else {
selectedGpxFile = new File(export_path_root, selectedFilename).getPath();
}
String message = String.format("%s %s?", getString(R.string.set), filesGpxList.get(selectedGpxIndex)); String message = String.format("%s %s?", getString(R.string.set), filesGpxList.get(selectedGpxIndex));
if (selectedGpxIndex == 0) { if (selectedGpxIndex == 0) {
selectedGpxFile = null; selectedGpxFile = null;
@@ -115,7 +115,9 @@ public class GpxReceiverActivity extends AbstractGBActivity {
private File create_file_from_uri(Uri source) { private File create_file_from_uri(Uri source) {
File destination = null; File destination = null;
try { try {
File external = FileUtils.getExternalFilesDir(); File external = new File(FileUtils.getExternalFilesDir(), "gpx");
//noinspection ResultOfMethodCallIgnored
external.mkdirs();
String fileName = get_file_name(source); String fileName = get_file_name(source);
if (fileName != null) { if (fileName != null) {
@@ -176,7 +176,9 @@ public class OpenTracksController extends Activity {
activityTrack.addTrackPoints(activityPoints); activityTrack.addTrackPoints(activityPoints);
try { try {
final File gpxDir = FileUtils.getExternalFilesDir(); final File gpxDir = new File(FileUtils.getExternalFilesDir(), "gpx");
//noinspection ResultOfMethodCallIgnored
gpxDir.mkdirs();
final File gpxFile = new File(gpxDir, gpxName + ".gpx"); final File gpxFile = new File(gpxDir, gpxName + ".gpx");
final GPXExporter gpxExporter = new GPXExporter(); final GPXExporter gpxExporter = new GPXExporter();
gpxExporter.performExport(activityTrack, gpxFile); gpxExporter.performExport(activityTrack, gpxFile);