diff --git a/app/src/main/java/com/indieweb/indigenous/post/TripActivity.java b/app/src/main/java/com/indieweb/indigenous/post/TripActivity.java index b73f2e46..b0a68009 100644 --- a/app/src/main/java/com/indieweb/indigenous/post/TripActivity.java +++ b/app/src/main/java/com/indieweb/indigenous/post/TripActivity.java @@ -1,7 +1,9 @@ package com.indieweb.indigenous.post; import android.content.Intent; +import android.database.Cursor; import android.net.Uri; +import android.provider.OpenableColumns; import android.os.Bundle; import android.text.TextUtils; import android.view.Menu; @@ -92,13 +94,23 @@ public boolean onCreateOptionsMenu(Menu menu) { public boolean onOptionsItemSelected(@NonNull MenuItem item) { if (item.getItemId() == R.id.loadGpx) { - Intent ii = new Intent(); - ii.setType("application/gpx+xml"); - ii.setAction(Intent.ACTION_OPEN_DOCUMENT); + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + + // Allow all file types - GPX files may have various MIME types + // (application/gpx+xml, application/octet-stream, text/xml, etc.) + // The app will validate the file content when parsing + intent.setType("*/*"); + + // Grant read permission + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + if (!isMediaRequest) { - ii.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); } - startActivityForResult(Intent.createChooser(ii, getString(R.string.trip_load_gpx)), PICK_GPX_REQUEST); + + startActivityForResult(intent, PICK_GPX_REQUEST); return true; } @@ -110,13 +122,38 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICK_GPX_REQUEST && resultCode == RESULT_OK) { if (data.getData() != null) { - parseGPXfile(data.getData(), data, true); + Uri uri = data.getData(); + if (isGpxFile(uri)) { + parseGPXfile(uri, data, true); + } else { + Snackbar.make(layout, getString(R.string.trip_invalid_file_type), Snackbar.LENGTH_LONG).show(); + } } } super.onActivityResult(requestCode, resultCode, data); } + /** + * Check if the selected file is a GPX file by extension. + * + * @param uri The file uri. + * @return true if the file has a .gpx extension. + */ + private boolean isGpxFile(Uri uri) { + String fileName = null; + try (Cursor cursor = getContentResolver().query(uri, null, null, null, null)) { + if (cursor != null && cursor.moveToFirst()) { + int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + if (nameIndex >= 0) { + fileName = cursor.getString(nameIndex); + } + } + } catch (Exception ignored) { + } + return fileName != null && fileName.toLowerCase().endsWith(".gpx"); + } + /** * Parse a GPX file. * @@ -218,7 +255,7 @@ public void onPostButtonClick(MenuItem item) { } if (transport.getSelectedItemPosition() != 0) { - String t = getResources().getStringArray(R.array.transport_array_values)[read.getSelectedItemPosition()]; + String t = getResources().getStringArray(R.array.transport_array_values)[transport.getSelectedItemPosition()]; bodyParams.put("transport", t); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1c98c5bc..9514225b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -318,6 +318,7 @@ Load GPX file Error reading GPX file: %s No points found in GPX file. + Please select a GPX file (.gpx) Start location End location Transport