From cf4a188e40ab5d6baf6d0ab0f80a7815c42cdd05 Mon Sep 17 00:00:00 2001 From: Manuel Fuhr Date: Thu, 21 Oct 2021 15:56:39 +0200 Subject: [PATCH 1/5] Rename flavours to specify targetSdkVersion The targetSdkVersion specifies which behaviour the app expects from the android platform. For past releases of BRouter the targetSdkVersion was specified in the filename, therefore this restores the old bevahior. --- brouter-routing-app/build.gradle | 9 ++++----- brouter-server/build.gradle | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/brouter-routing-app/build.gradle b/brouter-routing-app/build.gradle index dfaee18..b58f639 100644 --- a/brouter-routing-app/build.gradle +++ b/brouter-routing-app/build.gradle @@ -13,7 +13,6 @@ android { resValue('string', 'app_version', defaultConfig.versionName) setProperty("archivesBaseName","BRouterApp." + defaultConfig.versionName) - } if(project.hasProperty("RELEASE_STORE_FILE")) { @@ -65,20 +64,20 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } + flavorDimensions "api" productFlavors { - api10 { + api19 { dimension "api" minSdkVersion 10 targetSdkVersion 19 } - api19 { + api30 { dimension "api" minSdkVersion 19 targetSdkVersion 30 - } } @@ -86,7 +85,7 @@ android { dependencies { - api19Implementation 'androidx.appcompat:appcompat:1.3.1' + api30Implementation 'androidx.appcompat:appcompat:1.3.1' implementation project(':brouter-mapaccess') implementation project(':brouter-core') diff --git a/brouter-server/build.gradle b/brouter-server/build.gradle index 1cc9361..6b4aaea 100644 --- a/brouter-server/build.gradle +++ b/brouter-server/build.gradle @@ -54,10 +54,10 @@ distributions { include 'readmes/*' include 'profiles2/*' } - from ('../brouter-routing-app/build/outputs/apk/api10/release') { + from ('../brouter-routing-app/build/outputs/apk/api19/release') { include '*.apk' } - from ('../brouter-routing-app/build/outputs/apk/api19/release') { + from ('../brouter-routing-app/build/outputs/apk/api30/release') { include '*.apk' } from ('../brouter-server/build/libs') { From 0e04c1a849d49f63b624637cd024e369e5a42d46 Mon Sep 17 00:00:00 2001 From: Manuel Fuhr Date: Thu, 21 Oct 2021 15:56:47 +0200 Subject: [PATCH 2/5] Increase minSdkVersion to 14 and merge implementations AndroidX needs at least API level 14 (Ice Cream Sandwich) which was released 10 years ago and should not exclude many devices. Having a merged tree simplifies the development. --- brouter-routing-app/build.gradle | 6 +- .../routingapp/BInstallerMainActivity.java | 27 ----- .../routingapp/BRouterMainActivity.java | 106 ------------------ .../btools/routingapp/NotificationHelper.java | 104 ----------------- .../routingapp/BInstallerMainActivity.java | 37 ------ .../routingapp/BRouterMainActivity.java | 88 --------------- .../btools/routingapp/BInstallerActivity.java | 13 ++- .../btools/routingapp/BRouterActivity.java | 65 ++++++++++- .../btools/routingapp/NotificationHelper.java | 0 9 files changed, 78 insertions(+), 368 deletions(-) delete mode 100644 brouter-routing-app/src/api10/java/btools/routingapp/BInstallerMainActivity.java delete mode 100644 brouter-routing-app/src/api10/java/btools/routingapp/BRouterMainActivity.java delete mode 100644 brouter-routing-app/src/api10/java/btools/routingapp/NotificationHelper.java delete mode 100644 brouter-routing-app/src/api19/java/btools/routingapp/BInstallerMainActivity.java delete mode 100644 brouter-routing-app/src/api19/java/btools/routingapp/BRouterMainActivity.java rename brouter-routing-app/src/{api19 => main}/java/btools/routingapp/NotificationHelper.java (100%) diff --git a/brouter-routing-app/build.gradle b/brouter-routing-app/build.gradle index b58f639..c84a2a8 100644 --- a/brouter-routing-app/build.gradle +++ b/brouter-routing-app/build.gradle @@ -13,6 +13,8 @@ android { resValue('string', 'app_version', defaultConfig.versionName) setProperty("archivesBaseName","BRouterApp." + defaultConfig.versionName) + + minSdkVersion 14 } if(project.hasProperty("RELEASE_STORE_FILE")) { @@ -70,13 +72,11 @@ android { api19 { dimension "api" - minSdkVersion 10 targetSdkVersion 19 } api30 { dimension "api" - minSdkVersion 19 targetSdkVersion 30 } } @@ -85,7 +85,7 @@ android { dependencies { - api30Implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'androidx.appcompat:appcompat:1.3.1' implementation project(':brouter-mapaccess') implementation project(':brouter-core') diff --git a/brouter-routing-app/src/api10/java/btools/routingapp/BInstallerMainActivity.java b/brouter-routing-app/src/api10/java/btools/routingapp/BInstallerMainActivity.java deleted file mode 100644 index 9d354a5..0000000 --- a/brouter-routing-app/src/api10/java/btools/routingapp/BInstallerMainActivity.java +++ /dev/null @@ -1,27 +0,0 @@ -package btools.routingapp; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.os.Bundle; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.StatFs; - -import java.util.HashSet; -import java.util.Set; - -public class BInstallerMainActivity extends Activity { - - - static public long getAvailableSpace (String baseDir) { - StatFs stat = new StatFs(baseDir); - return (long)stat.getAvailableBlocks()*stat.getBlockSize(); - } -} diff --git a/brouter-routing-app/src/api10/java/btools/routingapp/BRouterMainActivity.java b/brouter-routing-app/src/api10/java/btools/routingapp/BRouterMainActivity.java deleted file mode 100644 index 92f07ef..0000000 --- a/brouter-routing-app/src/api10/java/btools/routingapp/BRouterMainActivity.java +++ /dev/null @@ -1,106 +0,0 @@ -package btools.routingapp; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.StatFs; -import android.widget.EditText; - -import java.io.File; -import java.lang.reflect.Method; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import btools.router.OsmNodeNamed; - -public class BRouterMainActivity extends Activity -{ - - public boolean checkSelfPermission (Context context, String perm ) { - return true; - } - - public String getStorageState(File f ) { - return Environment.getExternalStorageState(); - } - - public ArrayList getStorageDirectories() { - List list = getFilesDirs(); - ArrayList flist = new ArrayList<>(); - for (String s: list) { - File f = new File(s); - flist.add(f); - } - return flist; - } - - private List getFilesDirs() - { - ArrayList res = new ArrayList(); - - // 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 - } - - /* - // not on api 10 - try - { - Method method = Context.class.getDeclaredMethod("getExternalFilesDirs", new Class[]{ String.class } ); - File[] paths = (File[])method.invoke( this, 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; - } - -} diff --git a/brouter-routing-app/src/api10/java/btools/routingapp/NotificationHelper.java b/brouter-routing-app/src/api10/java/btools/routingapp/NotificationHelper.java deleted file mode 100644 index 18d0525..0000000 --- a/brouter-routing-app/src/api10/java/btools/routingapp/NotificationHelper.java +++ /dev/null @@ -1,104 +0,0 @@ -package btools.routingapp; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.media.AudioAttributes; -import android.os.Build; -import android.util.Log; - - - -import static android.content.Context.NOTIFICATION_SERVICE; - -public class NotificationHelper { - - private static final boolean DEBUG = false; - - public static String BRouterNotificationChannel1 = "brouter_channel_01"; - - private Context mContext; - private int NOTIFICATION_ID = 111; - private Notification mNotification; - private NotificationManager mNotificationManager; - private PendingIntent mContentIntent; - private CharSequence mContentTitle; - - public NotificationHelper(Context context) - { - if (DEBUG) Log.d("NH", "init " ); - mContext = context; - createNotificationChannels(); - } - - public void startNotification(Service service) { - if (DEBUG) Log.d("NH", "startNotification " ); - - mNotification = createNotification("BRouter Download", "Download some files"); - if (mNotification != null) { - NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - } - } - - public void progressUpdate(String text) { - mNotification = createNotification("BRouter Download", text); - - if (mNotification != null) { - mNotification.flags = Notification.FLAG_NO_CLEAR | - Notification.FLAG_ONGOING_EVENT; - NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationManager.notify(NOTIFICATION_ID, mNotification); - } - } - - - public Notification createNotification(String title, String desc) { - - Intent resultIntent = new Intent(mContext, BInstallerActivity.class); - - Intent notificationIntent = new Intent(); - mContentIntent = PendingIntent.getActivity(mContext, 0, resultIntent, PendingIntent.FLAG_IMMUTABLE); - - Notification.Builder builder ; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { - builder = new Notification.Builder(mContext); - builder.setSmallIcon(android.R.drawable.stat_sys_download) - .setContentTitle(title) - .setContentText(desc) - .setOnlyAlertOnce(true) - .setContentIntent(mContentIntent); - - if(Build.VERSION.SDK_INT>=11 && Build.VERSION.SDK_INT<=15) - return builder.getNotification(); - else if (Build.VERSION.SDK_INT > 15) - return builder.build(); - } - - return null; - - } - - - - /** - * create notification channels - */ - public void createNotificationChannels() { - if (DEBUG) Log.d("NH", "createNotificationChannels " ); - - } - - public void stopNotification() { - if (DEBUG) Log.d("NH", "stopNotification " ); - NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - mNotificationManager.deleteNotificationChannel(BRouterNotificationChannel1); - } - mNotificationManager.cancel(NOTIFICATION_ID); - } -} \ No newline at end of file diff --git a/brouter-routing-app/src/api19/java/btools/routingapp/BInstallerMainActivity.java b/brouter-routing-app/src/api19/java/btools/routingapp/BInstallerMainActivity.java deleted file mode 100644 index 3b37d9e..0000000 --- a/brouter-routing-app/src/api19/java/btools/routingapp/BInstallerMainActivity.java +++ /dev/null @@ -1,37 +0,0 @@ -package btools.routingapp; - -import java.util.HashSet; -import java.util.Set; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.os.Bundle; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.speech.tts.TextToSpeech.OnInitListener; -import android.os.StatFs; -import android.util.Log; - -public class BInstallerMainActivity extends Activity implements OnInitListener { - - - @Override - public void onInit(int i) - { - } - - - static public long getAvailableSpace (String baseDir) { - StatFs stat = new StatFs(baseDir); - - return (long)stat.getAvailableBlocksLong()*stat.getBlockSizeLong(); - } - -} diff --git a/brouter-routing-app/src/api19/java/btools/routingapp/BRouterMainActivity.java b/brouter-routing-app/src/api19/java/btools/routingapp/BRouterMainActivity.java deleted file mode 100644 index 8f33453..0000000 --- a/brouter-routing-app/src/api19/java/btools/routingapp/BRouterMainActivity.java +++ /dev/null @@ -1,88 +0,0 @@ -package btools.routingapp; - -import java.io.File; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import android.app.Activity; -import android.app.ActivityManager; -import android.app.AlertDialog; -import android.app.Dialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.os.StatFs; -import android.speech.tts.TextToSpeech.OnInitListener; -import android.util.Log; -import android.view.KeyEvent; -import android.widget.EditText; - -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import androidx.core.os.EnvironmentCompat; - -import btools.router.OsmNodeNamed; - -public class BRouterMainActivity extends Activity implements OnInitListener, ActivityCompat.OnRequestPermissionsResultCallback -{ - - @Override - public void onInit( int i ) - { - } - - public boolean checkSelfPermission (Context context, String perm ) { - boolean b = checkSelfPermission(context, perm); - if (b) { - ActivityCompat.requestPermissions (this, new String[]{perm}, 0); - } - - return b; - } - - public String getStorageState(File f) { - return EnvironmentCompat.getStorageState(f); //Environment.MEDIA_MOUNTED - } - - public File[] getExternFilesDirs(String d) { - return getExternalFilesDirs(null); - } - - public ArrayList getStorageDirectories () { - ArrayList list = null; - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) { - list = new ArrayList(Arrays.asList(getExternalMediaDirs())); - } else { - list = new ArrayList(Arrays.asList(getExternFilesDirs(null))); - } - ArrayList res = new ArrayList(); - - for (File f : list) { - if (f != null) { - if (getStorageState(f).equals(Environment.MEDIA_MOUNTED)) - res.add (f); - } - } - -// res.add(getContext().getFilesDir()); - return res; - } - - -} - - diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java b/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java index 14a4470..8014d37 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BInstallerActivity.java @@ -12,6 +12,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; +import android.os.Build; import android.os.Bundle; import android.os.PowerManager; import android.os.PowerManager.WakeLock; @@ -19,7 +20,7 @@ import android.speech.tts.TextToSpeech.OnInitListener; import android.os.StatFs; import android.util.Log; -public class BInstallerActivity extends BInstallerMainActivity { +public class BInstallerActivity extends Activity { public static final String DOWNLOAD_ACTION = "btools.routingapp.download"; @@ -151,4 +152,14 @@ public class BInstallerActivity extends BInstallerMainActivity { } + static public long getAvailableSpace (String baseDir) { + StatFs stat = new StatFs(baseDir); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + return stat.getAvailableBlocksLong()*stat.getBlockSizeLong(); + } + else { + return stat.getAvailableBlocks()*stat.getBlockSize(); + } + } } 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 900dca4..f9e244a 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java @@ -33,9 +33,12 @@ import android.view.KeyEvent; import android.widget.EditText; +import androidx.core.app.ActivityCompat; +import androidx.core.os.EnvironmentCompat; + import btools.router.OsmNodeNamed; -public class BRouterActivity extends BRouterMainActivity { +public class BRouterActivity extends Activity { private static final int DIALOG_SELECTPROFILE_ID = 1; private static final int DIALOG_EXCEPTION_ID = 2; @@ -54,7 +57,7 @@ public class BRouterActivity extends BRouterMainActivity { private static final int DIALOG_SHOW_WP_SCANRESULT_ID = 15; private static final int DIALOG_SHOW_REPEAT_TIMEOUT_HELP_ID = 16; private static final int DIALOG_SHOW_API23_HELP_ID = 17; - + private BRouterView mBRouterView; private PowerManager mPowerManager; @@ -667,4 +670,62 @@ public class BRouterActivity extends BRouterMainActivity { mWakeLock.release(); } + public boolean checkSelfPermission (Context context, String perm ) { + boolean b = checkSelfPermission(context, perm); + if (b) { + ActivityCompat.requestPermissions (this, new String[]{perm}, 0); + } + + return b; + } + + private String getStorageState(File f) { + return EnvironmentCompat.getStorageState(f); //Environment.MEDIA_MOUNTED + } + + public ArrayList getStorageDirectories () { + ArrayList list = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + list = new ArrayList(Arrays.asList(getExternalMediaDirs())); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + list = new ArrayList(Arrays.asList(getExternalFilesDirs(null))); + } + ArrayList res = new ArrayList(); + + for (File f : list) { + if (f != null) { + if (getStorageState(f).equals(Environment.MEDIA_MOUNTED)) + res.add (f); + } + } + + if (checkExternalStorageWritable()) { + res.add(Environment.getExternalStorageDirectory()); + } + + return res; + } + + private boolean checkExternalStorageWritable() { + boolean isWritable = false; + 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(); + isWritable = true; + } + } + catch (Throwable t) { + // ignore + } + return isWritable; + } } diff --git a/brouter-routing-app/src/api19/java/btools/routingapp/NotificationHelper.java b/brouter-routing-app/src/main/java/btools/routingapp/NotificationHelper.java similarity index 100% rename from brouter-routing-app/src/api19/java/btools/routingapp/NotificationHelper.java rename to brouter-routing-app/src/main/java/btools/routingapp/NotificationHelper.java From 12148f6a5d3184c93de5a5f7a279360fe4e1c139 Mon Sep 17 00:00:00 2001 From: Manuel Fuhr Date: Thu, 21 Oct 2021 16:36:02 +0200 Subject: [PATCH 3/5] Request runtime permission for WRITE_EXTERNAL_STORAGE Originally implemented by Erlkoenig90 (#244) but lost during the api split. --- .../btools/routingapp/BRouterActivity.java | 22 ++++++++++--------- .../java/btools/routingapp/BRouterView.java | 7 ++++-- 2 files changed, 17 insertions(+), 12 deletions(-) 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 f9e244a..2424f88 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterActivity.java @@ -38,7 +38,7 @@ import androidx.core.os.EnvironmentCompat; import btools.router.OsmNodeNamed; -public class BRouterActivity extends Activity { +public class BRouterActivity extends Activity implements ActivityCompat.OnRequestPermissionsResultCallback { private static final int DIALOG_SELECTPROFILE_ID = 1; private static final int DIALOG_EXCEPTION_ID = 2; @@ -670,15 +670,6 @@ public class BRouterActivity extends Activity { mWakeLock.release(); } - public boolean checkSelfPermission (Context context, String perm ) { - boolean b = checkSelfPermission(context, perm); - if (b) { - ActivityCompat.requestPermissions (this, new String[]{perm}, 0); - } - - return b; - } - private String getStorageState(File f) { return EnvironmentCompat.getStorageState(f); //Environment.MEDIA_MOUNTED } @@ -728,4 +719,15 @@ public class BRouterActivity extends Activity { } return isWritable; } + + @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(); + } + } + } } 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 618b91d..dd39382 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java @@ -38,6 +38,9 @@ import android.view.View; import android.widget.Toast; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + import btools.expressions.BExpressionContextWay; import btools.expressions.BExpressionMetaData; import btools.mapaccess.OsmNode; @@ -176,9 +179,9 @@ public class BRouterView extends View } if ( !td.isDirectory() ) { - if ( ( (BRouterActivity) getContext() ).checkSelfPermission (getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) { - // if (ContextCompat.checkSelfPermission (getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) { + 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( ( (BRouterActivity) getContext() ).getStorageDirectories (), guessBaseDir(), "Cannot access " + baseDir.getAbsolutePath () + "; select another"); } From dc95984199bfad4b40e019bcc2ccb34d1a1ac455 Mon Sep 17 00:00:00 2001 From: Manuel Fuhr Date: Tue, 2 Nov 2021 17:24:50 +0100 Subject: [PATCH 4/5] Improve detection of sdcard write access This allows reading waypoints from apps on till devices running API 28 if they store their files in a accessible path (not Android/data). It even works for devices running API 30 if they installed it as an update. --- .../btools/routingapp/BRouterService.java | 22 ++++++++++------ .../java/btools/routingapp/BRouterView.java | 25 ++++++++++--------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java index 2389467..095beb4 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java @@ -17,13 +17,20 @@ import java.util.List; import java.util.zip.GZIPOutputStream; import java.util.ArrayList; +import android.Manifest; import android.app.Service; import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; import android.util.Base64; + +import androidx.core.content.ContextCompat; + import btools.router.OsmNodeNamed; public class BRouterService extends Service @@ -203,7 +210,13 @@ public class BRouterService extends Service // add nogos from waypoint database int deviceLevel = android.os.Build.VERSION.SDK_INT; int targetSdkVersion = getApplicationInfo().targetSdkVersion; - boolean canAccessSdCard = deviceLevel < 23 || targetSdkVersion == 19; + boolean canAccessSdCard = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) { + canAccessSdCard = false; + } + if (ContextCompat.checkSelfPermission(BRouterService.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + canAccessSdCard = false; + } AppLogger.log( "dev/target=" + deviceLevel + "/" + targetSdkVersion + " canAccessSdCard=" + canAccessSdCard ); if ( canAccessSdCard ) { @@ -211,18 +224,13 @@ public class BRouterService extends Service worker.nogoList = new ArrayList( cor.nogopoints ); worker.nogoPolygonsList = new ArrayList(); } - else if (deviceLevel >= android.os.Build.VERSION_CODES.Q) { + else { CoordinateReader cor = new CoordinateReaderInternal( baseDir ); cor.readFromTo(); worker.nogoList = new ArrayList( cor.nogopoints ); worker.nogoPolygonsList = new ArrayList(); } - else - { - worker.nogoList = new ArrayList(); - worker.nogoPolygonsList = new ArrayList(); - } } 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 dd39382..1bc0d44 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java @@ -222,20 +222,21 @@ public class BRouterView extends View waitingForMigration = false; } - int deviceLevel = android.os.Build.VERSION.SDK_INT; + int deviceLevel = Build.VERSION.SDK_INT; int targetSdkVersion = getContext().getApplicationInfo().targetSdkVersion; - canAccessSdCard = deviceLevel < 23 || targetSdkVersion == 19; - if ( canAccessSdCard ) - { - cor = CoordinateReader.obtainValidReader( basedir, segmentDir ); + canAccessSdCard = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !Environment.isExternalStorageLegacy()) { + canAccessSdCard = false; } - else - { - if (deviceLevel >= android.os.Build.VERSION_CODES.Q) { - cor = new CoordinateReaderInternal(basedir); - } else { - cor = new CoordinateReaderNone(); - } + if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + canAccessSdCard = false; + } + + if (canAccessSdCard) { + cor = CoordinateReader.obtainValidReader(basedir, segmentDir); + } + else { + cor = new CoordinateReaderInternal(basedir); cor.readFromTo(); } From db77728d4ce7a3c33dc4d2c0cdb6a1029bc9d4ac Mon Sep 17 00:00:00 2001 From: Manuel Fuhr Date: Sun, 7 Nov 2021 11:12:48 +0100 Subject: [PATCH 5/5] Always fallback to CoordinateReaderInternal --- .../btools/routingapp/BRouterService.java | 16 +-- .../java/btools/routingapp/BRouterView.java | 10 +- .../btools/routingapp/CoordinateReader.java | 104 +++++++++--------- .../routingapp/CoordinateReaderNone.java | 32 ------ 4 files changed, 54 insertions(+), 108 deletions(-) delete mode 100644 brouter-routing-app/src/main/java/btools/routingapp/CoordinateReaderNone.java diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java index 095beb4..52cade2 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterService.java @@ -218,20 +218,10 @@ public class BRouterService extends Service canAccessSdCard = false; } AppLogger.log( "dev/target=" + deviceLevel + "/" + targetSdkVersion + " canAccessSdCard=" + canAccessSdCard ); - if ( canAccessSdCard ) - { - CoordinateReader cor = CoordinateReader.obtainValidReader( baseDir, worker.segmentDir, true ); - worker.nogoList = new ArrayList( cor.nogopoints ); - worker.nogoPolygonsList = new ArrayList(); - } - else { - CoordinateReader cor = new CoordinateReaderInternal( baseDir ); - cor.readFromTo(); - - worker.nogoList = new ArrayList( cor.nogopoints ); - worker.nogoPolygonsList = new ArrayList(); - } + CoordinateReader cor = CoordinateReader.obtainValidReader( baseDir, worker.segmentDir, canAccessSdCard, true ); + worker.nogoList = new ArrayList( cor.nogopoints ); + worker.nogoPolygonsList = new ArrayList(); } 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 1bc0d44..ada010e 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java @@ -232,13 +232,7 @@ public class BRouterView extends View canAccessSdCard = false; } - if (canAccessSdCard) { - cor = CoordinateReader.obtainValidReader(basedir, segmentDir); - } - else { - cor = new CoordinateReaderInternal(basedir); - cor.readFromTo(); - } + cor = CoordinateReader.obtainValidReader(basedir, segmentDir, canAccessSdCard); wpList = cor.waypoints; nogoList = cor.nogopoints; @@ -586,7 +580,7 @@ public class BRouterView extends View for ( int i = 0; i < wpList.size(); i++ ) msg += ( i > 0 ? "->" : "" ) + wpList.get( i ).name; } - ( (BRouterActivity) getContext() ).showResultMessage( "Select Action", msg, cor instanceof CoordinateReaderNone ? -2 : wpList.size() ); + ( (BRouterActivity) getContext() ).showResultMessage( "Select Action", msg, wpList.size() ); return; } diff --git a/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java b/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java index 4926b70..a6b7942 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReader.java @@ -149,76 +149,70 @@ public abstract class CoordinateReader protected abstract void readPointmap() throws Exception; - public static CoordinateReader obtainValidReader( String basedir, File segmentDir ) throws Exception + public static CoordinateReader obtainValidReader( String basedir, File segmentDir, boolean canAccessSdCard ) throws Exception { - return obtainValidReader( basedir, segmentDir, false ); + return obtainValidReader( basedir, segmentDir, canAccessSdCard, false ); } - public static CoordinateReader obtainValidReader( String basedir, File segmentDir, boolean nogosOnly ) throws Exception + public static CoordinateReader obtainValidReader( String basedir, File segmentDir, boolean canAccessSdCard, boolean nogosOnly ) throws Exception { CoordinateReader cor = null; ArrayList rl = new ArrayList(); - AppLogger.log( "adding standard maptool-base: " + basedir ); - rl.add( new CoordinateReaderOsmAnd( basedir ) ); - rl.add( new CoordinateReaderLocus( basedir ) ); - rl.add( new CoordinateReaderOrux( basedir ) ); + if (canAccessSdCard) { + AppLogger.log("adding standard maptool-base: " + basedir); + rl.add(new CoordinateReaderOsmAnd(basedir)); + rl.add(new CoordinateReaderLocus(basedir)); + rl.add(new CoordinateReaderOrux(basedir)); - // eventually add standard-sd - File standardbase = Environment.getExternalStorageDirectory(); - if ( standardbase != null ) - { - String base2 = standardbase.getAbsolutePath(); - if ( !base2.equals( basedir ) ) - { - AppLogger.log( "adding internal sd maptool-base: " + base2 ); - rl.add( new CoordinateReaderOsmAnd( base2 ) ); - rl.add( new CoordinateReaderLocus( base2 ) ); - rl.add( new CoordinateReaderOrux( base2 ) ); - } - } - - // eventually add explicit directory - File additional = RoutingHelper.getAdditionalMaptoolDir( segmentDir ); - if ( additional != null ) - { - String base3 = additional.getAbsolutePath(); - - AppLogger.log( "adding maptool-base from storage-config: " + base3 ); - - rl.add( new CoordinateReaderOsmAnd( base3 ) ); - rl.add( new CoordinateReaderOsmAnd( base3, true ) ); - rl.add( new CoordinateReaderLocus( base3 ) ); - rl.add( new CoordinateReaderOrux( base3 ) ); - } - - long tmax = 0; - for ( CoordinateReader r : rl ) - { - if ( AppLogger.isLogging() ) - { - AppLogger.log( "reading timestamp at systime " + new Date() ); - } - - long t = r.getTimeStamp(); - - if ( t != 0 ) - { - if ( AppLogger.isLogging() ) - { - AppLogger.log( "found coordinate source at " + r.basedir + r.rootdir + " with timestamp " + new Date( t ) ); + // eventually add standard-sd + File standardbase = Environment.getExternalStorageDirectory(); + if (standardbase != null) { + String base2 = standardbase.getAbsolutePath(); + if (!base2.equals(basedir)) { + AppLogger.log("adding internal sd maptool-base: " + base2); + rl.add(new CoordinateReaderOsmAnd(base2)); + rl.add(new CoordinateReaderLocus(base2)); + rl.add(new CoordinateReaderOrux(base2)); } } - if ( t > tmax ) - { - tmax = t; - cor = r; + // eventually add explicit directory + File additional = RoutingHelper.getAdditionalMaptoolDir(segmentDir); + if (additional != null) { + String base3 = additional.getAbsolutePath(); + + AppLogger.log("adding maptool-base from storage-config: " + base3); + + rl.add(new CoordinateReaderOsmAnd(base3)); + rl.add(new CoordinateReaderOsmAnd(base3, true)); + rl.add(new CoordinateReaderLocus(base3)); + rl.add(new CoordinateReaderOrux(base3)); + } + + long tmax = 0; + for (CoordinateReader r : rl) { + if (AppLogger.isLogging()) { + AppLogger.log("reading timestamp at systime " + new Date()); + } + + long t = r.getTimeStamp(); + + if (t != 0) { + if (AppLogger.isLogging()) { + AppLogger.log("found coordinate source at " + r.basedir + r.rootdir + " with timestamp " + new Date(t)); + } + } + + if (t > tmax) { + tmax = t; + cor = r; + } } } if ( cor == null ) { - cor = new CoordinateReaderNone(); + cor = new CoordinateReaderInternal(basedir); } cor.nogosOnly = nogosOnly; cor.readFromTo(); diff --git a/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReaderNone.java b/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReaderNone.java deleted file mode 100644 index 1b8d8be..0000000 --- a/brouter-routing-app/src/main/java/btools/routingapp/CoordinateReaderNone.java +++ /dev/null @@ -1,32 +0,0 @@ -package btools.routingapp; - - -/** - * Dummy coordinate reader if none found - */ -public class CoordinateReaderNone extends CoordinateReader -{ - public CoordinateReaderNone() - { - super( "" ); - rootdir = "none"; - } - - @Override - public long getTimeStamp() throws Exception - { - return 0L; - } - - @Override - public int getTurnInstructionMode() - { - return 0; // none - } - - @Override - public void readPointmap() throws Exception - { - } - -}