@@ -107,6 +107,7 @@ public class MainActivity extends NativeActivity {
107107 private MediaPlayer _mediaPlayer = null ;
108108 private LocationAdapter _locationAdapter = null ;
109109 private TextToSpeechAdapter _tts ;
110+ private Storage _storage ;
110111
111112 static {
112113 System .loadLibrary ("smallbasic" );
@@ -254,18 +255,6 @@ public void run() {
254255 return result ;
255256 }
256257
257- public String getExternalStorage () {
258- String result = null ;
259- File files = getExternalFilesDir (null );
260- if (files != null ) {
261- String externalFiles = files .getAbsolutePath ();
262- if (isPublicStorage (externalFiles )) {
263- result = externalFiles ;
264- }
265- }
266- return result ;
267- }
268-
269258 public String getIpAddress () {
270259 String result = "" ;
271260 try {
@@ -291,7 +280,7 @@ public String getIpAddress() {
291280 @ SuppressLint ("MissingPermission" )
292281 public String getLocation () {
293282 StringBuilder result = new StringBuilder ("{" );
294- if (permitted ( Manifest . permission . ACCESS_FINE_LOCATION )) {
283+ if (locationPermitted ( )) {
295284 LocationManager locationService = (LocationManager ) getSystemService (Context .LOCATION_SERVICE );
296285 Location location = _locationAdapter != null ? _locationAdapter .getLocation () : null ;
297286 if (locationService != null ) {
@@ -485,7 +474,7 @@ public boolean removeLocationUpdates() {
485474 public boolean requestLocationUpdates () {
486475 final LocationManager locationService = (LocationManager ) getSystemService (Context .LOCATION_SERVICE );
487476 boolean result = false ;
488- if (!permitted ( Manifest . permission . ACCESS_FINE_LOCATION )) {
477+ if (!locationPermitted ( )) {
489478 checkPermission (Manifest .permission .ACCESS_FINE_LOCATION , REQUEST_LOCATION_PERMISSION );
490479 } else if (locationService != null ) {
491480 final Criteria criteria = new Criteria ();
@@ -641,11 +630,11 @@ public void speak(final byte[] textBytes) {
641630 @ Override
642631 protected void onCreate (Bundle savedInstanceState ) {
643632 super .onCreate (savedInstanceState );
644- String homeFolder = setupStorageEnvironment ();
633+ setupStorageEnvironment ();
645634 if (!libraryMode ()) {
646635 processIntent ();
647636 processSettings ();
648- installSamples (homeFolder );
637+ installSamples ();
649638 }
650639 }
651640
@@ -728,7 +717,7 @@ private void execScheme(final String data) {
728717 }
729718
730719 private void execStream (InputStream inputStream ) throws IOException {
731- File outputFile = new File (getInternalStorage (), WEB_BAS );
720+ File outputFile = new File (_storage . getInternal (), WEB_BAS );
732721 BufferedWriter output = new BufferedWriter (new FileWriter (outputFile ));
733722 Log .i (TAG , "execStream() entered" );
734723 String line = readLine (inputStream );
@@ -741,39 +730,6 @@ private void execStream(InputStream inputStream) throws IOException {
741730 runFile (outputFile .getAbsolutePath ());
742731 }
743732
744- private String getInternalStorage () {
745- return getFilesDir ().getAbsolutePath ();
746- }
747-
748- private String getLegacyStorage () {
749- String result ;
750- String path = Environment .getExternalStorageDirectory ().getAbsolutePath ();
751- if (isPublicStorage (path )) {
752- File sb = new File (path , FOLDER_NAME );
753- if ((sb .isDirectory () && sb .canWrite ()) || sb .mkdirs ()) {
754- result = path + "/" + FOLDER_NAME ;
755- } else {
756- result = path ;
757- }
758- } else {
759- result = null ;
760- }
761- return result ;
762- }
763-
764- private String getMediaStorage () {
765- String result = null ;
766- if (android .os .Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
767- // https://commonsware.com/blog/2019/06/07/death-external-storage-end-saga.html
768- File [] dirs = getExternalMediaDirs ();
769- String path = dirs != null && dirs .length > 0 ? dirs [0 ].getAbsolutePath () : null ;
770- if (isPublicStorage (path )) {
771- result = path ;
772- }
773- }
774- return result ;
775- }
776-
777733 private Uri getSharedFile (File file ) {
778734 Uri result ;
779735 try {
@@ -800,7 +756,8 @@ private String getString(final byte[] bytes) {
800756 }
801757 }
802758
803- private void installSamples (String toDir ) {
759+ private void installSamples () {
760+ String toDir = _storage .getExternal ();
804761 File [] toFiles = new File (toDir ).listFiles (new BasFileFilter ());
805762 if (toFiles == null || toFiles .length == 0 ) {
806763 // only attempt with a clean destination folder
@@ -814,18 +771,8 @@ private void installSamples(String toDir) {
814771 }
815772 }
816773
817- private boolean isPublicStorage (String dir ) {
818- boolean result ;
819- if (dir == null || dir .isEmpty ()) {
820- result = false ;
821- } else {
822- File file = new File (dir );
823- result = file .isDirectory () && file .canRead () && file .canWrite ();
824- }
825- return result ;
826- }
827-
828- private boolean permitted (String permission ) {
774+ private boolean locationPermitted () {
775+ String permission = Manifest .permission .ACCESS_FINE_LOCATION ;
829776 return (ContextCompat .checkSelfPermission (this , permission ) == PackageManager .PERMISSION_GRANTED );
830777 }
831778
@@ -902,25 +849,18 @@ private String readLine(InputStream inputReader) throws IOException {
902849 }
903850
904851 private String saveSchemeData (final String buffer ) throws IOException {
905- File outputFile = new File (getInternalStorage (), SCHEME_BAS );
852+ File outputFile = new File (_storage . getInternal (), SCHEME_BAS );
906853 BufferedWriter output = new BufferedWriter (new FileWriter (outputFile ));
907854 output .write (buffer );
908855 output .close ();
909856 return outputFile .getAbsolutePath ();
910857 }
911858
912- private String setupStorageEnvironment () {
913- setenv ("INTERNAL_DIR" , getInternalStorage ());
914- setenv ("LEGACY_DIR" , getMediaStorage ());
915- String legacyStorage = getLegacyStorage ();
916- String externalStorage ;
917- if (isPublicStorage (legacyStorage )) {
918- externalStorage = legacyStorage ;
919- } else {
920- externalStorage = getExternalStorage ();
921- }
922- setenv ("EXTERNAL_DIR" , externalStorage );
923- return externalStorage ;
859+ private void setupStorageEnvironment () {
860+ _storage = new Storage ();
861+ setenv ("EXTERNAL_DIR" , _storage .getExternal ());
862+ setenv ("INTERNAL_DIR" , _storage .getInternal ());
863+ setenv ("LEGACY_DIR" , _storage .getMedia ());
924864 }
925865
926866 private static class BasFileFilter implements FilenameFilter {
@@ -930,6 +870,71 @@ public boolean accept(File dir, String name) {
930870 }
931871 }
932872
873+ private final class Storage {
874+ private final String _external ;
875+ private final String _internal ;
876+ private final String _media ;
877+
878+ private Storage () {
879+ String external = null ;
880+ String media = null ;
881+
882+ String path = Environment .getExternalStorageDirectory ().getAbsolutePath ();
883+ if (isPublicStorage (path )) {
884+ File sb = new File (path , FOLDER_NAME );
885+ if ((sb .isDirectory () && sb .canWrite ()) || sb .mkdirs ()) {
886+ external = path + "/" + FOLDER_NAME ;
887+ }
888+ }
889+
890+ if (external == null ) {
891+ File files = getExternalFilesDir (null );
892+ if (files != null ) {
893+ String externalFiles = files .getAbsolutePath ();
894+ if (isPublicStorage (externalFiles )) {
895+ external = externalFiles ;
896+ }
897+ }
898+ }
899+
900+ if (android .os .Build .VERSION .SDK_INT >= Build .VERSION_CODES .LOLLIPOP ) {
901+ // https://commonsware.com/blog/2019/06/07/death-external-storage-end-saga.html
902+ File [] dirs = getExternalMediaDirs ();
903+ path = dirs != null && dirs .length > 0 ? dirs [0 ].getAbsolutePath () : null ;
904+ if (isPublicStorage (path )) {
905+ media = path ;
906+ }
907+ }
908+
909+ this ._external = external ;
910+ this ._internal = getFilesDir ().getAbsolutePath ();
911+ this ._media = media ;
912+ }
913+
914+ public String getExternal () {
915+ return _external ;
916+ }
917+
918+ public String getInternal () {
919+ return _internal ;
920+ }
921+
922+ public String getMedia () {
923+ return _media ;
924+ }
925+
926+ private boolean isPublicStorage (String dir ) {
927+ boolean result ;
928+ if (dir == null || dir .isEmpty ()) {
929+ result = false ;
930+ } else {
931+ File file = new File (dir );
932+ result = file .isDirectory () && file .canRead () && file .canWrite ();
933+ }
934+ return result ;
935+ }
936+ }
937+
933938 private class WebServerImpl extends WebServer {
934939 private final Map <String , Long > fileLengths = new HashMap <>();
935940
@@ -947,12 +952,12 @@ protected Response getFile(String path, boolean asset) throws IOException {
947952 log ("Opened " + name + " " + length + " bytes" );
948953 result = new Response (getAssets ().open (name ), length );
949954 } else {
950- File file = getFile (getExternalStorage (), path );
955+ File file = getFile (_storage . getExternal (), path );
951956 if (file == null ) {
952- file = getFile (getMediaStorage (), path );
957+ file = getFile (_storage . getMedia (), path );
953958 }
954959 if (file == null ) {
955- file = getFile (getInternalStorage (), path );
960+ file = getFile (_storage . getInternal (), path );
956961 }
957962 if (file != null ) {
958963 result = new Response (new FileInputStream (file ), file .length ());
@@ -966,9 +971,9 @@ protected Response getFile(String path, boolean asset) throws IOException {
966971 @ Override
967972 protected Collection <FileData > getFileData () throws IOException {
968973 Collection <FileData > result = new ArrayList <>();
969- result .addAll (getFiles (new File (getExternalStorage ())));
970- result .addAll (getFiles (new File (getMediaStorage ())));
971- result .addAll (getFiles (new File (getInternalStorage ())));
974+ result .addAll (getFiles (new File (_storage . getExternal ())));
975+ result .addAll (getFiles (new File (_storage . getMedia ())));
976+ result .addAll (getFiles (new File (_storage . getInternal ())));
972977 return result ;
973978 }
974979
@@ -987,31 +992,31 @@ protected void renameFile(String from, String to) throws IOException {
987992 if (to == null || !to .endsWith (".bas" )) {
988993 throw new IOException ("Invalid file name: " + to );
989994 }
990- File toFile = getFile (getInternalStorage (), to );
995+ File toFile = getFile (_storage . getInternal (), to );
991996 if (toFile == null ) {
992- toFile = getFile (getExternalStorage (), to );
997+ toFile = getFile (_storage . getExternal (), to );
993998 }
994999 if (toFile != null ) {
9951000 throw new IOException ("File already exists" );
9961001 }
997- File fromFile = getFile (getInternalStorage (), from );
1002+ File fromFile = getFile (_storage . getInternal (), from );
9981003 if (fromFile == null ) {
999- fromFile = getFile (getExternalStorage (), from );
1004+ fromFile = getFile (_storage . getExternal (), from );
10001005 }
10011006 if (fromFile == null ) {
1002- fromFile = getFile (getInternalStorage (), from );
1007+ fromFile = getFile (_storage . getInternal (), from );
10031008 }
10041009 if (fromFile == null ) {
10051010 throw new IOException ("Previous file does not exist" );
10061011 }
1007- if (!fromFile .renameTo (new File (getExternalStorage (), to ))) {
1012+ if (!fromFile .renameTo (new File (_storage . getExternal (), to ))) {
10081013 throw new IOException ("File rename failed" );
10091014 }
10101015 }
10111016
10121017 @ Override
10131018 protected void saveFile (String fileName , byte [] content ) throws IOException {
1014- File file = new File (getExternalStorage (), fileName );
1019+ File file = new File (_storage . getExternal (), fileName );
10151020 if (file .exists ()) {
10161021 throw new IOException ("File already exists: " + fileName );
10171022 } else if (file .isDirectory ()) {
0 commit comments