diff --git a/Android app/app/build.gradle b/Android app/app/build.gradle index 4db2325..de39a65 100755 --- a/Android app/app/build.gradle +++ b/Android app/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "com.schlmgr" minSdkVersion 19 targetSdkVersion 32 - versionCode 58 - versionName '1.7.0' + versionCode 59 + versionName '1.8.0' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" signingConfig signingConfigs.debug } diff --git a/Android app/app/libs/SMLib.jar b/Android app/app/libs/SMLib.jar index 32cf8f6..86859b8 100644 Binary files a/Android app/app/libs/SMLib.jar and b/Android app/app/libs/SMLib.jar differ diff --git a/Android app/app/libs/SMLib.zip b/Android app/app/libs/SMLib.zip index c12f19f..566bb1c 100644 Binary files a/Android app/app/libs/SMLib.zip and b/Android app/app/libs/SMLib.zip differ diff --git a/Android app/app/src/main/java/com/schlmgr/gui/AndroidIOSystem.java b/Android app/app/src/main/java/com/schlmgr/gui/AndroidIOSystem.java index ae29681..e2178c9 100755 --- a/Android app/app/src/main/java/com/schlmgr/gui/AndroidIOSystem.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/AndroidIOSystem.java @@ -51,7 +51,7 @@ public class AndroidIOSystem extends Formatter.IOSystem { private static AndroidIOSystem ios; public static boolean canWrite() { - if (!canWrite && VERSION.SDK_INT >= 23 && PERMISSION_GRANTED != + if (!canWrite && VERSION.SDK_INT >= 23 && VERSION.SDK_INT < 30 && PERMISSION_GRANTED != ContextCompat.checkSelfPermission(CONTEXT, permission.WRITE_EXTERNAL_STORAGE)) { activity.requestPermissions (new String[]{permission.WRITE_EXTERNAL_STORAGE}, STORAGE_PERMISSION); @@ -67,8 +67,8 @@ public static boolean canWrite() { public static boolean testWrite() { if (!canWrite) { - if (VERSION.SDK_INT >= 23 && PERMISSION_GRANTED != ContextCompat.checkSelfPermission( - CONTEXT, permission.WRITE_EXTERNAL_STORAGE)) return false; + if (VERSION.SDK_INT >= 23 && VERSION.SDK_INT < 30 && PERMISSION_GRANTED != ContextCompat + .checkSelfPermission(CONTEXT, permission.WRITE_EXTERNAL_STORAGE)) return false; else return canWrite = true; } else return true; } @@ -128,17 +128,15 @@ protected void setDefaults(boolean first) { settings.put("parseNames", true); settings.put("version", BuildConfig.VERSION_CODE); } else { - Object value; - if ((value = settings.get("version")) == null //old version update compatibility ensure - || BuildConfig.VERSION_CODE > (Integer) value) { - int lastVersion = (Integer) value; - /*0if (lastVersion < 30) { + int version; + if ((version = (Integer) settings.get("version")) < BuildConfig.VERSION_CODE) { + /*if (version < 30) { defaultReacts.put("removeSchNames", moreInfo -> { for (MainChapter mch : MainChapter.ELEMENTS) mch.removeSetting("schNameCount"); }); } - if (lastVersion < 36) settings.put("doChoosePos", false); - if (lastVersion < 40) settings.put("doShowDesc", false);*/ + if (version < 36) settings.put("doChoosePos", false); + if (version < 40) settings.put("doShowDesc", false);*/ settings.put("version", BuildConfig.VERSION_CODE); } @@ -258,8 +256,8 @@ public GeneralPath createGeneralPath(Object path) { @Override public GeneralPath createGeneralPath(Object path, boolean internal) { - return path instanceof Uri ? new UriPath((Uri) path, internal) : path instanceof DocumentFile ? + return path instanceof Uri ? null : path instanceof DocumentFile ? new UriPath((DocumentFile) path, internal) : !(path instanceof File) && path.toString().contains(":") - ? new UriPath(path.toString(), internal) : super.createGeneralPath(path, internal); + ? new UriPath(path.toString()) : super.createGeneralPath(path, internal); } } diff --git a/Android app/app/src/main/java/com/schlmgr/gui/CurrentData.java b/Android app/app/src/main/java/com/schlmgr/gui/CurrentData.java index 0c9a9b1..998446b 100755 --- a/Android app/app/src/main/java/com/schlmgr/gui/CurrentData.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/CurrentData.java @@ -163,25 +163,21 @@ public void dismiss(boolean forever) { }, "uncaughtShower").start(); synchronized (toLoad) { boolean thread = false; - for (MainChapter mch : toLoad) { - if (mch.isEmpty(null)) try { - mch.load(thread = !thread); - } catch (Exception e) { - } - } + for (MainChapter mch : toLoad) mch.load(thread = !thread); toLoad.clear(); } } public static void createMchs() { synchronized (toLoad) { - if (Formatter.getSubjectsDir().listFiles() != null) for (GeneralPath f : Formatter.getSubjectsDir().listFiles()) - load:{ - for (MainChapter mch : MainChapter.ELEMENTS) - if (mch.getDir().equals(f)) break load; - if (f.getChild("setts.dat").exists()) - toLoad.add(new MainChapter(new Data(f.getName(), null))); - } + if (Formatter.getSubjectsDir().listFiles() != null) + for (GeneralPath f : Formatter.getSubjectsDir().listFiles()) + load:{ + for (MainChapter mch : MainChapter.ELEMENTS) + if (mch.getDir().equals(f)) break load; + if (f.getChild("setts.dat").exists()) + toLoad.add(new MainChapter(new Data(f.getName(), null))); + } for (GeneralPath f : ImportedMchs.get()) load:{ for (MainChapter mch : MainChapter.ELEMENTS) diff --git a/Android app/app/src/main/java/com/schlmgr/gui/UriPath.java b/Android app/app/src/main/java/com/schlmgr/gui/UriPath.java index 3faf64f..ce6bed6 100644 --- a/Android app/app/src/main/java/com/schlmgr/gui/UriPath.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/UriPath.java @@ -1,5 +1,6 @@ package com.schlmgr.gui; +import android.content.Intent; import android.net.Uri; import android.webkit.MimeTypeMap; @@ -11,6 +12,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; +import java.util.Arrays; import IOSystem.FilePath; import IOSystem.Formatter.IOSystem.GeneralPath; @@ -25,11 +27,7 @@ public class UriPath implements GeneralPath { private final boolean internal; public UriPath(String original) { - this(original, false); - } - - public UriPath(String original, boolean internal) { - this(Uri.parse(original), internal); + this(Uri.parse(original), true); } public UriPath(DocumentFile file) { @@ -42,17 +40,14 @@ public UriPath(DocumentFile file, boolean internal) { this.internal = internal; } - public UriPath(Uri uri) { - this(uri, false); - } - - public UriPath(Uri uri, boolean internal) { + /** + * Use only for folders obtained using Intent.ACTION_OPEN_DOCUMENT_TREE + */ + public UriPath(Uri uri, boolean folder) { this.uri = uri; original = uri.toString(); - if (uri.toString().startsWith("file://")) - file = DocumentFile.fromTreeUri(CONTEXT, uri); - else file = DocumentFile.fromSingleUri(CONTEXT, uri); - this.internal = internal; + file = folder ? DocumentFile.fromTreeUri(CONTEXT, uri) : DocumentFile.fromSingleUri(CONTEXT, uri); + this.internal = false; } @Override @@ -65,10 +60,6 @@ public String getName() { return file.getName(); } - public Uri getUri() { - return uri; - } - public DocumentFile getDocumentFile() { return file; } @@ -159,10 +150,12 @@ public boolean equals(GeneralPath filePath) { @Override public UriPath[] listFiles() { - DocumentFile[] files = file.listFiles(); - UriPath[] paths = new UriPath[files.length]; - for (int i = 0; i < files.length; i++) paths[i] = new UriPath(files[i]); - return paths; + if (file.isDirectory()) { + DocumentFile[] files = file.listFiles(); + UriPath[] paths = new UriPath[files.length]; + for (int i = 0; i < files.length; i++) paths[i] = new UriPath(files[i]); + return paths; + } else return null; } @Override diff --git a/Android app/app/src/main/java/com/schlmgr/gui/activity/MainActivity.java b/Android app/app/src/main/java/com/schlmgr/gui/activity/MainActivity.java index f1544c2..52361f7 100755 --- a/Android app/app/src/main/java/com/schlmgr/gui/activity/MainActivity.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/activity/MainActivity.java @@ -98,21 +98,6 @@ public void onCreate(Bundle savedInstanceState) { new AndroidIOSystem(); AndroidIOSystem.testWrite(); (background = new Thread(() -> { - if (!Formatter.getSubjectsDir().getOriginalName().contains(defDir - + "/Android/data/com.schlmgr") && !AndroidIOSystem.canWrite()) { - runOnUiThread(() -> { - Toast.makeText(this, getString(R.string.fail_permission_write) - + AndroidIOSystem.visibleInternalPath(Formatter.getSubjectsDir().getOriginalName()) - + '\n' + getString(R.string.fail_formatter), Toast.LENGTH_LONG).show(); - Formatter.resetDir(); - CurrentData.createMchs(); - MainFragment.VS.mfInstance.setContent(null, null, 0); - loaded = true; - }); - } else { - loaded = true; - CurrentData.createMchs(); - } try { while (true) { Thread.sleep(100_000); @@ -123,6 +108,20 @@ public void onCreate(Bundle savedInstanceState) { } catch (Exception e) { } }, "MA background")).start(); + if (!Formatter.getSubjectsDir().getOriginalName().contains(defDir + + "/Android/data/com.schlmgr") && !AndroidIOSystem.canWrite() || + !Formatter.getSubjectsDir().exists()) { + Toast.makeText(this, getString(R.string.fail_permission_write) + + AndroidIOSystem.visibleInternalPath(Formatter.getSubjectsDir().getOriginalName()) + + '\n' + getString(R.string.fail_formatter), Toast.LENGTH_LONG).show(); + Formatter.resetDir(); + CurrentData.createMchs(); + MainFragment.VS.mfInstance.setContent(null, null, 0); + loaded = true; + } else { + CurrentData.createMchs(); + loaded = true; + } } } diff --git a/Android app/app/src/main/java/com/schlmgr/gui/activity/SelectDirActivity.java b/Android app/app/src/main/java/com/schlmgr/gui/activity/SelectDirActivity.java index ecf166c..1e70303 100755 --- a/Android app/app/src/main/java/com/schlmgr/gui/activity/SelectDirActivity.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/activity/SelectDirActivity.java @@ -63,7 +63,8 @@ public class SelectDirActivity extends PopupCareActivity @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (VERSION.SDK_INT >= 29) { + context = getApplicationContext(); + if (VERSION.SDK_INT >= 30) { Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); startActivityForResult(Intent.createChooser(i, activity.getString(R.string.action_chooser_dir)), GET_DIR); @@ -116,7 +117,6 @@ public void onCreate(Bundle savedInstanceState) { } }); } - context = getApplicationContext(); path_handler = findViewById(R.id.dir_path_handler); path = findViewById(R.id.dir_path); list = findViewById(R.id.dir_list); @@ -292,25 +292,32 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { new Thread(() -> { if (requestCode == GET_DIR) { Uri path = data.getData(); - CONTEXT.grantUriPermission(CONTEXT.getPackageName(), path, Intent - .FLAG_GRANT_READ_URI_PERMISSION | Intent - .FLAG_GRANT_WRITE_URI_PERMISSION); CONTEXT.getContentResolver().takePersistableUriPermission(path, Intent .FLAG_GRANT_READ_URI_PERMISSION | Intent .FLAG_GRANT_WRITE_URI_PERMISSION); - DocumentFile dir = DocumentFile.fromTreeUri(CONTEXT, data.getData()); - if (Formatter.changeDir(new UriPath(dir))) { - MainFragment.VS = new MainFragment.ViewState(); - backLog.clear(); + UriPath file = new UriPath(path, true); + if (importing) { + if (file.getChild("main.json") != null && file.getChild("setts.dat") != null) + CurrentData.ImportedMchs.importMch(file); CurrentData.createMchs(); - runOnUiThread(() -> Toast.makeText( - context, getString(R.string.choose_dir), Toast.LENGTH_SHORT).show()); + if (backLog.path.isEmpty()) MainFragment.VS.mfInstance.setContent(null, null, 0); + } else { + if (Formatter.changeDir(file)) { + MainFragment.VS = new MainFragment.ViewState(); + backLog.clear(); + CurrentData.createMchs(); + runOnUiThread(() -> Toast.makeText( + context, getString(R.string.choose_dir), Toast.LENGTH_SHORT).show()); + } else runOnUiThread(() -> Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show()); } } super.onActivityResult(requestCode, resultCode, data); }, "DirAct onActivityResult").start(); } - super.onBackPressed(); + super. + + onBackPressed(); + } private static final int GET_DIR = 7; diff --git a/Android app/app/src/main/java/com/schlmgr/gui/fragments/MainFragment.java b/Android app/app/src/main/java/com/schlmgr/gui/fragments/MainFragment.java index d42a72e..f2ea2c6 100755 --- a/Android app/app/src/main/java/com/schlmgr/gui/fragments/MainFragment.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/fragments/MainFragment.java @@ -905,7 +905,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { List currentPath = (List) backLog.path.clone(); Container self = (Container) backLog.path.get(-1), par = (Container) backLog.path.get(-2); - SimpleReader content = new SimpleReader(new UriPath(data.getData()).load(), self, par); + SimpleReader content = new SimpleReader(new UriPath(data.getData(), false).load(), self, par); if (backLog.adapter instanceof HierarchyAdapter) { HierarchyAdapter ha = (HierarchyAdapter) backLog.adapter; int old = ha.list.size(); @@ -924,7 +924,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { break; case WORD_WRITE: if (VS.contentAdapter.selected < 1) { - new SimpleWriter(new UriPath(data.getData()), new Container[]{ + new SimpleWriter(new UriPath(data.getData(), false), new Container[]{ (Container) backLog.path.get(-1), (Container) backLog.path.get(-2)}); break; } @@ -937,17 +937,17 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { } VS.contentAdapter.selected = -1; setSelectOpts(false); - new SimpleWriter(new UriPath(data.getData()), toExport); + new SimpleWriter(new UriPath(data.getData(), false), toExport); break; case IMAGE_PICK: defaultReacts.get("NotifyNewImage") - .react(new UriPath(data.getData())); + .react(new UriPath(data.getData(), false)); break; case SCH_READ: try { List currentPath = (List) backLog.path.clone(); ((Container) backLog.path.get(-1)).putChild((Container) backLog.path.get(-2), - new ContentReader(new UriPath(data.getData()).load(), (MainChapter) backLog.path.get(0)) + new ContentReader(new UriPath(data.getData(), false).load(), (MainChapter) backLog.path.get(0)) .mContent.getItem((Container) backLog.path.get(-1))); CurrentData.save(currentPath); } catch (Exception e) { diff --git a/Android app/app/src/main/java/com/schlmgr/gui/list/ImageItemModel.java b/Android app/app/src/main/java/com/schlmgr/gui/list/ImageItemModel.java index fbeea9b..b89c114 100755 --- a/Android app/app/src/main/java/com/schlmgr/gui/list/ImageItemModel.java +++ b/Android app/app/src/main/java/com/schlmgr/gui/list/ImageItemModel.java @@ -77,9 +77,7 @@ public static Bitmap getScaledBitmap(GeneralPath path, float maxSize, boolean bi Options opts = new Options(); opts.inJustDecodeBounds = true; try { - if (path instanceof UriPath) BitmapFactory.decodeStream( - CONTEXT.getContentResolver().openInputStream( - ((UriPath) path).getUri())); + if (path instanceof UriPath) BitmapFactory.decodeStream(((UriPath) path).createInputStream()); else BitmapFactory.decodeFile(path.getOriginalName()); } catch (IOException e) { throw new IllegalArgumentException(e); @@ -87,9 +85,7 @@ public static Bitmap getScaledBitmap(GeneralPath path, float maxSize, boolean bi float ratio = (opts.outHeight > opts.outWidth != bigger ? opts.outHeight : opts.outWidth) / maxSize; if (ratio <= 1) try { - return path instanceof UriPath ? BitmapFactory.decodeStream( - CONTEXT.getContentResolver().openInputStream( - ((UriPath) path).getUri())) : + return path instanceof UriPath ? BitmapFactory.decodeStream(((UriPath) path).createInputStream()) : BitmapFactory.decodeFile(path.getOriginalName()); } catch (IOException e) { throw new IllegalArgumentException(e); @@ -98,8 +94,7 @@ public static Bitmap getScaledBitmap(GeneralPath path, float maxSize, boolean bi opts.inJustDecodeBounds = false; try { return path instanceof UriPath ? BitmapFactory.decodeStream( - CONTEXT.getContentResolver().openInputStream( - ((UriPath) path).getUri()), null, opts) : + ((UriPath) path).createInputStream(), null, opts) : BitmapFactory.decodeFile(path.getOriginalName(), opts); } catch (IOException e) { throw new IllegalArgumentException(e); diff --git a/Library/src/IOSystem/Formatter.java b/Library/src/IOSystem/Formatter.java index 696cccb..1687176 100644 --- a/Library/src/IOSystem/Formatter.java +++ b/Library/src/IOSystem/Formatter.java @@ -201,7 +201,7 @@ protected IOSystem(Object setts) { if ((value = settings.get("exportWordSplit")) != null) { SimpleWriter.setWordSplitter((String) value); } else { - settings.put("exportWordSplit", 1); + settings.put("exportWordSplit", SimpleWriter.wordSplitter); } setDefaults(false); } catch (Exception e) { diff --git a/SchoolManager.apk b/SchoolManager.apk index 20a0849..a19ba42 100644 Binary files a/SchoolManager.apk and b/SchoolManager.apk differ