Cleanup base directory selection, use Context.getExternalFilesDirs and request WRITE_EXTERNAL_STORAGE permission, use AndroidX and raise minSdkVersion to 14. Use File instead of plain Strings for paths in some places, use try-with-resources, and some other small improvements.

This commit is contained in:
Niklas Guertler 2020-05-24 17:49:50 +02:00
parent 72e2e13d07
commit dbdfd36f88
17 changed files with 173 additions and 220 deletions

View file

@ -41,7 +41,7 @@ public class RoutingEngine extends Thread
private volatile boolean terminated; private volatile boolean terminated;
protected String segmentDir; protected File segmentDir;
private String outfileBase; private String outfileBase;
private String logfileBase; private String logfileBase;
private boolean infoLogEnabled; private boolean infoLogEnabled;
@ -64,7 +64,7 @@ public class RoutingEngine extends Thread
private boolean directWeaving = !Boolean.getBoolean( "disableDirectWeaving" ); private boolean directWeaving = !Boolean.getBoolean( "disableDirectWeaving" );
public RoutingEngine( String outfileBase, String logfileBase, String segmentDir, public RoutingEngine( String outfileBase, String logfileBase, File segmentDir,
List<OsmNodeNamed> waypoints, RoutingContext rc ) List<OsmNodeNamed> waypoints, RoutingContext rc )
{ {
this.segmentDir = segmentDir; this.segmentDir = segmentDir;

View file

@ -11,20 +11,20 @@ import btools.mapaccess.StorageConfigHelper;
public final class RoutingHelper public final class RoutingHelper
{ {
public static File getAdditionalMaptoolDir( String segmentDir ) public static File getAdditionalMaptoolDir( File segmentDir )
{ {
return StorageConfigHelper.getAdditionalMaptoolDir(segmentDir); return StorageConfigHelper.getAdditionalMaptoolDir(segmentDir);
} }
public static File getSecondarySegmentDir( String segmentDir ) public static File getSecondarySegmentDir( File segmentDir )
{ {
return StorageConfigHelper.getSecondarySegmentDir(segmentDir); return StorageConfigHelper.getSecondarySegmentDir(segmentDir);
} }
public static boolean hasDirectoryAnyDatafiles( String segmentDir ) public static boolean hasDirectoryAnyDatafiles( File segmentDir )
{ {
if ( hasAnyDatafiles( new File( segmentDir ) ) ) if ( hasAnyDatafiles( segmentDir ) )
{ {
return true; return true;
} }

View file

@ -56,10 +56,10 @@ public final class NodesCache
return "collecting=" + garbageCollectionEnabled + " noGhosts=" + ghostCleaningDone + " cacheSum=" + cacheSum + " cacheSumClean=" + cacheSumClean + " ghostSum=" + ghostSum + " ghostWakeup=" + ghostWakeup ; return "collecting=" + garbageCollectionEnabled + " noGhosts=" + ghostCleaningDone + " cacheSum=" + cacheSum + " cacheSumClean=" + cacheSumClean + " ghostSum=" + ghostSum + " ghostWakeup=" + ghostWakeup ;
} }
public NodesCache( String segmentDir, BExpressionContextWay ctxWay, boolean forceSecondaryData, long maxmem, NodesCache oldCache, boolean detailed ) public NodesCache( File segmentDir, BExpressionContextWay ctxWay, boolean forceSecondaryData, long maxmem, NodesCache oldCache, boolean detailed )
{ {
this.maxmemtiles = maxmem / 8; this.maxmemtiles = maxmem / 8;
this.segmentDir = new File( segmentDir ); this.segmentDir = segmentDir;
this.nodesMap = new OsmNodesMap(); this.nodesMap = new OsmNodesMap();
this.nodesMap.maxmem = (2L*maxmem) / 3L; this.nodesMap.maxmem = (2L*maxmem) / 3L;
this.expCtxWay = ctxWay; this.expCtxWay = ctxWay;
@ -77,7 +77,7 @@ public final class NodesCache
first_file_access_name = null; first_file_access_name = null;
if ( !this.segmentDir.isDirectory() ) if ( !this.segmentDir.isDirectory() )
throw new RuntimeException( "segment directory " + segmentDir + " does not exist" ); throw new RuntimeException( "segment directory " + segmentDir.getAbsolutePath () + " does not exist" );
if ( oldCache != null ) if ( oldCache != null )
{ {

View file

@ -11,21 +11,21 @@ import java.io.FileReader;
public class StorageConfigHelper public class StorageConfigHelper
{ {
public static File getSecondarySegmentDir( String segmentDir ) public static File getSecondarySegmentDir( File segmentDir )
{ {
return getStorageLocation( segmentDir, "secondary_segment_dir=" ); return getStorageLocation( segmentDir, "secondary_segment_dir=" );
} }
public static File getAdditionalMaptoolDir( String segmentDir ) public static File getAdditionalMaptoolDir( File segmentDir )
{ {
return getStorageLocation( segmentDir, "additional_maptool_dir=" ); return getStorageLocation( segmentDir, "additional_maptool_dir=" );
} }
private static File getStorageLocation( String segmentDir, String tag ) private static File getStorageLocation( File segmentDir, String tag )
{ {
File res = null; File res = null;
BufferedReader br = null; BufferedReader br = null;
String configFile = segmentDir + "/storageconfig.txt"; File configFile = new File (segmentDir, "storageconfig.txt");
try try
{ {
br = new BufferedReader( new FileReader( configFile ) ); br = new BufferedReader( new FileReader( configFile ) );
@ -38,7 +38,7 @@ public class StorageConfigHelper
if ( line.startsWith( tag ) ) if ( line.startsWith( tag ) )
{ {
String path = line.substring( tag.length() ).trim(); String path = line.substring( tag.length() ).trim();
res = path.startsWith( "/" ) ? new File( path ) : new File( new File( segmentDir ), path ); res = path.startsWith( "/" ) ? new File( path ) : new File( segmentDir, path );
if ( !res.exists() ) res = null; if ( !res.exists() ) res = null;
break; break;
} }

View file

@ -7,7 +7,7 @@ android {
defaultConfig { defaultConfig {
applicationId "btools.routingapp" applicationId "btools.routingapp"
minSdkVersion 10 minSdkVersion 14
targetSdkVersion 29 targetSdkVersion 29
versionCode 41 versionCode 41
versionName "1.6.1" versionName "1.6.1"
@ -27,6 +27,7 @@ android {
dependencies { dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation project(':brouter-mapaccess') implementation project(':brouter-mapaccess')
implementation project(':brouter-core') implementation project(':brouter-core')
implementation project(':brouter-expressions') implementation project(':brouter-expressions')

View file

@ -58,7 +58,7 @@ public class BInstallerView extends View
private boolean tilesVisible = false; private boolean tilesVisible = false;
private long availableSize; private long availableSize;
private String baseDir; private File baseDir;
private boolean isDownloading = false; private boolean isDownloading = false;
private volatile boolean downloadCanceled = false; private volatile boolean downloadCanceled = false;
@ -207,7 +207,7 @@ public class BInstallerView extends View
private void deleteRawTracks() private void deleteRawTracks()
{ {
File modeDir = new File( baseDir + "/brouter/modes" ); File modeDir = new File( baseDir, "brouter/modes" );
String[] fileNames = modeDir.list(); String[] fileNames = modeDir.list();
if ( fileNames == null ) return; if ( fileNames == null ) return;
for( String fileName : fileNames ) for( String fileName : fileNames )
@ -224,9 +224,9 @@ public class BInstallerView extends View
{ {
clearTileSelection( MASK_INSTALLED_RD5 | MASK_CURRENT_RD5 ); clearTileSelection( MASK_INSTALLED_RD5 | MASK_CURRENT_RD5 );
scanExistingFiles( new File( baseDir + "/brouter/segments4" ) ); scanExistingFiles( new File( baseDir, "brouter/segments4" ) );
File secondary = RoutingHelper.getSecondarySegmentDir( baseDir + "/brouter/segments4" ); File secondary = RoutingHelper.getSecondarySegmentDir( new File ( baseDir, "brouter/segments4" ) );
if ( secondary != null ) if ( secondary != null )
{ {
scanExistingFiles( secondary ); scanExistingFiles( secondary );
@ -235,7 +235,7 @@ public class BInstallerView extends View
availableSize = -1; availableSize = -1;
try try
{ {
StatFs stat = new StatFs(baseDir); StatFs stat = new StatFs(baseDir.getAbsolutePath ());
availableSize = (long)stat.getAvailableBlocks()*stat.getBlockSize(); availableSize = (long)stat.getAvailableBlocks()*stat.getBlockSize();
} }
catch (Exception e) { /* ignore */ } catch (Exception e) { /* ignore */ }
@ -472,7 +472,7 @@ float tx, ty;
int tidx = gridPos2Tileindex( ix, iy ); int tidx = gridPos2Tileindex( ix, iy );
if ( ( tileStatus[tidx] & MASK_DELETED_RD5 ) != 0 ) if ( ( tileStatus[tidx] & MASK_DELETED_RD5 ) != 0 )
{ {
new File( baseDir + "/brouter/segments4/" + baseNameForTile( tidx ) + ".rd5").delete(); new File( baseDir, "brouter/segments4/" + baseNameForTile( tidx ) + ".rd5").delete();
} }
} }
} }
@ -667,7 +667,7 @@ float tx, ty;
OutputStream output = null; OutputStream output = null;
HttpURLConnection connection = null; HttpURLConnection connection = null;
String surl = sUrls[0]; String surl = sUrls[0];
String fname = null; File fname = null;
File tmp_file = null; File tmp_file = null;
try try
{ {
@ -676,17 +676,16 @@ float tx, ty;
int slidx = surl.lastIndexOf( "segments4/" ); int slidx = surl.lastIndexOf( "segments4/" );
String name = surl.substring( slidx+10 ); String name = surl.substring( slidx+10 );
String surlBase = surl.substring( 0, slidx+10 ); String surlBase = surl.substring( 0, slidx+10 );
fname = baseDir + "/brouter/segments4/" + name; fname = new File (baseDir, "brouter/segments4/" + name);
boolean delta = true; boolean delta = true;
File targetFile = new File( fname ); if ( fname.exists() )
if ( targetFile.exists() )
{ {
updateProgress( "Calculating local checksum.." ); updateProgress( "Calculating local checksum.." );
// first check for a delta file // first check for a delta file
String md5 = Rd5DiffManager.getMD5( targetFile ); String md5 = Rd5DiffManager.getMD5( fname );
String surlDelta = surlBase + "diff/" + name.replace( ".rd5", "/" + md5 + ".rd5diff" ); String surlDelta = surlBase + "diff/" + name.replace( ".rd5", "/" + md5 + ".rd5diff" );
URL urlDelta = new URL(surlDelta); URL urlDelta = new URL(surlDelta);
@ -728,7 +727,7 @@ float tx, ty;
// download the file // download the file
input = connection.getInputStream(); input = connection.getInputStream();
tmp_file = new File( fname + ( delta ? "_diff" : "_tmp" ) ); tmp_file = new File( fname.getAbsolutePath() + ( delta ? "_diff" : "_tmp" ) );
output = new FileOutputStream( tmp_file ); output = new FileOutputStream( tmp_file );
byte data[] = new byte[4096]; byte data[] = new byte[4096];
@ -768,7 +767,7 @@ float tx, ty;
updateProgress( "Applying delta.." ); updateProgress( "Applying delta.." );
File diffFile = tmp_file; File diffFile = tmp_file;
tmp_file = new File( fname + "_tmp" ); tmp_file = new File( fname + "_tmp" );
Rd5DiffTool.recoverFromDelta( targetFile, diffFile, tmp_file, this ); Rd5DiffTool.recoverFromDelta( fname, diffFile, tmp_file, this );
diffFile.delete(); diffFile.delete();
} }
if (isDownloadCanceled()) if (isDownloadCanceled())
@ -781,9 +780,9 @@ float tx, ty;
String check_result = PhysicalFile.checkFileIntegrity( tmp_file ); String check_result = PhysicalFile.checkFileIntegrity( tmp_file );
if ( check_result != null ) return check_result; if ( check_result != null ) return check_result;
if ( !tmp_file.renameTo( targetFile ) ) if ( !tmp_file.renameTo( fname ) )
{ {
return "Could not rename to " + targetFile; return "Could not rename to " + fname.getAbsolutePath();
} }
deleteRawTracks(); // invalidate raw-tracks after data update deleteRawTracks(); // invalidate raw-tracks after data update
} }

View file

@ -1,5 +1,6 @@
package btools.routingapp; package btools.routingapp;
import java.io.File;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -13,16 +14,22 @@ import android.app.Dialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.PowerManager.WakeLock; import android.os.PowerManager.WakeLock;
import android.os.StatFs; import android.os.StatFs;
import android.speech.tts.TextToSpeech.OnInitListener; import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.widget.EditText; import android.widget.EditText;
import androidx.core.app.ActivityCompat;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
public class BRouterActivity extends Activity implements OnInitListener public class BRouterActivity extends Activity implements OnInitListener, ActivityCompat.OnRequestPermissionsResultCallback
{ {
private static final int DIALOG_SELECTPROFILE_ID = 1; private static final int DIALOG_SELECTPROFILE_ID = 1;
private static final int DIALOG_EXCEPTION_ID = 2; private static final int DIALOG_EXCEPTION_ID = 2;
@ -268,13 +275,14 @@ public class BRouterActivity extends Activity implements OnInitListener
public void onClick( DialogInterface dialog, int whichButton ) public void onClick( DialogInterface dialog, int whichButton )
{ {
String basedir = input.getText().toString(); String basedir = input.getText().toString();
mBRouterView.startSetup( basedir, true ); mBRouterView.startSetup( new File(basedir), true );
} }
} ); } );
return builder.create(); return builder.create();
case DIALOG_SELECTBASEDIR_ID: case DIALOG_SELECTBASEDIR_ID:
builder = new AlertDialog.Builder( this ); builder = new AlertDialog.Builder( this );
builder.setTitle( "Select an SDCARD base dir:" ); builder.setTitle( "Choose brouter data base dir:" );
// builder.setMessage( message );
builder.setSingleChoiceItems( basedirOptions, 0, new DialogInterface.OnClickListener() builder.setSingleChoiceItems( basedirOptions, 0, new DialogInterface.OnClickListener()
{ {
@Override @Override
@ -428,7 +436,7 @@ public class BRouterActivity extends Activity implements OnInitListener
private String[] availableProfiles; private String[] availableProfiles;
private String selectedProfile = null; private String selectedProfile = null;
private List<String> availableBasedirs; private List<File> availableBasedirs;
private String[] basedirOptions; private String[] basedirOptions;
private int selectedBasedir; private int selectedBasedir;
@ -484,22 +492,21 @@ public class BRouterActivity extends Activity implements OnInitListener
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void selectBasedir( List<String> items, String defaultBasedir, String message ) public void selectBasedir( ArrayList<File> items, String defaultBasedir, String message )
{ {
this.defaultbasedir = defaultBasedir; this.defaultbasedir = defaultBasedir;
this.message = message; this.message = message;
availableBasedirs = new ArrayList<String>(); availableBasedirs = items;
ArrayList<Long> dirFreeSizes = new ArrayList<Long>(); ArrayList<Long> dirFreeSizes = new ArrayList<Long>();
for ( String d : items ) for ( File f : items )
{ {
long size = 0L; long size = 0L;
try try
{ {
StatFs stat = new StatFs( d ); StatFs stat = new StatFs( f.getAbsolutePath() );
size = (long) stat.getAvailableBlocks() * stat.getBlockSize(); size = (long) stat.getAvailableBlocks() * stat.getBlockSize();
} }
catch (Exception e) { /* ignore */ } catch (Exception e) { /* ignore */ }
availableBasedirs.add( d );
dirFreeSizes.add( Long.valueOf( size ) ); dirFreeSizes.add( Long.valueOf( size ) );
} }
@ -510,7 +517,7 @@ public class BRouterActivity extends Activity implements OnInitListener
{ {
basedirOptions[bdidx++] = availableBasedirs.get( idx ) + " (" + df.format( dirFreeSizes.get( idx ) / 1024. / 1024. / 1024. ) + " GB free)"; basedirOptions[bdidx++] = availableBasedirs.get( idx ) + " (" + df.format( dirFreeSizes.get( idx ) / 1024. / 1024. / 1024. ) + " GB free)";
} }
basedirOptions[bdidx] = "Other"; basedirOptions[bdidx] = "Enter path manually";
showDialog( DIALOG_SELECTBASEDIR_ID ); showDialog( DIALOG_SELECTBASEDIR_ID );
} }
@ -644,4 +651,15 @@ public class BRouterActivity extends Activity implements OnInitListener
public void onInit( int i ) public void onInit( int i )
{ {
} }
@Override
public void onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 0) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mBRouterView.startSetup(null, true);
} else {
mBRouterView.init();
}
}
}
} }

View file

@ -11,6 +11,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -58,7 +59,7 @@ public class BRouterService extends Service
if ( configInput != null ) try { configInput.close(); } catch (Exception ee) {} if ( configInput != null ) try { configInput.close(); } catch (Exception ee) {}
} }
worker.baseDir = baseDir; worker.baseDir = baseDir;
worker.segmentDir = baseDir + "/brouter/segments4"; worker.segmentDir = new File (baseDir, "brouter/segments4" );
String remoteProfile = params.getString( "remoteProfile" ); String remoteProfile = params.getString( "remoteProfile" );
@ -85,9 +86,9 @@ public class BRouterService extends Service
try try
{ {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos.write( "z64".getBytes("UTF-8") ); // marker prefix baos.write( "z64".getBytes(StandardCharsets.UTF_8) ); // marker prefix
OutputStream os = new GZIPOutputStream( baos ); OutputStream os = new GZIPOutputStream( baos );
byte[] ab = gpxMessage.getBytes("UTF-8"); byte[] ab = gpxMessage.getBytes(StandardCharsets.UTF_8);
gpxMessage = null; gpxMessage = null;
os.write( ab ); os.write( ab );
ab = null; ab = null;

View file

@ -12,6 +12,7 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
@ -19,16 +20,24 @@ import java.util.TreeMap;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import android.Manifest;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.os.Environment; import android.os.Environment;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.os.EnvironmentCompat;
import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionContextWay;
import btools.expressions.BExpressionMetaData; import btools.expressions.BExpressionMetaData;
import btools.mapaccess.OsmNode; import btools.mapaccess.OsmNode;
@ -57,10 +66,11 @@ public class BRouterView extends View
private List<OsmNodeNamed> nogoVetoList; private List<OsmNodeNamed> nogoVetoList;
private OsmTrack rawTrack; private OsmTrack rawTrack;
private String modesDir; private File retryBaseDir;
private String tracksDir; private File modesDir;
private String segmentDir; private File tracksDir;
private String profileDir; private File segmentDir;
private File profileDir;
private String profilePath; private String profilePath;
private String profileName; private String profileName;
private String sourceHint; private String sourceHint;
@ -104,14 +114,13 @@ public class BRouterView extends View
imgh = metrics.heightPixels; imgh = metrics.heightPixels;
// get base dir from private file // get base dir from private file
String baseDir = ConfigHelper.getBaseDir( getContext() ); File baseDir = ConfigHelper.getBaseDir( getContext() );
// check if valid // check if valid
boolean bdValid = false; boolean bdValid = false;
if ( baseDir != null ) if ( baseDir != null )
{ {
File bd = new File( baseDir ); bdValid = baseDir.isDirectory();
bdValid = bd.isDirectory(); File brd = new File( baseDir, "brouter" );
File brd = new File( bd, "brouter" );
if ( brd.isDirectory() ) if ( brd.isDirectory() )
{ {
startSetup( baseDir, false ); startSetup( baseDir, false );
@ -135,64 +144,59 @@ public class BRouterView extends View
} }
} }
public void startSetup( String baseDir, boolean storeBasedir ) public void startSetup( File baseDir, boolean storeBasedir )
{ {
cor = null; if (baseDir == null) {
try baseDir = retryBaseDir;
{ retryBaseDir = null;
File fbd = new File( baseDir );
if ( !fbd.isDirectory() )
{
throw new IllegalArgumentException( "Base-directory " + baseDir + " is not a directory " );
}
if ( storeBasedir )
{
// Android 4.4 patch: try extend the basedir if not valid
File td = new File( fbd, "brouter" );
try
{
td.mkdir();
}
catch (Exception e) {}
if ( !td.isDirectory() )
{
File td1 = new File( fbd, "Android/data/btools/routingapp" );
try
{
td1.mkdirs();
}
catch (Exception e){}
td = new File( td1, "brouter" );
try
{
td.mkdir();
}
catch (Exception e) {}
if ( td.isDirectory() )
fbd = td1;
} }
if ( storeBasedir )
{
File td = new File( baseDir, "brouter" );
try
{
td.mkdirs();
}
catch (Exception e) {
Log.d ("BRouterView", "Error creating base directory: " + e.getMessage());
e.printStackTrace();
}
if ( !td.isDirectory() ) {
if (ContextCompat.checkSelfPermission (getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
retryBaseDir = baseDir;
ActivityCompat.requestPermissions ((BRouterActivity) getContext(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
} else {
( (BRouterActivity) getContext() ).selectBasedir( getStorageDirectories (), guessBaseDir(), "Cannot access " + baseDir.getAbsolutePath () + "; select another");
}
return;
}
ConfigHelper.writeBaseDir( getContext(), baseDir ); ConfigHelper.writeBaseDir( getContext(), baseDir );
} }
String basedir = fbd.getAbsolutePath(); try
{
cor = null;
String basedir = baseDir.getAbsolutePath();
AppLogger.log( "using basedir: " + basedir ); AppLogger.log( "using basedir: " + basedir );
String version = "v1.6.1"; String version = "v1.6.1";
// create missing directories // create missing directories
assertDirectoryExists( "project directory", basedir + "/brouter", null, null ); assertDirectoryExists( "project directory", new File (basedir, "brouter"), null, null );
segmentDir = basedir + "/brouter/segments4"; segmentDir = new File (basedir, "/brouter/segments4");
if ( assertDirectoryExists( "data directory", segmentDir, "segments4.zip", null ) ) if ( assertDirectoryExists( "data directory", segmentDir, "segments4.zip", null ) )
{ {
ConfigMigration.tryMigrateStorageConfig( ConfigMigration.tryMigrateStorageConfig(
new File( basedir + "/brouter/segments3/storageconfig.txt" ), new File( basedir + "/brouter/segments3/storageconfig.txt" ),
new File( basedir + "/brouter/segments4/storageconfig.txt" ) ); new File( basedir + "/brouter/segments4/storageconfig.txt" ) );
} }
profileDir = basedir + "/brouter/profiles2"; profileDir = new File (basedir, "brouter/profiles2");
assertDirectoryExists( "profile directory", profileDir, "profiles2.zip", version ); assertDirectoryExists( "profile directory", profileDir, "profiles2.zip", version );
modesDir = basedir + "/brouter/modes"; modesDir = new File (basedir, "/brouter/modes");
assertDirectoryExists( "modes directory", modesDir, "modes.zip", version ); assertDirectoryExists( "modes directory", modesDir, "modes.zip", version );
assertDirectoryExists( "readmes directory", basedir + "/brouter/readmes", "readmes.zip", version ); assertDirectoryExists( "readmes directory", new File (basedir, "brouter/readmes"), "readmes.zip", version );
int deviceLevel = android.os.Build.VERSION.SDK_INT; int deviceLevel = android.os.Build.VERSION.SDK_INT;
int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion;
@ -219,17 +223,18 @@ public class BRouterView extends View
if ( cor.tracksdir != null ) if ( cor.tracksdir != null )
{ {
tracksDir = cor.basedir + cor.tracksdir; tracksDir = new File (cor.basedir, cor.tracksdir);
assertDirectoryExists( "track directory", tracksDir, null, null ); assertDirectoryExists( "track directory", tracksDir, null, null );
// output redirect: look for a pointerfile in tracksdir // output redirect: look for a pointerfile in tracksdir
File tracksDirPointer = new File( tracksDir + "/brouter.redirect" ); File tracksDirPointer = new File( tracksDir, "brouter.redirect" );
if ( tracksDirPointer.isFile() ) if ( tracksDirPointer.isFile() )
{ {
tracksDir = readSingleLineFile( tracksDirPointer ); String tracksDirStr = readSingleLineFile( tracksDirPointer );
if ( tracksDir == null ) if ( tracksDirStr == null )
throw new IllegalArgumentException( "redirect pointer file is empty: " + tracksDirPointer ); throw new IllegalArgumentException( "redirect pointer file is empty: " + tracksDirPointer );
if ( !( new File( tracksDir ).isDirectory() ) ) tracksDir = new File (tracksDirStr);
if ( !( tracksDir.isDirectory() ) )
throw new IllegalArgumentException( "redirect pointer file " + tracksDirPointer + " does not point to a directory: " + tracksDir ); throw new IllegalArgumentException( "redirect pointer file " + tracksDirPointer + " does not point to a directory: " + tracksDir );
} }
else else
@ -248,10 +253,10 @@ public class BRouterView extends View
} }
if ( tracksDir == null ) if ( tracksDir == null )
{ {
tracksDir = basedir + "/brouter"; // fallback tracksDir = new File (basedir, "router"); // fallback
} }
String[] fileNames = new File( profileDir ).list(); String[] fileNames = profileDir.list();
ArrayList<String> profiles = new ArrayList<String>(); ArrayList<String> profiles = new ArrayList<String>();
boolean lookupsFound = false; boolean lookupsFound = false;
@ -387,7 +392,7 @@ public class BRouterView extends View
{ {
if ( wp.name.equals( waypoint ) ) if ( wp.name.equals( waypoint ) )
{ {
if ( wp.ilat != 0 || wp.ilat != 0 ) if ( wp.ilat != 0 || wp.ilon != 0 )
{ {
int nwp = wpList.size(); int nwp = wpList.size();
if ( nwp == 0 || wpList.get( nwp-1 ) != wp ) if ( nwp == 0 || wpList.get( nwp-1 ) != wp )
@ -513,10 +518,10 @@ public class BRouterView extends View
OsmNode prev = null; OsmNode prev = null;
for ( OsmNode n : wpList ) for ( OsmNode n : wpList )
{ {
maxlon = n.ilon > maxlon ? n.ilon : maxlon; maxlon = Math.max(n.ilon, maxlon);
minlon = n.ilon < minlon ? n.ilon : minlon; minlon = Math.min(n.ilon, minlon);
maxlat = n.ilat > maxlat ? n.ilat : maxlat; maxlat = Math.max(n.ilat, maxlat);
minlat = n.ilat < minlat ? n.ilat : minlat; minlat = Math.min(n.ilat, minlat);
if ( prev != null ) if ( prev != null )
{ {
plain_distance += n.calcDistance( prev ); plain_distance += n.calcDistance( prev );
@ -536,7 +541,7 @@ public class BRouterView extends View
scaleLon = imgw / ( difflon * 1.5 ); scaleLon = imgw / ( difflon * 1.5 );
scaleLat = imgh / ( difflat * 1.5 ); scaleLat = imgh / ( difflat * 1.5 );
scaleMeter2Pixel = scaleLon < scaleLat ? scaleLon : scaleLat; scaleMeter2Pixel = Math.min(scaleLon, scaleLat);
scaleLon = scaleMeter2Pixel*dlon2m; scaleLon = scaleMeter2Pixel*dlon2m;
scaleLat = scaleMeter2Pixel*dlat2m; scaleLat = scaleMeter2Pixel*dlat2m;
@ -570,18 +575,16 @@ public class BRouterView extends View
} }
} }
private boolean assertDirectoryExists( String message, String path, String assetZip, String versionTag ) private boolean assertDirectoryExists( String message, File path, String assetZip, String versionTag )
{ {
File f = new File( path ); boolean exists = path.exists();
boolean exists = f.exists();
if ( !exists ) if ( !exists )
{ {
f.mkdirs(); path.mkdirs();
} }
if ( versionTag != null ) if ( versionTag != null )
{ {
File vtag = new File( f, versionTag ); File vtag = new File( path, versionTag );
try try
{ {
exists = !vtag.createNewFile(); exists = !vtag.createNewFile();
@ -606,7 +609,7 @@ public class BRouterView extends View
if ( ze == null ) if ( ze == null )
break; break;
String name = ze.getName(); String name = ze.getName();
File outfile = new File( f, name ); File outfile = new File( path, name );
outfile.getParentFile().mkdirs(); outfile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream( outfile ); FileOutputStream fos = new FileOutputStream( outfile );
@ -629,7 +632,7 @@ public class BRouterView extends View
} }
} }
if ( !f.exists() || !f.isDirectory() ) if ( !path.exists() || !path.isDirectory() )
throw new IllegalArgumentException( message + ": " + path + " cannot be created" ); throw new IllegalArgumentException( message + ": " + path + " cannot be created" );
return false; return false;
} }
@ -1071,76 +1074,29 @@ public class BRouterView extends View
private String readSingleLineFile( File f ) private String readSingleLineFile( File f )
{ {
BufferedReader br = null; try ( FileInputStream fis = new FileInputStream (f);
try InputStreamReader isr = new InputStreamReader (fis);
{ BufferedReader br = new BufferedReader (isr)) {
br = new BufferedReader( new InputStreamReader( new FileInputStream( f ) ) );
return br.readLine(); return br.readLine();
} }
catch (Exception e) catch (Exception e)
{ {
return null; return null;
} }
finally
{
if ( br != null )
try
{
br.close();
}
catch (Exception ee)
{
} }
private ArrayList<File> getStorageDirectories () {
ArrayList<File> list = new ArrayList<File>(Arrays.asList(getContext().getExternalFilesDirs(null)));
ArrayList<File> res = new ArrayList<File>();
for (File f : list) {
if (f != null) {
if (EnvironmentCompat.getStorageState(f).equals(Environment.MEDIA_MOUNTED))
res.add (f);
} }
} }
private List<String> getStorageDirectories() // res.add(getContext().getFilesDir());
{
ArrayList<String> res = new ArrayList<String>();
// check write access on internal sd
try
{
File sd = Environment.getExternalStorageDirectory();
File testDir = new File( sd, "brouter" );
boolean didExist = testDir.isDirectory();
if ( !didExist )
{
testDir.mkdir();
}
File testFile = new File( testDir, "test" + System.currentTimeMillis() );
testFile.createNewFile();
if ( testFile.exists() )
{
testFile.delete();
res.add( sd.getPath() );
}
if ( !didExist )
{
testDir.delete();
}
}
catch( Throwable t )
{
// ignore
}
try
{
Method method = Context.class.getDeclaredMethod("getExternalFilesDirs", new Class[]{ String.class } );
File[] paths = (File[])method.invoke( getContext(), new Object[1] );
for( File path : paths )
{
res.add( path.getPath() );
}
}
catch( Exception e )
{
res.add( e.toString() );
res.add( Environment.getExternalStorageDirectory().getPath() );
}
return res; return res;
} }
} }

View file

@ -17,7 +17,7 @@ import btools.router.RoutingEngine;
public class BRouterWorker public class BRouterWorker
{ {
public String baseDir; public String baseDir;
public String segmentDir; public File segmentDir;
public String profileName; public String profileName;
public String profilePath; public String profilePath;
public String rawTrackPath; public String rawTrackPath;

View file

@ -6,59 +6,35 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.File;
import android.content.Context; import android.content.Context;
public class ConfigHelper public class ConfigHelper
{ {
public static String getBaseDir( Context ctx ) public static File getBaseDir( Context ctx )
{ {
// get base dir from private file // get base dir from private file
InputStream configInput = null;
try try (InputStream configInput = ctx.openFileInput( "config15.dat" );
{ InputStreamReader isr = new InputStreamReader( configInput );
configInput = ctx.openFileInput( "config15.dat" ); BufferedReader br = new BufferedReader(isr)) {
BufferedReader br = new BufferedReader( new InputStreamReader( configInput ) ); return new File ( br.readLine() );
return br.readLine();
} }
catch (Exception e) catch (Exception e)
{ {
return null; return null;
} }
finally
{
if ( configInput != null )
{
try
{
configInput.close();
}
catch (Exception ee)
{
}
}
}
} }
public static void writeBaseDir( Context ctx, String baseDir ) public static void writeBaseDir( Context ctx, File baseDir )
{ {
BufferedWriter bw = null; try (OutputStream configOutput = ctx.openFileOutput( "config15.dat", Context.MODE_PRIVATE );
try OutputStreamWriter osw = new OutputStreamWriter( configOutput );
{ BufferedWriter bw = new BufferedWriter( osw)) {
OutputStream configOutput = ctx.openFileOutput( "config15.dat", Context.MODE_PRIVATE ); bw.write( baseDir.getAbsolutePath () );
bw = new BufferedWriter( new OutputStreamWriter( configOutput ) );
bw.write( baseDir );
bw.write( '\n' ); bw.write( '\n' );
} }
catch (Exception e){ /* ignore */ } catch (Exception e){ /* ignore */ }
finally
{
if ( bw != null )
try
{
bw.close();
}
catch (Exception ee) { /* ignore */ }
}
} }
} }

View file

@ -87,17 +87,17 @@ public class ConfigMigration
} }
} }
public static File saveAdditionalMaptoolDir( String segmentDir, String value ) public static File saveAdditionalMaptoolDir( File segmentDir, String value )
{ {
return saveStorageLocation( segmentDir, "additional_maptool_dir=", value ); return saveStorageLocation( segmentDir, "additional_maptool_dir=", value );
} }
private static File saveStorageLocation( String segmentDir, String tag, String value ) private static File saveStorageLocation( File segmentDir, String tag, String value )
{ {
File res = null; File res = null;
BufferedReader br = null; BufferedReader br = null;
BufferedWriter bw = null; BufferedWriter bw = null;
String configFile = segmentDir + "/storageconfig.txt"; File configFile = new File (segmentDir, "storageconfig.txt");
List<String> lines = new ArrayList<String>(); List<String> lines = new ArrayList<String>();
try try
{ {

View file

@ -149,12 +149,12 @@ public abstract class CoordinateReader
protected abstract void readPointmap() throws Exception; protected abstract void readPointmap() throws Exception;
public static CoordinateReader obtainValidReader( String basedir, String segmentDir ) throws Exception public static CoordinateReader obtainValidReader( String basedir, File segmentDir ) throws Exception
{ {
return obtainValidReader( basedir, segmentDir, false ); return obtainValidReader( basedir, segmentDir, false );
} }
public static CoordinateReader obtainValidReader( String basedir, String segmentDir, boolean nogosOnly ) throws Exception public static CoordinateReader obtainValidReader( String basedir, File segmentDir, boolean nogosOnly ) throws Exception
{ {
CoordinateReader cor = null; CoordinateReader cor = null;
ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>(); ArrayList<CoordinateReader> rl = new ArrayList<CoordinateReader>();

View file

@ -6,6 +6,7 @@ import java.io.FileOutputStream;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.io.File;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
import btools.router.RoutingContext; import btools.router.RoutingContext;
@ -75,7 +76,7 @@ public class BRouter
wplist.add( from ); wplist.add( from );
wplist.add( to ); wplist.add( to );
RoutingEngine re = new RoutingEngine( null, null, args[0], wplist, readRoutingContext(a2) ); RoutingEngine re = new RoutingEngine( null, null, new File (args[0]), wplist, readRoutingContext(a2) );
re.doRun( maxRunningTime ); re.doRun( maxRunningTime );
if ( re.getErrorMessage() != null ) if ( re.getErrorMessage() != null )
{ {
@ -111,7 +112,7 @@ public class BRouter
SearchBoundary boundary = new SearchBoundary( wplist.get(0), searchRadius, direction/2 ); SearchBoundary boundary = new SearchBoundary( wplist.get(0), searchRadius, direction/2 );
rc.trafficOutputStream = dos; rc.trafficOutputStream = dos;
rc.inverseDirection = (direction & 1 ) != 0; rc.inverseDirection = (direction & 1 ) != 0;
re = new RoutingEngine( "mytrack", "mylog", args[0], wplist, rc ); re = new RoutingEngine( "mytrack", "mylog", new File ( args[0] ), wplist, rc );
re.boundary = boundary; re.boundary = boundary;
re.airDistanceCostFactor = rc.trafficDirectionFactor; re.airDistanceCostFactor = rc.trafficDirectionFactor;
rc.countTraffic = true; rc.countTraffic = true;
@ -127,7 +128,7 @@ public class BRouter
{ {
wplist.add( readPosition( args, 3, "to" ) ); wplist.add( readPosition( args, 3, "to" ) );
RoutingContext rc = readRoutingContext(args); RoutingContext rc = readRoutingContext(args);
re = new RoutingEngine( "mytrack", "mylog", args[0], wplist, rc ); re = new RoutingEngine( "mytrack", "mylog", new File ( args[0] ), wplist, rc );
re.doRun( 0 ); re.doRun( 0 );
} }

View file

@ -294,7 +294,7 @@ public class RouteServer extends Thread implements Comparable<RouteServer>
} }
ServiceContext serviceContext = new ServiceContext(); ServiceContext serviceContext = new ServiceContext();
serviceContext.segmentDir = args[0]; serviceContext.segmentDir = new File ( args[0] );
serviceContext.profileDir = args[1]; serviceContext.profileDir = args[1];
System.setProperty( "profileBaseDir", serviceContext.profileDir ); System.setProperty( "profileBaseDir", serviceContext.profileDir );
String dirs = args[2]; String dirs = args[2];

View file

@ -2,6 +2,7 @@ package btools.server;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.io.File;
import btools.router.OsmNodeNamed; import btools.router.OsmNodeNamed;
@ -10,7 +11,7 @@ import btools.router.OsmNodeNamed;
*/ */
public class ServiceContext public class ServiceContext
{ {
public String segmentDir; public File segmentDir;
public String profileDir; public String profileDir;
public String customProfileDir; public String customProfileDir;
public String sharedProfileDir; public String sharedProfileDir;

View file

@ -67,7 +67,7 @@ public class RouterTest
RoutingEngine re = new RoutingEngine( RoutingEngine re = new RoutingEngine(
wd + "/" + trackname, wd + "/" + trackname,
wd + "/" + trackname, wd + "/" + trackname,
wd + "/../../../brouter-map-creator/target/test-classes/tmp/segments", wplist, rctx ); new File ( wd, "/../../../brouter-map-creator/target/test-classes/tmp/segments"), wplist, rctx );
re.doRun( 0 ); re.doRun( 0 );
return re.getErrorMessage(); return re.getErrorMessage();