diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java index a5022ba..bf059fe 100644 --- a/brouter-core/src/main/java/btools/router/RoutingEngine.java +++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java @@ -63,6 +63,7 @@ public class RoutingEngine extends Thread private Object[] extract; private boolean directWeaving = !Boolean.getBoolean( "disableDirectWeaving" ); + private String outfile; public RoutingEngine( String outfileBase, String logfileBase, File segmentDir, List waypoints, RoutingContext rc ) @@ -185,6 +186,7 @@ public class RoutingEngine extends Thread track.writeGpx( filename ); foundTrack = track; alternativeIndex = i; + outfile = filename; } else { @@ -1369,4 +1371,7 @@ public class RoutingEngine extends Thread return terminated; } + public String getOutfile() { + return outfile; + } } diff --git a/brouter-routing-app/src/main/AndroidManifest.xml b/brouter-routing-app/src/main/AndroidManifest.xml index 3c8f22e..17957da 100644 --- a/brouter-routing-app/src/main/AndroidManifest.xml +++ b/brouter-routing-app/src/main/AndroidManifest.xml @@ -91,5 +91,15 @@ android:exported="true" android:process=":brouter_service" /> + + + + diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java index 5306206..b9af03c 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java @@ -122,16 +122,16 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat "*** Attention: ***\n\n" + "The Download Manager is used to download routing-data " + "files which can be up to 170MB each. Do not start the Download Manager " + "on a cellular data connection without a data plan! " + "Download speed is restricted to 16 MBit/s.").setPositiveButton("I know", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class); - startActivity(intent); - showNewDialog(DIALOG_MAINACTION_ID); - } - }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - finish(); - } - }); + public void onClick(DialogInterface dialog, int id) { + Intent intent = new Intent(BRouterActivity.this, BInstallerActivity.class); + startActivity(intent); + showNewDialog(DIALOG_MAINACTION_ID); + } + }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + finish(); + } + }); return builder.create(); case DIALOG_SHOW_API23_HELP_ID: builder @@ -148,10 +148,10 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat + "the APK of the BRouter App from the release page ( http://brouter.de/brouter/revisions.html ), which " + "is still built against Android API 10, and does not have these limitations. " ).setNegativeButton("Exit", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - finish(); - } - }); + public void onClick(DialogInterface dialog, int id) { + finish(); + } + }); return builder.create(); case DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID: builder @@ -161,10 +161,10 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat + "when started from your map-tool. If you repeat the same request from your " + "maptool, with the exact same destination point and a close-by starting point, " + "this request is guaranteed not to time out.").setNegativeButton("Exit", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - finish(); - } - }); + public void onClick(DialogInterface dialog, int id) { + finish(); + } + }); return builder.create(); case DIALOG_OLDDATAHINT_ID: builder @@ -272,31 +272,49 @@ public class BRouterActivity extends AppCompatActivity implements ActivityCompat }); return builder.create(); case DIALOG_SHOWRESULT_ID: - String leftLabel = wpCount < 0 ? (wpCount != -2 ? "Exit" : "Help") : (wpCount == 0 ? "Select from" : "Select to/via"); - String rightLabel = wpCount < 2 ? (wpCount == -3 ? "Help" : "Server-Mode") : "Calc Route"; + // -3: Repeated route calculation + // -2: No waypoints? + // -1: Route calculated + // other: Select waypoints for route calculation + builder.setTitle(title).setMessage(errorMessage); - builder.setTitle(title).setMessage(errorMessage).setPositiveButton(leftLabel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - if (wpCount == -2) { - showWaypointDatabaseHelp(); - } else if (wpCount == -1 || wpCount == -3) { - finish(); - } else { - mBRouterView.pickWaypoints(); - } - } - }).setNegativeButton(rightLabel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - if (wpCount == -3) { - showRepeatTimeoutHelp(); - } else if (wpCount < 2) { - mBRouterView.startConfigureService(); - } else { - mBRouterView.finishWaypointSelection(); - mBRouterView.startProcessing(selectedProfile); - } - } + // Neutral button + if (wpCount == 0) { + builder.setNeutralButton("Server-Mode", (dialog, which) -> { + mBRouterView.startConfigureService(); + }); + } else if (wpCount == -3) { + builder.setNeutralButton("Info", (dialog, which) -> { + showRepeatTimeoutHelp(); + }); + } else if (wpCount == -2) { + builder.setNeutralButton("Help", (dialog, which) -> { + showWaypointDatabaseHelp(); + }); + } else if (wpCount >= 2) { + builder.setNeutralButton("Calc Route", (dialog, which) -> { + mBRouterView.finishWaypointSelection(); + mBRouterView.startProcessing(selectedProfile); + }); + } + + // Positive button + if (wpCount == -3 || wpCount == -1) { + builder.setPositiveButton("Share GPX", (dialog, which) -> { + mBRouterView.shareTrack(); + }); + } else if (wpCount >= 0) { + String selectLabel = wpCount == 0 ? "Select from" : "Select to/via"; + builder.setPositiveButton(selectLabel, (dialog, which) -> { + mBRouterView.pickWaypoints(); + }); + } + + // Negative button + builder.setNegativeButton("Exit", (dialog, which) -> { + finish(); }); + return builder.create(); case DIALOG_MODECONFIGOVERVIEW_ID: builder.setTitle("Success").setMessage(message).setPositiveButton("Exit", new DialogInterface.OnClickListener() { diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java index d075546..8c6f52e 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java @@ -2,6 +2,7 @@ package btools.routingapp; import android.Manifest; import android.content.Context; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.graphics.Canvas; @@ -13,6 +14,7 @@ import android.widget.Toast; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -68,6 +70,7 @@ public class BRouterView extends View { private boolean waitingForMigration = false; private String rawTrackPath; private String oldMigrationPath; + private String trackOutfile; private boolean needsViaSelection; private boolean needsNogoSelection; private boolean needsWaypointSelection; @@ -283,21 +286,19 @@ public class BRouterView extends View { } } - private void moveFile(String inputPath, String inputFile, String outputPath) { - + private void copyFile(String inputPath, String inputFile, String outputPath) { InputStream in; OutputStream out; - try { + try { //create output directory if it doesn't exist File dir = new File(outputPath); if (!dir.exists()) { dir.mkdirs(); } - - in = new FileInputStream(inputPath + "/" + inputFile); - out = new FileOutputStream(outputPath + "/" + inputFile); + in = new FileInputStream(new File(inputPath, inputFile)); + out = new FileOutputStream(new File(outputPath, inputFile)); byte[] buffer = new byte[1024]; int read; @@ -310,16 +311,17 @@ public class BRouterView extends View { out.flush(); out.close(); - // delete the original file - new File(inputPath + "/" + inputFile).delete(); - - - } catch (FileNotFoundException fnfe1) { - Log.e("tag", fnfe1.getMessage()); + } catch (FileNotFoundException fileNotFoundException) { + Log.e("tag", fileNotFoundException.getMessage()); } catch (Exception e) { Log.e("tag", e.getMessage()); } + } + private void moveFile(String inputPath, String inputFile, String outputPath) { + copyFile(inputPath, inputFile, outputPath); + // delete the original file + new File(inputPath, inputFile).delete(); } public boolean hasUpToDateLookups() { @@ -707,6 +709,7 @@ public class BRouterView extends View { title += " / " + cr.getAlternativeIndex() + ". Alternative"; ((BRouterActivity) getContext()).showResultMessage(title, result, rawTrackPath == null ? -1 : -3); + trackOutfile = cr.getOutfile(); } cr = null; waitingForSelection = true; @@ -848,4 +851,16 @@ public class BRouterView extends View { ((BRouterActivity) getContext()).showModeConfigOverview(msg.toString()); } + public void shareTrack() { + File track = new File(trackOutfile); + // Copy file to cache to ensure FileProvider allows sharing the file + File cacheDir = getContext().getCacheDir(); + copyFile(track.getParent(), track.getName(), cacheDir.getAbsolutePath()); + Intent intent = new Intent(); + intent.setDataAndType(FileProvider.getUriForFile(getContext(), "btools.routing.fileprovider", new File(cacheDir, track.getName())), + "application/gpx+xml"); + intent.setAction(Intent.ACTION_VIEW); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + getContext().startActivity(intent); + } } diff --git a/brouter-routing-app/src/main/res/xml/filepaths.xml b/brouter-routing-app/src/main/res/xml/filepaths.xml new file mode 100644 index 0000000..5b58665 --- /dev/null +++ b/brouter-routing-app/src/main/res/xml/filepaths.xml @@ -0,0 +1,5 @@ + + +