From 97382965da97bf118d99ac70bfba0df138d398f8 Mon Sep 17 00:00:00 2001
From: hyb1996 <946994919@qq.com>
Date: Tue, 28 Nov 2017 20:59:29 +0800
Subject: [PATCH] add: supports for daily task and disposable task
---
LICENSE.md | 4 +-
app/src/main/AndroidManifest.xml | 2 +
app/src/main/assets/docs/util.html | 6 +-
.../assets/editor/codemirror/CHANGELOG.md | 6 +-
.../java/com/stardust/scriptdroid/App.java | 10 +-
.../scriptdroid/external/ScriptIntents.java | 2 +-
.../external/tasker/TaskPrefEditActivity.java | 2 +-
.../widget/ScriptWidgetSettingsActivity.java | 2 +-
.../scriptdroid/model/script/Scripts.java | 2 +-
.../DevPluginResponseHandler.java | 2 +-
.../storage/database/ModelChange.java | 34 +++
.../database}/TimedTaskDatabase.java | 2 +-
.../file}/SampleFileProvider.java | 2 +-
.../file}/StorageFileProvider.java | 2 +-
.../{io => storage/file}/TmpScriptFiles.java | 3 +-
.../scriptdroid/timing/TaskReceiver.java | 1 +
.../scriptdroid/timing/TimedTask.java | 128 ++++++++--
.../scriptdroid/timing/TimedTaskManager.java | 81 +++++-
.../timing/TimedTaskScheduler.java | 8 +-
.../scriptdroid/ui/build/BuildActivity.java | 11 +-
.../ui/common/ScriptOperations.java | 12 +-
.../filechooser/FileChooserDialogBuilder.java | 2 +-
.../scriptdroid/ui/floating/CircularMenu.java | 5 +-
.../scriptdroid/ui/main/MainActivity.java | 2 +-
.../ui/main/community/CommunityWebView.java | 2 +-
.../ui/main/sample/SampleListFragment.java | 8 +-
.../ui/main/sample/SampleListView.java | 3 +-
.../ui/main/scripts/MyScriptListFragment.java | 4 +-
.../ui/main/scripts/ScriptListView.java | 3 +-
.../scriptdroid/ui/main/task/Task.java | 119 +++++++++
.../scriptdroid/ui/main/task/TaskGroup.java | 131 ++++++++++
.../ui/main/task/TaskListRecyclerView.java | 206 ++++++++++------
.../ui/main/task/TaskManagerFragment.java | 8 +-
.../ui/timing/TimedTaskSettingActivity.java | 232 ++++++++++++++++++
.../ui/update/UpdateInfoDialogBuilder.java | 2 +-
.../ic_date_range_black_48dp.png | Bin 0 -> 249 bytes
.../drawable-hdpi/ic_schedule_black_48dp.png | Bin 0 -> 1029 bytes
.../ic_date_range_black_48dp.png | Bin 0 -> 187 bytes
.../drawable-mdpi/ic_schedule_black_48dp.png | Bin 0 -> 687 bytes
.../ic_date_range_black_48dp.png | Bin 0 -> 318 bytes
.../drawable-xhdpi/ic_schedule_black_48dp.png | Bin 0 -> 1364 bytes
.../ic_date_range_black_48dp.png | Bin 0 -> 481 bytes
.../ic_schedule_black_48dp.png | Bin 0 -> 2046 bytes
.../ic_date_range_black_48dp.png | Bin 0 -> 718 bytes
.../ic_schedule_black_48dp.png | Bin 0 -> 2718 bytes
.../layout/activity_timed_task_setting.xml | 192 +++++++++++++++
.../main/res/menu/menu_timed_task_setting.xml | 10 +
app/src/main/res/raw/mpl_20_full.txt | 4 +-
app/src/main/res/values/strings.xml | 10 +-
.../src/main/java/com/stardust/pio/PFile.java | 5 +-
.../main/java/com/stardust/pio/PFiles.java | 7 +
51 files changed, 1106 insertions(+), 171 deletions(-)
create mode 100644 app/src/main/java/com/stardust/scriptdroid/storage/database/ModelChange.java
rename app/src/main/java/com/stardust/scriptdroid/{timing => storage/database}/TimedTaskDatabase.java (76%)
rename app/src/main/java/com/stardust/scriptdroid/{io => storage/file}/SampleFileProvider.java (97%)
rename app/src/main/java/com/stardust/scriptdroid/{io => storage/file}/StorageFileProvider.java (99%)
rename app/src/main/java/com/stardust/scriptdroid/{io => storage/file}/TmpScriptFiles.java (90%)
create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/main/task/Task.java
create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskGroup.java
create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/timing/TimedTaskSettingActivity.java
create mode 100644 app/src/main/res/drawable-hdpi/ic_date_range_black_48dp.png
create mode 100644 app/src/main/res/drawable-hdpi/ic_schedule_black_48dp.png
create mode 100644 app/src/main/res/drawable-mdpi/ic_date_range_black_48dp.png
create mode 100644 app/src/main/res/drawable-mdpi/ic_schedule_black_48dp.png
create mode 100644 app/src/main/res/drawable-xhdpi/ic_date_range_black_48dp.png
create mode 100644 app/src/main/res/drawable-xhdpi/ic_schedule_black_48dp.png
create mode 100644 app/src/main/res/drawable-xxhdpi/ic_date_range_black_48dp.png
create mode 100644 app/src/main/res/drawable-xxhdpi/ic_schedule_black_48dp.png
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_date_range_black_48dp.png
create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_schedule_black_48dp.png
create mode 100644 app/src/main/res/layout/activity_timed_task_setting.xml
create mode 100644 app/src/main/res/menu/menu_timed_task_setting.xml
diff --git a/LICENSE.md b/LICENSE.md
index 18a94633..92b7e2d8 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -47,7 +47,7 @@ Mozilla Public License Version 2.0
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
- whether at the time of the initial grant or subsequently, any and
+ whether at the timeFlag of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
@@ -246,7 +246,7 @@ non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
+first timeFlag You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f1d0dbd1..90b5b38a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -86,6 +86,7 @@
+
@@ -102,6 +103,7 @@
android:name=".ui.error.IssueReporterActivity"
android:theme="@style/IssueReporterTheme"/>
+
diff --git a/app/src/main/assets/docs/util.html b/app/src/main/assets/docs/util.html
index 0958af14..53993f45 100644
--- a/app/src/main/assets/docs/util.html
+++ b/app/src/main/assets/docs/util.html
@@ -234,14 +234,14 @@ exports.puts = util.deprecate(function() {
When called, util.deprecate() will return a function that will emit a
DeprecationWarning using the process.on('warning') event. By default,
this warning will be emitted and printed to stderr exactly once, the first
-time it is called. After the warning is emitted, the wrapped function
+timeFlag it is called. After the warning is emitted, the wrapped function
is called.
If either the --no-deprecation or --no-warnings command line flags are
used, or if the process.noDeprecation property is set to true prior to
the first deprecation warning, the util.deprecate() method does nothing.
If the --trace-deprecation or --trace-warnings command line flags are set,
or the process.traceDeprecation property is set to true, a warning and a
-stack trace are printed to stderr the first time the deprecated function is
+stack trace are printed to stderr the first timeFlag the deprecated function is
called.
If the --throw-deprecation command line flag is set, or the
process.throwDeprecation property is set to true, then an exception will be
@@ -447,7 +447,7 @@ via the util.inspect.styles and util.inspect.colors pr
regexp - red
null - bold
undefined - grey
-special - cyan (only applied to functions at this time)
+special - cyan (only applied to functions at this timeFlag)
name - (no styling)
The predefined color codes are: white, grey, black, blue, cyan,
diff --git a/app/src/main/assets/editor/codemirror/CHANGELOG.md b/app/src/main/assets/editor/codemirror/CHANGELOG.md
index ff7d6e23..4c929d24 100644
--- a/app/src/main/assets/editor/codemirror/CHANGELOG.md
+++ b/app/src/main/assets/editor/codemirror/CHANGELOG.md
@@ -643,7 +643,7 @@ Fix a [bug](https://github.com/codemirror/CodeMirror/issues/3834) that caused ph
* The editor and theme CSS was cleaned up. Some selectors are now less specific than before
* New theme: [abcdef](http://codemirror.net/demo/theme.html#abcdef)
* Lines longer than [`maxHighlightLength`](http://codemirror.net/doc/manual.html#option_maxHighlightLength) are now less likely to mess up indentation
-* New addons: [`autorefresh`](http://codemirror.net/doc/manual.html#addon_autorefresh) for refreshing an editor the first time it becomes visible, and `html-lint` for using [HTMLHint](http://htmlhint.com/)
+* New addons: [`autorefresh`](http://codemirror.net/doc/manual.html#addon_autorefresh) for refreshing an editor the first timeFlag it becomes visible, and `html-lint` for using [HTMLHint](http://htmlhint.com/)
* The [`search`](http://codemirror.net/doc/manual.html#addon_search) addon now recognizes `\r` and `\n` in pattern and replacement input
## 5.5.0 (2015-07-20)
@@ -774,7 +774,7 @@ Emergency single-patch update to 4.9\. Fixes Firefox-specific problem where the
## 4.4.0 (2014-07-21)
* **Note:** Some events might now fire in slightly different order (`"change"` is still guaranteed to fire before `"cursorActivity"`)
-* Nested operations in multiple editors are now synced (complete at same time, reducing DOM reflows)
+* Nested operations in multiple editors are now synced (complete at same timeFlag, reducing DOM reflows)
* Visual block mode for [vim](http://codemirror.net/demo/vim.html) () is nearly complete
* New mode: [Kotlin](http://codemirror.net/mode/kotlin/index.html)
* Better multi-selection paste for text copied from multiple CodeMirror selections
@@ -804,7 +804,7 @@ Emergency single-patch update to 4.9\. Fixes Firefox-specific problem where the
## 4.1.0 (2014-04-22)
-* _Slightly incompatible_: The [`"cursorActivity"`](http://codemirror.net/doc/manual.html#event_cursorActivity) event now fires after all other events for the operation (and only for handlers that were actually registered at the time the activity happened).
+* _Slightly incompatible_: The [`"cursorActivity"`](http://codemirror.net/doc/manual.html#event_cursorActivity) event now fires after all other events for the operation (and only for handlers that were actually registered at the timeFlag the activity happened).
* New command: [`insertSoftTab`](http://codemirror.net/doc/manual.html#command_insertSoftTab).
* New mode: [Django](http://codemirror.net/mode/django/index.html).
* Improved modes: [Verilog](http://codemirror.net/mode/verilog/index.html) (rewritten), [Jinja2](http://codemirror.net/mode/jinja2/index.html), [Haxe](http://codemirror.net/mode/haxe/index.html), [PHP](http://codemirror.net/mode/php/index.html) (string interpolation highlighted), [JavaScript](http://codemirror.net/mode/javascript/index.html) (indentation of trailing else, template strings), [LiveScript](http://codemirror.net/mode/livescript/index.html) (multi-line strings).
diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java
index 538707a4..112bf255 100644
--- a/app/src/main/java/com/stardust/scriptdroid/App.java
+++ b/app/src/main/java/com/stardust/scriptdroid/App.java
@@ -12,12 +12,16 @@ import com.bumptech.glide.request.transition.Transition;
import com.flurry.android.FlurryAgent;
import com.nickandjerry.dynamiclayoutinflator.lib.ImageLoader;
import com.nickandjerry.dynamiclayoutinflator.lib.util.Drawables;
+import com.raizlabs.android.dbflow.config.DatabaseConfig;
+import com.raizlabs.android.dbflow.config.FlowConfig;
import com.raizlabs.android.dbflow.config.FlowManager;
+import com.raizlabs.android.dbflow.runtime.DirectModelNotifier;
import com.squareup.leakcanary.LeakCanary;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.autojs.key.GlobalKeyObserver;
import com.stardust.scriptdroid.autojs.record.GlobalRecorder;
import com.stardust.scriptdroid.network.GlideApp;
+import com.stardust.scriptdroid.storage.database.TimedTaskDatabase;
import com.stardust.scriptdroid.timing.TimedTaskScheduler;
import com.stardust.scriptdroid.tool.CrashHandler;
import com.stardust.scriptdroid.ui.error.ErrorReportActivity;
@@ -68,7 +72,11 @@ public class App extends MultiDexApplication {
}
private void init() {
- FlowManager.init(this);
+ FlowManager.init(FlowConfig.builder(this)
+ .addDatabaseConfig(DatabaseConfig.builder(TimedTaskDatabase.class)
+ .modelNotifier(DirectModelNotifier.get())
+ .build())
+ .build());
ThemeColorManager.setDefaultThemeColor(new ThemeColor(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorAccent)));
ThemeColorManager.init(this);
AutoJs.initInstance(this);
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/ScriptIntents.java b/app/src/main/java/com/stardust/scriptdroid/external/ScriptIntents.java
index 756a1f7d..86046457 100644
--- a/app/src/main/java/com/stardust/scriptdroid/external/ScriptIntents.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/ScriptIntents.java
@@ -10,7 +10,7 @@ import com.stardust.autojs.script.ScriptSource;
import com.stardust.autojs.script.SequenceScriptSource;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.scriptdroid.autojs.AutoJs;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.model.script.PathChecker;
import java.io.File;
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/tasker/TaskPrefEditActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/tasker/TaskPrefEditActivity.java
index f13928b9..feec24cd 100644
--- a/app/src/main/java/com/stardust/scriptdroid/external/tasker/TaskPrefEditActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/tasker/TaskPrefEditActivity.java
@@ -11,7 +11,7 @@ import android.view.MenuItem;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.ScriptIntents;
import com.stardust.scriptdroid.model.script.ScriptFile;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
import com.twofortyfouram.locale.sdk.client.ui.activity.AbstractAppCompatPluginActivity;
diff --git a/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java
index a7bca029..c9b7fa15 100644
--- a/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java
@@ -9,7 +9,7 @@ import android.view.MenuItem;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.model.script.ScriptFile;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
diff --git a/app/src/main/java/com/stardust/scriptdroid/model/script/Scripts.java b/app/src/main/java/com/stardust/scriptdroid/model/script/Scripts.java
index 5a3062c3..991b5d5e 100644
--- a/app/src/main/java/com/stardust/scriptdroid/model/script/Scripts.java
+++ b/app/src/main/java/com/stardust/scriptdroid/model/script/Scripts.java
@@ -16,7 +16,7 @@ import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.external.ScriptIntents;
import com.stardust.scriptdroid.external.shortcut.Shortcut;
import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.ui.edit.EditActivity;
import org.mozilla.javascript.RhinoException;
diff --git a/app/src/main/java/com/stardust/scriptdroid/pluginclient/DevPluginResponseHandler.java b/app/src/main/java/com/stardust/scriptdroid/pluginclient/DevPluginResponseHandler.java
index 6580bd4e..52e54c15 100644
--- a/app/src/main/java/com/stardust/scriptdroid/pluginclient/DevPluginResponseHandler.java
+++ b/app/src/main/java/com/stardust/scriptdroid/pluginclient/DevPluginResponseHandler.java
@@ -12,7 +12,7 @@ import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.model.script.Scripts;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import java.util.HashMap;
diff --git a/app/src/main/java/com/stardust/scriptdroid/storage/database/ModelChange.java b/app/src/main/java/com/stardust/scriptdroid/storage/database/ModelChange.java
new file mode 100644
index 00000000..f2d90ceb
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/storage/database/ModelChange.java
@@ -0,0 +1,34 @@
+package com.stardust.scriptdroid.storage.database;
+
+import com.raizlabs.android.dbflow.structure.BaseModel;
+
+/**
+ * Created by Stardust on 2017/11/28.
+ */
+
+public class ModelChange {
+
+ private final M mData;
+ private final BaseModel.Action mAction;
+
+ public ModelChange(M data, BaseModel.Action action) {
+ mData = data;
+ mAction = action;
+ }
+
+ public M getData() {
+ return mData;
+ }
+
+ public BaseModel.Action getAction() {
+ return mAction;
+ }
+
+ @Override
+ public String toString() {
+ return "ModelChange{" +
+ "mData=" + mData +
+ ", mAction=" + mAction +
+ '}';
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskDatabase.java b/app/src/main/java/com/stardust/scriptdroid/storage/database/TimedTaskDatabase.java
similarity index 76%
rename from app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskDatabase.java
rename to app/src/main/java/com/stardust/scriptdroid/storage/database/TimedTaskDatabase.java
index 877cf55a..101b5fe2 100644
--- a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskDatabase.java
+++ b/app/src/main/java/com/stardust/scriptdroid/storage/database/TimedTaskDatabase.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.timing;
+package com.stardust.scriptdroid.storage.database;
import com.raizlabs.android.dbflow.annotation.Database;
diff --git a/app/src/main/java/com/stardust/scriptdroid/io/SampleFileProvider.java b/app/src/main/java/com/stardust/scriptdroid/storage/file/SampleFileProvider.java
similarity index 97%
rename from app/src/main/java/com/stardust/scriptdroid/io/SampleFileProvider.java
rename to app/src/main/java/com/stardust/scriptdroid/storage/file/SampleFileProvider.java
index 1f50bfe2..614df1eb 100644
--- a/app/src/main/java/com/stardust/scriptdroid/io/SampleFileProvider.java
+++ b/app/src/main/java/com/stardust/scriptdroid/storage/file/SampleFileProvider.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.io;
+package com.stardust.scriptdroid.storage.file;
import android.content.Context;
import android.content.res.AssetManager;
diff --git a/app/src/main/java/com/stardust/scriptdroid/io/StorageFileProvider.java b/app/src/main/java/com/stardust/scriptdroid/storage/file/StorageFileProvider.java
similarity index 99%
rename from app/src/main/java/com/stardust/scriptdroid/io/StorageFileProvider.java
rename to app/src/main/java/com/stardust/scriptdroid/storage/file/StorageFileProvider.java
index acabf5fa..4fcb5aea 100644
--- a/app/src/main/java/com/stardust/scriptdroid/io/StorageFileProvider.java
+++ b/app/src/main/java/com/stardust/scriptdroid/storage/file/StorageFileProvider.java
@@ -1,4 +1,4 @@
-package com.stardust.scriptdroid.io;
+package com.stardust.scriptdroid.storage.file;
import android.os.Environment;
diff --git a/app/src/main/java/com/stardust/scriptdroid/io/TmpScriptFiles.java b/app/src/main/java/com/stardust/scriptdroid/storage/file/TmpScriptFiles.java
similarity index 90%
rename from app/src/main/java/com/stardust/scriptdroid/io/TmpScriptFiles.java
rename to app/src/main/java/com/stardust/scriptdroid/storage/file/TmpScriptFiles.java
index 4a816ecd..2f84c192 100644
--- a/app/src/main/java/com/stardust/scriptdroid/io/TmpScriptFiles.java
+++ b/app/src/main/java/com/stardust/scriptdroid/storage/file/TmpScriptFiles.java
@@ -1,9 +1,8 @@
-package com.stardust.scriptdroid.io;
+package com.stardust.scriptdroid.storage.file;
import android.content.Context;
import com.stardust.pio.PFiles;
-import com.stardust.scriptdroid.model.script.ScriptFile;
import java.io.File;
import java.io.IOException;
diff --git a/app/src/main/java/com/stardust/scriptdroid/timing/TaskReceiver.java b/app/src/main/java/com/stardust/scriptdroid/timing/TaskReceiver.java
index dcba453c..be12c3a9 100644
--- a/app/src/main/java/com/stardust/scriptdroid/timing/TaskReceiver.java
+++ b/app/src/main/java/com/stardust/scriptdroid/timing/TaskReceiver.java
@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.external.ScriptIntents;
/**
diff --git a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTask.java b/app/src/main/java/com/stardust/scriptdroid/timing/TimedTask.java
index 42200b47..3d6b8d9d 100644
--- a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTask.java
+++ b/app/src/main/java/com/stardust/scriptdroid/timing/TimedTask.java
@@ -1,20 +1,19 @@
package com.stardust.scriptdroid.timing;
+import android.app.PendingIntent;
+import android.content.Context;
import android.content.Intent;
-import android.text.format.Time;
import com.raizlabs.android.dbflow.annotation.Column;
import com.raizlabs.android.dbflow.annotation.PrimaryKey;
import com.raizlabs.android.dbflow.annotation.Table;
import com.stardust.autojs.execution.ExecutionConfig;
import com.stardust.scriptdroid.external.ScriptIntents;
+import com.stardust.scriptdroid.storage.database.TimedTaskDatabase;
-import org.joda.time.Instant;
-import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;
-import java.util.Calendar;
import java.util.concurrent.TimeUnit;
@@ -33,39 +32,40 @@ public class TimedTask {
public final static int FLAG_FRIDAY = 0x20;
public final static int FLAG_SATURDAY = 0x40;
private static final int FLAG_EVERYDAY = 0x7F;
+ private static final int REQUEST_CODE = 2000;
- @PrimaryKey(autoincrement = true)
+ @PrimaryKey(autoincrement = true, quickCheckAutoIncrement = true)
@Column(name = "id")
- int mId;
+ int mId = -1;
- @Column(name = "days_of_week")
- int mDaysOfWeek;
+ @Column(name = "time")
+ long mTimeFlag;
@Column(name = "scheduled")
boolean mScheduled;
@Column(name = "delay")
- private long mDelay = 0;
+ long mDelay = 0;
@Column(name = "interval")
- private long mInterval = 0;
+ long mInterval = 0;
@Column(name = "loop_times")
- private int mLoopTimes = 1;
+ int mLoopTimes = 1;
@Column(name = "millis")
- private long mMillis;
+ long mMillis;
@Column(name = "script_path")
- private String mScriptPath;
+ String mScriptPath;
public TimedTask() {
}
- public TimedTask(long millis, int daysOfWeek, String scriptPath, ExecutionConfig config) {
+ public TimedTask(long millis, int timeFlag, String scriptPath, ExecutionConfig config) {
mMillis = millis;
- mDaysOfWeek = daysOfWeek;
+ mTimeFlag = timeFlag;
mScriptPath = scriptPath;
mDelay = config.delay;
mLoopTimes = config.loopTimes;
@@ -73,7 +73,7 @@ public class TimedTask {
}
public boolean isDisposable() {
- return mDaysOfWeek == FLAG_DISPOSABLE;
+ return mTimeFlag == FLAG_DISPOSABLE;
}
public boolean isScheduled() {
@@ -97,10 +97,67 @@ public class TimedTask {
return nextTimeMillis;
}
+ public long getMillis() {
+ return mMillis;
+ }
+
public int getId() {
return mId;
}
+ public String getScriptPath() {
+ return mScriptPath;
+ }
+
+
+ public void setId(int id) {
+ mId = id;
+ }
+
+ public long getTimeFlag() {
+ return mTimeFlag;
+ }
+
+ public void setTimeFlag(long time) {
+ mTimeFlag = time;
+ }
+
+ public long getDelay() {
+ return mDelay;
+ }
+
+ public void setDelay(long delay) {
+ mDelay = delay;
+ }
+
+ public long getInterval() {
+ return mInterval;
+ }
+
+ public void setInterval(long interval) {
+ mInterval = interval;
+ }
+
+ public int getLoopTimes() {
+ return mLoopTimes;
+ }
+
+ public void setLoopTimes(int loopTimes) {
+ mLoopTimes = loopTimes;
+ }
+
+ public void setMillis(long millis) {
+ mMillis = millis;
+ }
+
+ public void setScriptPath(String scriptPath) {
+ mScriptPath = scriptPath;
+ }
+
+ public boolean isDaily() {
+ return mTimeFlag == FLAG_EVERYDAY;
+ }
+
public Intent createIntent() {
return new Intent(TaskReceiver.ACTION_TASK)
.putExtra(TaskReceiver.EXTRA_TASK_ID, mId)
@@ -110,12 +167,47 @@ public class TimedTask {
.putExtra(ScriptIntents.EXTRA_KEY_LOOP_INTERVAL, mInterval);
}
+
+ public PendingIntent createPendingIntent(Context context) {
+ return PendingIntent.getBroadcast(context, REQUEST_CODE + 1 + getId(),
+ createIntent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ }
+
+ @Override
+ public String toString() {
+ return "TimedTask{" +
+ "mId=" + mId +
+ ", mTimeFlag=" + mTimeFlag +
+ ", mScheduled=" + mScheduled +
+ ", mDelay=" + mDelay +
+ ", mInterval=" + mInterval +
+ ", mLoopTimes=" + mLoopTimes +
+ ", mMillis=" + mMillis +
+ ", mScriptPath='" + mScriptPath + '\'' +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ TimedTask timedTask = (TimedTask) o;
+
+ return mId == timedTask.mId;
+ }
+
+ @Override
+ public int hashCode() {
+ return mId;
+ }
+
public static TimedTask dailyTask(LocalTime time, String scriptPath, ExecutionConfig config) {
return new TimedTask(time.getMillisOfDay(), FLAG_EVERYDAY, scriptPath, config);
}
- public static TimedTask disposableTask(long millis, String scriptPath, ExecutionConfig config) {
- return new TimedTask(millis, FLAG_EVERYDAY, scriptPath, config);
+ public static TimedTask disposableTask(LocalDateTime dateTime, String scriptPath, ExecutionConfig config) {
+ return new TimedTask(dateTime.toDateTime().getMillis(), FLAG_DISPOSABLE, scriptPath, config);
}
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskManager.java b/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskManager.java
index 59c3788b..dfc660db 100644
--- a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskManager.java
+++ b/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskManager.java
@@ -2,17 +2,26 @@ package com.stardust.scriptdroid.timing;
import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
import com.raizlabs.android.dbflow.config.FlowManager;
+import com.raizlabs.android.dbflow.runtime.DirectModelNotifier;
import com.raizlabs.android.dbflow.rx2.language.RXSQLite;
import com.raizlabs.android.dbflow.sql.language.SQLite;
+import com.raizlabs.android.dbflow.structure.BaseModel;
import com.raizlabs.android.dbflow.structure.ModelAdapter;
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.storage.database.ModelChange;
+import com.stardust.scriptdroid.storage.database.TimedTaskDatabase;
+
+import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Flowable;
+import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
+import io.reactivex.subjects.PublishSubject;
/**
* Created by Stardust on 2017/11/27.
@@ -20,31 +29,48 @@ import io.reactivex.schedulers.Schedulers;
public class TimedTaskManager {
+
private static TimedTaskManager sInstance;
private ModelAdapter mTimedTaskModelAdapter;
+ private Context mContext;
+ private PublishSubject> mTimedTaskChanges = PublishSubject.create();
public static TimedTaskManager getInstance() {
if (sInstance == null) {
- sInstance = new TimedTaskManager();
+ sInstance = new TimedTaskManager(App.getApp());
}
return sInstance;
}
- public TimedTaskManager() {
+ public TimedTaskManager(Context context) {
+ mContext = context;
mTimedTaskModelAdapter = FlowManager.getModelAdapter(TimedTask.class);
- }
+ DirectModelNotifier.get().registerForModelChanges(TimedTask.class, new DirectModelNotifier.ModelChangedListener() {
+ @Override
+ public void onModelChanged(@NonNull TimedTask model, @NonNull BaseModel.Action action) {
+ mTimedTaskChanges.onNext(new ModelChange<>(model, action));
+ }
+
+ @Override
+ public void onTableChanged(@Nullable Class> tableChanged, @NonNull BaseModel.Action action) {
- public void notifyTaskFinished(int id) {
- getTaskById(id).subscribe(timedTask -> {
- if (timedTask.isDisposable()) {
- removeTask(id).subscribe();
- } else {
- timedTask.setScheduled(false);
- mTimedTaskModelAdapter.update(timedTask);
}
});
}
+ public void notifyTaskFinished(int id) {
+ TimedTask task = getTimedTask(id);
+ if (task == null)
+ return;
+ if (task.isDisposable()) {
+ mTimedTaskModelAdapter.delete(task);
+ } else {
+ task.setScheduled(false);
+ mTimedTaskModelAdapter.update(task);
+ }
+ }
+
+
private Flowable getTaskById(int id) {
return RXSQLite.rx(SQLite.select()
.from(TimedTask.class)
@@ -61,6 +87,16 @@ public class TimedTaskManager {
}
+ public void cancelTask(TimedTask timedTask) {
+ TimedTaskScheduler.cancel(mContext, timedTask);
+ mTimedTaskModelAdapter.delete(timedTask);
+ }
+
+ public void addTask(TimedTask timedTask) {
+ mTimedTaskModelAdapter.insert(timedTask);
+ TimedTaskScheduler.scheduleTaskIfNeeded(mContext, timedTask);
+ }
+
public Flowable getAllTasks() {
return RXSQLite.rx(SQLite.select().from(TimedTask.class))
@@ -69,10 +105,31 @@ public class TimedTaskManager {
}
+ public Observable> getTimeTaskChanges() {
+ return mTimedTaskChanges;
+ }
+
public void notifyTaskScheduled(TimedTask timedTask) {
timedTask.setScheduled(true);
mTimedTaskModelAdapter.update(timedTask);
}
+ public List getAllTasksAsList() {
+ return SQLite.select().from(TimedTask.class)
+ .queryList();
+ }
+
+ public TimedTask getTimedTask(int taskId) {
+ return SQLite.select()
+ .from(TimedTask.class)
+ .where(TimedTask_Table.id.is(taskId))
+ .querySingle();
+ }
+
+ public void updateTask(TimedTask task) {
+ mTimedTaskModelAdapter.update(task);
+ TimedTaskScheduler.cancel(mContext, task);
+ TimedTaskScheduler.scheduleTaskIfNeeded(mContext, task);
+ }
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskScheduler.java b/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskScheduler.java
index 6fadbb9e..b607e01c 100644
--- a/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskScheduler.java
+++ b/app/src/main/java/com/stardust/scriptdroid/timing/TimedTaskScheduler.java
@@ -61,8 +61,7 @@ public class TimedTaskScheduler extends BroadcastReceiver {
return;
}
// FIXME: 2017/11/28 requestCode may > 65535
- PendingIntent op = PendingIntent.getBroadcast(context, REQUEST_CODE + 1 + timedTask.getId(),
- timedTask.createIntent(), PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent op = timedTask.createPendingIntent(context);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, millis, op);
} else {
@@ -76,4 +75,9 @@ public class TimedTaskScheduler extends BroadcastReceiver {
INTERVAL, PendingIntent.getBroadcast(context, REQUEST_CODE,
new Intent(TimedTaskScheduler.ACTION_CHECK_TASK), PendingIntent.FLAG_UPDATE_CURRENT));
}
+
+ public static void cancel(Context context, TimedTask timedTask) {
+ AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ alarmManager.cancel(timedTask.createPendingIntent(context));
+ }
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/build/BuildActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/build/BuildActivity.java
index 519ae598..60a909cc 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/build/BuildActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/build/BuildActivity.java
@@ -1,23 +1,17 @@
package com.stardust.scriptdroid.ui.build;
-import android.annotation.SuppressLint;
-import android.app.ListActivity;
-import android.app.PendingIntent;
import android.content.Intent;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
-import com.stardust.autojs.apkbuilder.ApkBuilder;
-import com.stardust.pio.PFiles;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.build.AutoJsApkBuilder;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
-import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import com.stardust.util.IntentUtil;
import org.androidannotations.annotations.AfterViews;
@@ -26,10 +20,7 @@ import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
import java.io.File;
-import java.io.FileOutputStream;
-import java.util.concurrent.Callable;
-import butterknife.OnClick;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java
index 365e63ac..4f5a6b0b 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/common/ScriptOperations.java
@@ -21,14 +21,16 @@ import com.stardust.pio.PFiles;
import com.stardust.pio.UncheckedIOException;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.io.TmpScriptFiles;
+import com.stardust.scriptdroid.external.ScriptIntents;
+import com.stardust.scriptdroid.storage.file.TmpScriptFiles;
import com.stardust.scriptdroid.model.sample.SampleFile;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.model.script.Scripts;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.network.download.DownloadManager;
import com.stardust.scriptdroid.ui.filechooser.FileChooserDialogBuilder;
import com.stardust.scriptdroid.ui.shortcut.ShortcutCreateActivity;
+import com.stardust.scriptdroid.ui.timing.TimedTaskSettingActivity_;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import org.reactivestreams.Publisher;
@@ -40,8 +42,6 @@ import java.io.InputStream;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.functions.Consumer;
-import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.PublishSubject;
@@ -307,7 +307,9 @@ public class ScriptOperations {
}
public void timedTask(ScriptFile scriptFile) {
-
+ TimedTaskSettingActivity_.intent(mContext)
+ .extra(ScriptIntents.EXTRA_KEY_PATH, scriptFile.getPath())
+ .start();
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/filechooser/FileChooserDialogBuilder.java b/app/src/main/java/com/stardust/scriptdroid/ui/filechooser/FileChooserDialogBuilder.java
index 71a80435..ea733d77 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/filechooser/FileChooserDialogBuilder.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/filechooser/FileChooserDialogBuilder.java
@@ -7,7 +7,7 @@ import android.support.annotation.StringRes;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.model.script.ScriptFile;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
import java.io.File;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java b/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java
index adfa350d..e018f624 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/floating/CircularMenu.java
@@ -9,7 +9,6 @@ import android.widget.ImageView;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
-import com.google.gson.Gson;
import com.stardust.app.DialogUtils;
import com.stardust.app.OperationDialogBuilder;
import com.stardust.autojs.core.record.Recorder;
@@ -21,10 +20,8 @@ import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.accessibility.AccessibilityService;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.autojs.record.GlobalRecorder;
-import com.stardust.scriptdroid.io.StorageFileProvider;
-import com.stardust.scriptdroid.model.script.ScriptFile;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
-import com.stardust.scriptdroid.tool.GsonUtils;
import com.stardust.scriptdroid.ui.floating.layoutinspector.LayoutBoundsFloatyWindow;
import com.stardust.scriptdroid.ui.floating.layoutinspector.LayoutHierarchyFloatyWindow;
import com.stardust.scriptdroid.ui.main.MainActivity_;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java
index e9921989..27816179 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java
@@ -29,7 +29,7 @@ import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.ui.common.NotAskAgainDialog;
import com.stardust.scriptdroid.ui.doc.OnlineDocsFragment_;
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.ui.main.community.CommunityFragment_;
import com.stardust.scriptdroid.ui.log.LogActivity_;
import com.stardust.scriptdroid.ui.main.sample.SampleListFragment_;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/community/CommunityWebView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/community/CommunityWebView.java
index f86cd4bd..faedb0f6 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/community/CommunityWebView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/community/CommunityWebView.java
@@ -9,7 +9,7 @@ import android.webkit.ValueCallback;
import android.webkit.WebView;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.model.script.Scripts;
import com.stardust.scriptdroid.network.download.DownloadManager;
import com.stardust.scriptdroid.ui.common.OptionListView;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListFragment.java
index 01c94696..e3178ce3 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListFragment.java
@@ -6,12 +6,8 @@ import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.io.SampleFileProvider;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.SampleFileProvider;
import com.stardust.scriptdroid.model.script.Scripts;
-import com.stardust.scriptdroid.tool.SimpleObserver;
-import com.stardust.scriptdroid.ui.common.ScriptOperations;
-import com.stardust.scriptdroid.ui.main.FloatingActionMenu;
import com.stardust.scriptdroid.ui.main.QueryEvent;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.scriptdroid.ui.main.scripts.ScriptListView;
@@ -23,8 +19,6 @@ import org.androidannotations.annotations.ViewById;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-
/**
* Created by Stardust on 2017/10/28.
*/
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListView.java
index 93599f25..d4d3997c 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/sample/SampleListView.java
@@ -15,8 +15,7 @@ import android.widget.TextView;
import com.stardust.pio.PFiles;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.io.SampleFileProvider;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.SampleFileProvider;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.model.script.Scripts;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/MyScriptListFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/MyScriptListFragment.java
index e185bbd4..7ea344fc 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/MyScriptListFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/MyScriptListFragment.java
@@ -4,12 +4,10 @@ import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
-import android.view.View;
import com.stardust.scriptdroid.R;
-import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.model.script.Scripts;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.tool.SimpleObserver;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.main.FloatingActionMenu;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java
index 97a2a646..055ec5f2 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/scripts/ScriptListView.java
@@ -8,7 +8,6 @@ import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
@@ -22,7 +21,7 @@ import com.stardust.pio.PFiles;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.model.script.ScriptFile;
import com.stardust.scriptdroid.model.script.Scripts;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.ui.common.ScriptLoopDialog;
import com.stardust.scriptdroid.ui.common.ScriptOperations;
import com.stardust.scriptdroid.ui.floating.EditorFloaty;
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/Task.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/Task.java
new file mode 100644
index 00000000..c1b8ecfd
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/Task.java
@@ -0,0 +1,119 @@
+package com.stardust.scriptdroid.ui.main.task;
+
+import com.stardust.autojs.engine.JavaScriptEngine;
+import com.stardust.autojs.engine.ScriptEngine;
+import com.stardust.autojs.engine.ScriptEngineFactory;
+import com.stardust.autojs.script.AutoFileSource;
+import com.stardust.autojs.script.JavaScriptSource;
+import com.stardust.autojs.script.ScriptSource;
+import com.stardust.pio.PFile;
+import com.stardust.pio.PFiles;
+import com.stardust.scriptdroid.App;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.timing.TimedTask;
+import com.stardust.scriptdroid.timing.TimedTaskManager;
+
+import org.joda.time.format.DateTimeFormat;
+
+/**
+ * Created by Stardust on 2017/11/28.
+ */
+
+public abstract class Task {
+
+ public abstract String getName();
+
+ public abstract String getDesc();
+
+ public abstract void cancel();
+
+ public abstract String getEngineName();
+
+ public static class PendingTask extends Task {
+
+ private TimedTask mTimedTask;
+
+
+ public PendingTask(TimedTask timedTask) {
+ mTimedTask = timedTask;
+ }
+
+ public TimedTask getTimedTask() {
+ return mTimedTask;
+ }
+
+ @Override
+ public String getName() {
+ return PFiles.getSimplifiedPath(mTimedTask.getScriptPath());
+ }
+
+ @Override
+ public String getDesc() {
+ long nextTime = mTimedTask.getNextTime();
+ return App.getApp().getString(R.string.text_next_run_time) + ": " +
+ DateTimeFormat.shortDateTime().print(nextTime);
+ }
+
+ @Override
+ public void cancel() {
+ TimedTaskManager.getInstance().cancelTask(mTimedTask);
+ }
+
+ @Override
+ public String getEngineName() {
+ if (mTimedTask.getScriptPath().endsWith(".js")) {
+ return JavaScriptSource.ENGINE;
+ } else {
+ return AutoFileSource.ENGINE;
+ }
+ }
+
+ public void setTimedTask(TimedTask timedTask) {
+ mTimedTask = timedTask;
+ }
+ }
+
+ public static class RunningTask extends Task {
+ private final ScriptEngine mScriptEngine;
+
+ public RunningTask(ScriptEngine scriptEngine) {
+ mScriptEngine = scriptEngine;
+ }
+
+ public ScriptEngine getScriptEngine() {
+ return mScriptEngine;
+ }
+
+ @Override
+ public String getName() {
+ ScriptSource source = (ScriptSource) mScriptEngine.getTag(ScriptEngine.TAG_SOURCE);
+ if (source == null) {
+ return null;
+ }
+ return source.getName();
+ }
+
+ @Override
+ public String getDesc() {
+ ScriptSource source = (ScriptSource) mScriptEngine.getTag(ScriptEngine.TAG_SOURCE);
+ if (source == null) {
+ return null;
+ }
+ return source.toString();
+ }
+
+ @Override
+ public void cancel() {
+ mScriptEngine.forceStop();
+ }
+
+ @Override
+ public String getEngineName() {
+ ScriptSource source = (ScriptSource) mScriptEngine.getTag(ScriptEngine.TAG_SOURCE);
+ if (source == null) {
+ return null;
+ }
+ return source.getEngineName();
+ }
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskGroup.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskGroup.java
new file mode 100644
index 00000000..f3e85318
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskGroup.java
@@ -0,0 +1,131 @@
+package com.stardust.scriptdroid.ui.main.task;
+
+import android.content.Context;
+
+import com.bignerdranch.expandablerecyclerview.model.Parent;
+import com.stardust.autojs.engine.ScriptEngine;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.autojs.AutoJs;
+import com.stardust.scriptdroid.timing.TimedTask;
+import com.stardust.scriptdroid.timing.TimedTaskManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Created by Stardust on 2017/11/28.
+ */
+
+public abstract class TaskGroup implements Parent {
+
+ protected List mTasks = new ArrayList<>();
+ private String mTitle;
+
+ protected TaskGroup(String title) {
+ mTitle = title;
+ }
+
+
+ @Override
+ public List getChildList() {
+ return mTasks;
+ }
+
+ @Override
+ public boolean isInitiallyExpanded() {
+ return true;
+ }
+
+ public String getTitle() {
+ return mTitle;
+ }
+
+ public abstract void refresh();
+
+ public static class PendingTaskGroup extends TaskGroup {
+
+ public PendingTaskGroup(Context context) {
+ super(context.getString(R.string.text_timed_task));
+ refresh();
+ }
+
+ @Override
+ public void refresh() {
+ List timedTasks = TimedTaskManager.getInstance().getAllTasksAsList();
+ mTasks.clear();
+ for (TimedTask timedTask : timedTasks) {
+ mTasks.add(new Task.PendingTask(timedTask));
+ }
+ }
+
+ public int addTask(TimedTask timedTask) {
+ int pos = mTasks.size();
+ mTasks.add(new Task.PendingTask(timedTask));
+ return pos;
+ }
+
+ public int removeTask(TimedTask data) {
+ int i = indexOf(data);
+ if (i >= 0)
+ mTasks.remove(i);
+ return i;
+ }
+
+ private int indexOf(TimedTask data) {
+ for (int i = 0; i < mTasks.size(); i++) {
+ if (((Task.PendingTask) mTasks.get(i)).getTimedTask().equals(data)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int updateTask(TimedTask task) {
+ int i = indexOf(task);
+ if (i >= 0)
+ ((Task.PendingTask) mTasks.get(i)).setTimedTask(task);
+ return i;
+ }
+ }
+
+ public static class RunningTaskGroup extends TaskGroup {
+
+ public RunningTaskGroup(Context context) {
+ super(context.getString(R.string.text_running_task));
+ refresh();
+ }
+
+ @Override
+ public void refresh() {
+ Set scriptEngines = AutoJs.getInstance().getScriptEngineService().getEngines();
+ mTasks.clear();
+ for (ScriptEngine engine : scriptEngines) {
+ mTasks.add(new Task.RunningTask(engine));
+ }
+ }
+
+ public int addTask(ScriptEngine engine) {
+ int pos = mTasks.size();
+ mTasks.add(new Task.RunningTask(engine));
+ return pos;
+ }
+
+ public int removeTask(ScriptEngine engine) {
+ int i = indexOf(engine);
+ if (i >= 0) {
+ mTasks.remove(i);
+ }
+ return i;
+ }
+
+ public int indexOf(ScriptEngine engine) {
+ for (int i = 0; i < mTasks.size(); i++) {
+ if (((Task.RunningTask) mTasks.get(i)).getScriptEngine().equals(engine)) {
+ return i;
+ }
+ }
+ return -1;
+ }
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java
index ef6eb5ba..934a538d 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskListRecyclerView.java
@@ -2,16 +2,22 @@ package com.stardust.scriptdroid.ui.main.task;
import android.content.Context;
import android.graphics.drawable.GradientDrawable;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.ThemeColorRecyclerView;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.TextView;
import android.workground.WrapContentLinearLayoutManager;
+import com.bignerdranch.expandablerecyclerview.ChildViewHolder;
+import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter;
+import com.bignerdranch.expandablerecyclerview.ParentViewHolder;
+import com.raizlabs.android.dbflow.structure.BaseModel;
import com.stardust.autojs.ScriptEngineService;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.execution.ScriptExecution;
@@ -19,9 +25,13 @@ import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.SimpleScriptExecutionListener;
import com.stardust.autojs.engine.ScriptEngine;
import com.stardust.autojs.script.AutoFileSource;
-import com.stardust.autojs.script.ScriptSource;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
+import com.stardust.scriptdroid.storage.database.ModelChange;
+import com.stardust.scriptdroid.timing.TaskReceiver;
+import com.stardust.scriptdroid.timing.TimedTask;
+import com.stardust.scriptdroid.timing.TimedTaskManager;
+import com.stardust.scriptdroid.ui.timing.TimedTaskSettingActivity_;
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
import java.util.ArrayList;
@@ -30,6 +40,8 @@ import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
/**
* Created by Stardust on 2017/3/24.
@@ -38,28 +50,23 @@ import butterknife.OnClick;
public class TaskListRecyclerView extends ThemeColorRecyclerView implements ScriptEngineManager.EngineLifecycleCallback {
- private final OnClickListener mOnItemClickListenerProxy = new OnClickListener() {
- @Override
- public void onClick(View v) {
+ private static final String LOG_TAG = "TaskListRecyclerView";
- }
- };
-
- private final List mScriptEngines = new ArrayList<>();
+ private final List mTaskGroups = new ArrayList<>();
+ private TaskGroup.RunningTaskGroup mRunningTaskGroup;
+ private TaskGroup.PendingTaskGroup mPendingTaskGroup;
private Adapter mAdapter;
+ private Disposable mTimedTaskChangeDisposable;
private final ScriptEngineService mScriptEngineService = AutoJs.getInstance().getScriptEngineService();
private ScriptExecutionListener mScriptExecutionListener = new SimpleScriptExecutionListener() {
@Override
public void onStart(final ScriptExecution execution) {
- post(new Runnable() {
- @Override
- public void run() {
- int position = mScriptEngines.indexOf(execution.getEngine());
- if (position >= 0) {
- mAdapter.notifyItemChanged(position);
- } else {
- updateEngineList();
- }
+ post(() -> {
+ int position = mRunningTaskGroup.indexOf(execution.getEngine());
+ if (position >= 0) {
+ mAdapter.notifyChildChanged(0, position);
+ } else {
+ refresh();
}
});
@@ -89,14 +96,21 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
.marginResId(R.dimen.script_and_folder_list_divider_left_margin, R.dimen.script_and_folder_list_divider_right_margin)
.showLastDivider()
.build());
- mAdapter = new Adapter();
+ mRunningTaskGroup = new TaskGroup.RunningTaskGroup(getContext());
+ mTaskGroups.add(mRunningTaskGroup);
+ mPendingTaskGroup = new TaskGroup.PendingTaskGroup(getContext());
+ mTaskGroups.add(mPendingTaskGroup);
+ mAdapter = new Adapter(mTaskGroups);
setAdapter(mAdapter);
}
- public void updateEngineList() {
- mScriptEngines.clear();
- mScriptEngines.addAll(mScriptEngineService.getEngines());
- mAdapter.notifyDataSetChanged();
+ public void refresh() {
+ for (TaskGroup group : mTaskGroups) {
+ group.refresh();
+ }
+ mAdapter.notifyParentChanged(0);
+ mAdapter.notifyParentChanged(1);
+ //notifyDataSetChanged not working...
}
@Override
@@ -104,13 +118,16 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
super.onAttachedToWindow();
mScriptEngineService.registerEngineLifecycleCallback(this);
AutoJs.getInstance().getScriptEngineService().registerGlobalScriptExecutionListener(mScriptExecutionListener);
+ mTimedTaskChangeDisposable = TimedTaskManager.getInstance().getTimeTaskChanges()
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::onTimedTaskChange);
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility == VISIBLE) {
- updateEngineList();
+ refresh();
}
}
@@ -119,63 +136,84 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
super.onDetachedFromWindow();
mScriptEngineService.unregisterEngineLifecycleCallback(this);
AutoJs.getInstance().getScriptEngineService().unregisterGlobalScriptExecutionListener(mScriptExecutionListener);
+ mTimedTaskChangeDisposable.dispose();
}
- private void onScriptANR(final ScriptEngine engine) {
- // TODO: 2017/7/19 强制停止aq1sws2
+ void onTimedTaskChange(ModelChange taskChange) {
+ if (taskChange.getAction() == BaseModel.Action.INSERT) {
+ mAdapter.notifyChildInserted(1, mPendingTaskGroup.addTask(taskChange.getData()));
+ } else if (taskChange.getAction() == BaseModel.Action.DELETE) {
+ final int i = mPendingTaskGroup.removeTask(taskChange.getData());
+ // FIXME: 2017/11/28 task id is always 0
+ if (i >= 0) {
+ mAdapter.notifyChildRemoved(1, i);
+ } else {
+ Log.w(LOG_TAG, "data inconsistent on change: " + taskChange);
+ refresh();
+ }
+ } else if (taskChange.getAction() == BaseModel.Action.UPDATE) {
+ final int i = mPendingTaskGroup.updateTask(taskChange.getData());
+ if (i >= 0) {
+ mAdapter.notifyChildChanged(1, i);
+ } else {
+ Log.w(LOG_TAG, "data inconsistent on change: " + taskChange);
+ refresh();
+ }
+ }
}
@Override
public void onEngineCreate(final ScriptEngine engine) {
- synchronized (mScriptEngines) {
- post(new Runnable() {
- @Override
- public void run() {
- mScriptEngines.add(engine);
- getAdapter().notifyItemInserted(mScriptEngines.size() - 1);
- }
- });
- }
+ post(() ->
+ mAdapter.notifyChildInserted(0, mRunningTaskGroup.addTask(engine))
+ );
}
@Override
public void onEngineRemove(final ScriptEngine engine) {
- post(new Runnable() {
- @Override
- public void run() {
- final int i = mScriptEngines.indexOf(engine);
- if (i >= 0) {
- mScriptEngines.remove(i);
- mAdapter.notifyItemRemoved(i);
- } else {
- updateEngineList();
- }
-
+ post(() -> {
+ final int i = mRunningTaskGroup.removeTask(engine);
+ if (i >= 0) {
+ mAdapter.notifyChildRemoved(0, i);
+ } else {
+ refresh();
}
+
});
}
- private class Adapter extends RecyclerView.Adapter {
+ private class Adapter extends ExpandableRecyclerAdapter {
+ public Adapter(@NonNull List parentList) {
+ super(parentList);
+ }
+
+ @NonNull
@Override
- public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
- return new ViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.task_list_recycler_view_item, parent, false));
+ public TaskGroupViewHolder onCreateParentViewHolder(@NonNull ViewGroup parentViewGroup, int viewType) {
+ return new TaskGroupViewHolder(LayoutInflater.from(parentViewGroup.getContext())
+ .inflate(R.layout.dialog_code_generate_option_group, parentViewGroup, false));
+ }
+
+ @NonNull
+ @Override
+ public TaskViewHolder onCreateChildViewHolder(@NonNull ViewGroup parent, int viewType) {
+ return new TaskViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.task_list_recycler_view_item, parent, false));
}
@Override
- public void onBindViewHolder(ViewHolder holder, int position) {
- ScriptEngine engine = mScriptEngines.get(position);
- ScriptSource source = (ScriptSource) mScriptEngines.get(position).getTag(ScriptEngine.TAG_SOURCE);
- holder.bind(source, engine);
+ public void onBindParentViewHolder(@NonNull TaskGroupViewHolder viewHolder, int parentPosition, @NonNull TaskGroup taskGroup) {
+ viewHolder.title.setText(taskGroup.getTitle());
}
@Override
- public int getItemCount() {
- return mScriptEngines.size();
+ public void onBindChildViewHolder(@NonNull TaskViewHolder viewHolder, int parentPosition, int childPosition, @NonNull Task task) {
+ viewHolder.bind(task);
}
}
- class ViewHolder extends RecyclerView.ViewHolder {
+
+ class TaskViewHolder extends ChildViewHolder {
@BindView(R.id.first_char)
TextView mFirstChar;
@@ -184,24 +222,21 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
@BindView(R.id.desc)
TextView mDesc;
- private ScriptEngine mScriptEngine;
+ private Task mTask;
private GradientDrawable mFirstCharBackground;
- ViewHolder(View itemView) {
+ TaskViewHolder(View itemView) {
super(itemView);
- itemView.setOnClickListener(mOnItemClickListenerProxy);
+ itemView.setOnClickListener(this::onItemClick);
ButterKnife.bind(this, itemView);
mFirstCharBackground = (GradientDrawable) mFirstChar.getBackground();
}
- public void bind(ScriptSource source, ScriptEngine engine) {
- mScriptEngine = engine;
- if (source == null)
- return;
- mName.setText(source.getName());
- mDesc.setText(source.toString());
- //ignore android studio warning: use equals to compare string
- if (source.getEngineName() == AutoFileSource.ENGINE) {
+ public void bind(Task task) {
+ mTask = task;
+ mName.setText(task.getName());
+ mDesc.setText(task.getDesc());
+ if (AutoFileSource.ENGINE.equals(mTask.getEngineName())) {
mFirstChar.setText("R");
mFirstCharBackground.setColor(getResources().getColor(R.color.color_r));
} else {
@@ -210,12 +245,45 @@ public class TaskListRecyclerView extends ThemeColorRecyclerView implements Scri
}
}
+
@OnClick(R.id.stop)
void stop() {
- if (mScriptEngine != null) {
- mScriptEngine.forceStop();
+ if (mTask != null) {
+ mTask.cancel();
+ }
+ }
+
+ void onItemClick(View view) {
+ if (mTask instanceof Task.PendingTask) {
+ TimedTaskSettingActivity_.intent(getContext())
+ .extra(TaskReceiver.EXTRA_TASK_ID, ((Task.PendingTask) mTask).getTimedTask().getId())
+ .start();
}
}
}
+ private class TaskGroupViewHolder extends ParentViewHolder {
+
+ TextView title;
+ ImageView icon;
+
+ TaskGroupViewHolder(@NonNull View itemView) {
+ super(itemView);
+ title = (TextView) itemView.findViewById(R.id.title);
+ icon = (ImageView) itemView.findViewById(R.id.icon);
+ itemView.setOnClickListener(view -> {
+ if (isExpanded()) {
+ collapseView();
+ } else {
+ expandView();
+ }
+ });
+ }
+
+ @Override
+ public void onExpansionToggled(boolean expanded) {
+ icon.setRotation(expanded ? -90 : 0);
+ }
+ }
+
}
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java
index fc403661..494ca5fd 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/task/TaskManagerFragment.java
@@ -3,20 +3,14 @@ package com.stardust.scriptdroid.ui.main.task;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.SwipeRefreshLayout;
-import android.view.MenuItem;
import android.view.View;
-import android.widget.PopupMenu;
-import android.widget.TextView;
-import com.stardust.autojs.core.console.ConsoleView;
-import com.stardust.autojs.core.console.StardustConsole;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.ui.main.ViewPagerFragment;
import com.stardust.scriptdroid.ui.widget.SimpleAdapterDataObserver;
import org.androidannotations.annotations.AfterViews;
-import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ViewById;
@@ -63,7 +57,7 @@ public class TaskManagerFragment extends ViewPagerFragment {
});
mSwipeRefreshLayout.setOnRefreshListener(() -> {
- mTaskListRecyclerView.updateEngineList();
+ mTaskListRecyclerView.refresh();
mTaskListRecyclerView.postDelayed(() -> {
if (mSwipeRefreshLayout != null)
mSwipeRefreshLayout.setRefreshing(false);
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/timing/TimedTaskSettingActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/timing/TimedTaskSettingActivity.java
new file mode 100644
index 00000000..4608c023
--- /dev/null
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/timing/TimedTaskSettingActivity.java
@@ -0,0 +1,232 @@
+package com.stardust.scriptdroid.ui.timing;
+
+import android.app.DatePickerDialog;
+import android.app.TimePickerDialog;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.TimePicker;
+import android.widget.Toast;
+
+import com.github.aakira.expandablelayout.ExpandableRelativeLayout;
+import com.stardust.autojs.execution.ExecutionConfig;
+import com.stardust.scriptdroid.R;
+import com.stardust.scriptdroid.external.ScriptIntents;
+import com.stardust.scriptdroid.model.script.ScriptFile;
+import com.stardust.scriptdroid.timing.TaskReceiver;
+import com.stardust.scriptdroid.timing.TimedTask;
+import com.stardust.scriptdroid.timing.TimedTaskManager;
+import com.stardust.scriptdroid.ui.BaseActivity;
+
+import org.androidannotations.annotations.AfterViews;
+import org.androidannotations.annotations.CheckedChange;
+import org.androidannotations.annotations.Click;
+import org.androidannotations.annotations.EActivity;
+import org.androidannotations.annotations.ViewById;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalDateTime;
+import org.joda.time.LocalTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+
+/**
+ * Created by Stardust on 2017/11/28.
+ */
+@EActivity(R.layout.activity_timed_task_setting)
+public class TimedTaskSettingActivity extends BaseActivity {
+
+
+ private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormat.forPattern("HH:mm");
+ private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern("yy-MM-dd");
+
+ @ViewById(R.id.toolbar)
+ Toolbar mToolbar;
+
+ @ViewById(R.id.timing_group)
+ RadioGroup mTimingGroup;
+
+ @ViewById(R.id.disposable_task_radio)
+ RadioButton mDisposableTaskRadio;
+
+ @ViewById(R.id.daily_task_radio)
+ RadioButton mDailyTaskRadio;
+
+ @ViewById(R.id.weekly_task_radio)
+ RadioButton mWeeklyTaskRadio;
+
+ @ViewById(R.id.disposable_task_time)
+ TextView mDisposableTaskTime;
+
+ @ViewById(R.id.disposable_task_date)
+ TextView mDisposableTaskDate;
+
+ @ViewById(R.id.daily_task_time_picker)
+ TimePicker mDailyTaskTimePicker;
+
+ @ViewById(R.id.weekly_task_time_picker)
+ TimePicker mWWeeklyTaskTimePicker;
+
+ private ScriptFile mScriptFile;
+ private TimedTask mTimedTask;
+
+ @Override
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ int taskId = getIntent().getIntExtra(TaskReceiver.EXTRA_TASK_ID, -1);
+ if (taskId != -1) {
+ mTimedTask = TimedTaskManager.getInstance().getTimedTask(taskId);
+ if (mTimedTask != null) {
+ mScriptFile = new ScriptFile(mTimedTask.getScriptPath());
+ }
+ } else {
+ String path = getIntent().getStringExtra(ScriptIntents.EXTRA_KEY_PATH);
+ if (TextUtils.isEmpty(path)) {
+ finish();
+ }
+ mScriptFile = new ScriptFile(path);
+ }
+
+ }
+
+ @AfterViews
+ void setupViews() {
+ setToolbarAsBack(getString(R.string.text_timed_task));
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ mToolbar.setSubtitle(mScriptFile.getName());
+ }
+ setUpTime();
+ }
+
+ private void setUpTime() {
+ mDisposableTaskDate.setText(DATE_FORMATTER.print(LocalDate.now()));
+ mDisposableTaskTime.setText(TIME_FORMATTER.print(LocalTime.now()));
+ if (mTimedTask == null) {
+ mDailyTaskRadio.setChecked(true);
+ return;
+ }
+ if (mTimedTask.isDisposable()) {
+ mDisposableTaskRadio.setChecked(true);
+ mDisposableTaskTime.setText(TIME_FORMATTER.print(mTimedTask.getMillis()));
+ mDisposableTaskDate.setText(DATE_FORMATTER.print(mTimedTask.getMillis()));
+ return;
+ }
+ if (mTimedTask.isDaily()) {
+ mDailyTaskRadio.setChecked(true);
+ LocalTime time = LocalTime.fromMillisOfDay(mTimedTask.getMillis());
+ mDailyTaskTimePicker.setCurrentHour(time.getHourOfDay());
+ mDailyTaskTimePicker.setCurrentMinute(time.getMinuteOfHour());
+ return;
+ }
+ // TODO: 2017/11/28 Weekly
+ }
+
+
+ @CheckedChange({R.id.daily_task_radio, R.id.weekly_task_radio, R.id.disposable_task_radio})
+ void onCheckedChanged(CompoundButton button) {
+ ExpandableRelativeLayout relativeLayout = findExpandableLayoutOf(button);
+ if (button.isChecked()) {
+ relativeLayout.post(relativeLayout::expand);
+ } else {
+ relativeLayout.collapse();
+ }
+
+ }
+
+ private ExpandableRelativeLayout findExpandableLayoutOf(CompoundButton button) {
+ ViewGroup parent = (ViewGroup) button.getParent();
+ for (int i = 0; i < parent.getChildCount(); i++) {
+ if (parent.getChildAt(i) == button) {
+ return ((ExpandableRelativeLayout) parent.getChildAt(i + 1));
+ }
+ }
+ throw new IllegalStateException("findExpandableLayout: button = " + button + ", parent = " + parent + ", childCount = " + parent.getChildCount());
+ }
+
+ @Click(R.id.disposable_task_time_container)
+ void showDisposableTaskTimePicker() {
+ LocalTime time = TIME_FORMATTER.parseLocalTime(mDisposableTaskTime.getText().toString());
+ new TimePickerDialog(this, (view, hourOfDay, minute) -> mDisposableTaskTime.setText(TIME_FORMATTER.print(new LocalTime(hourOfDay, minute))), time.getHourOfDay(), time.getMinuteOfHour(), true)
+ .show();
+
+ }
+
+
+ @Click(R.id.disposable_task_date_container)
+ void showDisposableTaskDatePicker() {
+ LocalDate date = DATE_FORMATTER.parseLocalDate(mDisposableTaskDate.getText().toString());
+ new DatePickerDialog(this, (view, year, month, dayOfMonth) ->
+ mDisposableTaskDate.setText(DATE_FORMATTER.print(new LocalDate(year, month, dayOfMonth)))
+ , date.getYear(), date.getMonthOfYear(), date.getDayOfMonth())
+ .show();
+ }
+
+ TimedTask createTimedTask() {
+ if (mDisposableTaskRadio.isChecked()) {
+ return createDisposableTask();
+ } else if (mDailyTaskRadio.isChecked()) {
+ return createDailyTask();
+ } else {
+ return createWeeklyTask();
+ }
+ }
+
+ private TimedTask createWeeklyTask() {
+ // TODO: 2017/11/28 Weekly
+ return null;
+ }
+
+ private TimedTask createDailyTask() {
+ LocalTime time = new LocalTime(mDailyTaskTimePicker.getCurrentHour(), mDailyTaskTimePicker.getCurrentMinute());
+ return TimedTask.dailyTask(time, mScriptFile.getPath(), new ExecutionConfig());
+ }
+
+ private TimedTask createDisposableTask() {
+ LocalTime time = TIME_FORMATTER.parseLocalTime(mDisposableTaskTime.getText().toString());
+ LocalDate date = DATE_FORMATTER.parseLocalDate(mDisposableTaskDate.getText().toString());
+ LocalDateTime dateTime = new LocalDateTime(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth(),
+ time.getHourOfDay(), time.getMinuteOfHour());
+ if (dateTime.isBefore(LocalDateTime.now())) {
+ Toast.makeText(this, R.string.text_disposable_task_time_before_now, Toast.LENGTH_SHORT).show();
+ return null;
+ }
+ return TimedTask.disposableTask(dateTime, mScriptFile.getPath(), ExecutionConfig.getDefault());
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_timed_task_setting, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.action_done) {
+ createOrUpdateTimedTask();
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ private void createOrUpdateTimedTask() {
+ TimedTask task = createTimedTask();
+ if (task == null)
+ return;
+ if (mTimedTask == null) {
+ TimedTaskManager.getInstance().addTask(task);
+ Toast.makeText(this, R.string.text_already_create, Toast.LENGTH_SHORT).show();
+ } else {
+ task.setId(mTimedTask.getId());
+ TimedTaskManager.getInstance().updateTask(task);
+ }
+ finish();
+ }
+}
diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/update/UpdateInfoDialogBuilder.java b/app/src/main/java/com/stardust/scriptdroid/ui/update/UpdateInfoDialogBuilder.java
index 1df1ea04..17211028 100644
--- a/app/src/main/java/com/stardust/scriptdroid/ui/update/UpdateInfoDialogBuilder.java
+++ b/app/src/main/java/com/stardust/scriptdroid/ui/update/UpdateInfoDialogBuilder.java
@@ -17,7 +17,7 @@ import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.BuildConfig;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.network.entity.VersionInfo;
-import com.stardust.scriptdroid.io.StorageFileProvider;
+import com.stardust.scriptdroid.storage.file.StorageFileProvider;
import com.stardust.scriptdroid.tool.IntentTool;
import com.stardust.util.DownloadTask;
import com.stardust.util.IntentUtil;
diff --git a/app/src/main/res/drawable-hdpi/ic_date_range_black_48dp.png b/app/src/main/res/drawable-hdpi/ic_date_range_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..a860637eed1494c76ac6b5a21efb4fc1ec8e7430
GIT binary patch
literal 249
zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY0wn)GsXhaw4tTmahEy=Vy}5Pj;Q#@*hqF1N
zB32btR>v3x%cr#!z6i0XJN|sX@Xba3BAiP@1a78k-3n7^WbvwaKHoCza8AZYN2Z(A
zOZuVP`nA>foGbbAA5qXq=Uj^@uHM;!5UcW;3nWScE))I#(@}W|*7B
z#Hljj>WBRfOq?P|vhzVahoxX?5Mj2kHY#Ixqg2YP)4X52mIb-#&CxTItWJ7yV5fSu
pO3kH|(94VOJeWFT^^z%8%*IPQl8@8|%mey`!PC{xWt~$(698iTU}XRR
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-hdpi/ic_schedule_black_48dp.png b/app/src/main/res/drawable-hdpi/ic_schedule_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..1dad2a853f166bebf7a323acac147c7761ee238a
GIT binary patch
literal 1029
zcmV+g1p51lP)YuG$3Q;k0nTI>0v4cdPUTbPU}Z9k4>_K83bzxlGZ%Br9A0D_
z3bPBJV;S-h+v45QJdNeZBXr`?kxa&NWJ|MGJSQOfj5CIhI{niN$H6iN#ro-8hcN
z7?JXen`k1ZMfea)WDGa55#?;mO^n47d5ee~I{5*MWeCU8ii?2b8HUC3HEr3~&X0++
z%Vh*qBjgHZCn`l`(303#Jz1A5)}t4u;q5H@(p{K_XNbru;1`U8N&14YyKH9`)RT
zX*dvfEEPNN+=d6SN)zbB*;BENRgVw#Jda5p#?j8PT{)t>KSo|aB@59TlWdC2)<;hQAL3vKOmZ1`Ed*C#lC7!eRrIVJcrO$(TxNKY3cAqSuj9abAvg)Wg==>o
zJcian3I&XHU+9lz=#5ZFA-F|m`G7J)^cdKvutJ;4EHh~()o$qR7ljq7W0cIa3#rbM
zVUHGA2%eOg&LGu;GVItw3!NY{-A}47WZ15S7TQB*`ixWqW!OrE7FtQAb1GHmfe
z3$>x=yHtA6Hx*i_Sufy46}mQmA-|i!@=x?hD+Eu7B`O!5*dI-eNtbGvjrMs-%;B}_7di)nRwj5wWCyUMT;RBx}?#v8~%
zDHqq#GHPd11$yAKG1Y6~Jf_DUo7W(2GuPV>_$ce+u2`NIG0AK$N5QS~*Y_#wL>W4k
zfUNeUul%R0P$A>o?SG#$zyq5NW4~v^o1WU
zP|0|Ild?lQKTP)`!k2}0S7$z3;plNp@*MT}&=5Nv
zJb<%qCSsC1@F4cSdmQb!;}9%XsXpJ@iPbUoqe{178lGn%vRXK{v5f1fS`+VK8hW#S
z#v`jQrr`}5vn|*6n1HN<
zy@gGwBTXHfaVz7nL|!K(r)J%~HH_j(PGApKrj2HrX=7#f-~^sxbjmNTqY*C-VIr0@
zlN0%fS!Jut;609}jRh!R
zSI*=CK4$=9nZ-=T(4SAakJH$Z7HVp0{-J&Xj+BT{S*hCH00000NkvXXu0mjfZ$j%k
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-mdpi/ic_date_range_black_48dp.png b/app/src/main/res/drawable-mdpi/ic_date_range_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..3e3ac404ddf414ac54e0cf7f70516476a53c23bd
GIT binary patch
literal 187
zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA0wn)(8}b0DCQlc~kP61P(~mMXJ20>;pAqr#
zy8d-$)JfHVxp1R+K3vfwtW%RwjI=NT-$AI7w^4VueN#Zm7PiEOh-ZW?Qqt=*MIgx
za`+|qi;phM}lDnEhnJ_|0FOkG5DXyq{gMKW0uYP?JJEYVrUQ+`@
zc8ch0`r=5`pirt8n+>;Ct<_YpZ2&VQo@2D#Yt&%+9T@~vnO2YnFHa>r1{@hchA1B4
zK}Qz}ek9`9AjW6WbVSD-3GD^P25>+$v(Rx=LK&_MvPE+U9akmP!IeR0(fo^!w-SoG
zGDxX)(;+)R(3L?*G`VgJIyy2?B}$kY6tSD6d5N4fxjXkn^_~g%Oq%RqOd-r7zN;i%
z?TqPc3GKs-CY+{Nsq3QUpnRWc{J2jW-eV38#Ey|_yW^kg9f|ql?eF>
z;Sf+*pvG9sXv!&|;NUPT1|$IzbZBU}wxs^!S51)z^WKy>Gn$>uQ@wEgeYH-&g*u4?
zY_4YuJ-Id{FIzZegMa;*@Oiw;R%W%z%4POF?E5^=SIofJ`1itam#1@HA7hlW28IiR
Mr>mdKI;Vst0QKW}y8r+H
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xhdpi/ic_schedule_black_48dp.png b/app/src/main/res/drawable-xhdpi/ic_schedule_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..68df97405d064575f79734ef0ab6c727e9b3c9c7
GIT binary patch
literal 1364
zcmV-a1*`grP)YQ+NcIT~l$u2T7
zGBPqUEYgWRxRj^)ih)dF0ZW^l&m{Wu1y67hyV9N(NhJsHBqNXj4(3tzp-2lM#~!@N
zd?ciEd6}IkCsnGskkLpChjBI)q(TK(G6S*T6fUAbqLgto;}MIF;vf>Ej;|00enby&
z&vDE_966K2a7vNq0~Et6T*BV0O(zQEnk>+Xwb`3Xc{RY0e~cAzL}&g)JYB}OoJk#i
z)N>Z!vkdX{C)(kFl^BJ1IE|aBB@Ff4!gR#Lq10lT)tTry30_Dk;zWEg(>%U)EGt`m
z`X1e1!adXwht}NBQjZ9=SfZ0h@$_c{Y_Kr{JqoEE7AWusqUA{n*rLQUh?XC1%t+5Q
zTRNvixA`(sh&Vhq5;~d3K&K?f!Pf)ybux%0GA<#I}(`J
z)qcN}cz{ZE=ka3j33Q&(^kzsr0NiHuVm1W=vA;Sj)}|7mK^;8zBoL1q&Ax?H0>Dp3
zPaYx=!;EHUrWW8_qbCCiKu5%|F0}wFBZlq5PobkAwE(F7*v|NJvC-s}R0F&oeoyq2
z(d3d;16-l*?fg)On7vaCu%FSJ&+%n|(PZsZ1FUQGrZ2usHkx!wH9%LRHxuzg9jgne
z1}Lh3*8EUMiCn4ya_U(1{}14zgx;r)Xq0pbr7?(w1zbL7MMjVecR0AX1#{51Nd
zrG;#Fh9b%@SQSn1v&m=p@}$w^QlgUQYW)fVi@B4k$Xkg=!*AwZB@VT`k0{4;BxR8{
zbLWTOPLC!odom1B{=ho;qTUDC312!OhV{fH&o#Q3Sjt1R#v52wwP{NLhIrqJSudt3
zoJ4ux`@sPO;xVJy_t;`jh9k;9*qG+|+4$rG1Y%!xtx|_A3S7$qME$};Xc`g2-3dgA
zxkkfVut^;sAcj|3lYQVbOW&YzQh9darE>T+Idex-&X5FI@>|*FGZ9O5}Q1~
zB3hoKge@v~5z+D;D`0^R3`evKViQZt))0^HZ-XToJl<7b%7Za~q%Dtlyu~}3o>*j6
zj|jpvE~AntRB;6}5RdLRVwna;ARf-(HW~;+BeydX@o*45aX<%tLp)u^Pn^rj_^~SI
z^E2Wt-_r(1-P=OKI!e5vf}4fb_-nSFc*SR#;wyUdN@U2*)Hq&&?gMwu#*BZSSD92Ks1OG*SHBtU#Mqr4SE6+3E+b{>=V}%_7h?nA!q+F
zLR`Co0j{TFa}*2A2YZ;N!o9QJAr%lLGcqU%4m<4=H5$KdJe=d#Wz
Gp$P!I`>>e+
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxhdpi/ic_schedule_black_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_schedule_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..93c9fdeb05b99c3f38d15f72666099c86d942384
GIT binary patch
literal 2046
zcmVK4B=M?;Mwzec`0sFdUYdnVA{F
zjOB*8%*@PzHH3739p4*CyOL(c+3)6!8dpz%9l*xENaQ88EeI#m_-^di?WI-3}qXdnF{{ILN?+>
zRMztXL)emLVIM}(h!;ay!^2c#F_(TU$BVfvpgRuMNpS-2<0Vwypa)htoVV~2E-Tmv
zD|BEco~AO6Rv69YZ0hkemX(ae!BAaTfoDLOPa6z0lr)|p;!K
zYWN{U&|h&gHKfQyidt^v>rl1rie}vdKeaY6m7_?JEtjL2#)iO?+r!Z4c-939vw=J4
zK$JRicfc856W!5dK%l?lTJE9+acIRof&M`2=#K^`1WL~gIuoa^%np>I?j)>xfWO_>
z^dJd+_}0IpC3`Qb32u&5F;OcbH%<9qFT*qy
ze5{CgED<|IIV{|f?ELRFqp+)TyuS|-O7VvJ!D(cIV1RNTEkga3b1sZc5Xzf%cOv5Q
zo?^ycYIK4s_)f85?GTAR>c4`~34(r#=0=0_8)Xr8UXa~jO
z-tWlT(_la$Ih%A+fV~GY@Sd*aEG>T)mEy&6UG52?XH3@=y#C8lKEAzx{
zzz$X=sI#~S^Bh@dAzpSWSd}1{A)c7sI*tx@lywQJ6WcPFj7=B!2U6B0$Q5_bCX%57
z)(Drp8LUeX+#w#@%OfNE;t8e3$^^;n`8^pqM?C)ISeYP~UxXH&5$zh{lVD|n5I3kN
zlM(4G*Fb9%G*oEO=VYK#?6F;}P0)^Fn@S1o0P$oh)+Wf|x9C==rA_8}7AFW63auJI
zXjcoDy3^tW$&=R032n4+sne`ZkhDAe1fk85SD`IVP%oiX&l8%o6IN|?f@*|Ty&Byp
zsJ+z*>Lj%43qo5dT&m3C1j(bjUkI&1xKy##2`UjVCcTjd*~*ZcwEoAuI4%A&u7=0Fi33Hkyw1L+4isM$F4cp``Ti`X1ySi8-S*+A
z1ShM<@Ub#Qt2v8&(Y+=D3kOqhnltAF(jr#N3!`i-qFXTA
zUwpPW#OGK(QKqP#izy;gjyQPPo6su6AiE+ca~KtQIbKD@m&J>1^w`l~VlOCH@9652C#beT|DuM`!zvQ*ltq6MvL2fs73o13DU+
zuFf_CmF{@aAI8{DTvwci4t0Erm)TiEF}>@kA`5fGW56BJp;+u}i*S&25#J>H3|Se5
zCzQLM)~+l{ESp-Egw*_k<~saa?#E8NzbpeCPoABd^%boIu$Y5C>j>`~uu5>%i|
z6^nhMyNlQr@rq9nAF&HM?9Qh?ku4^l1hnBhpFq-_O40_?;1kssY)3+>1AIece1cuA
zl1aYttYjw=bS&$9L;8-sB;oh~-(_gzU=r3p&@0=YVF%*06VC^FWqTbOoEj)a>$s2B
z#GwrjvOZ7*ebJ;l;Gl0LM5H3p*Lr84~tlt(Y5a+AEOLlHJ%~mSNdY0jx04IJ#%P{
zpY@;tBcCBKknJ?lvG3!n1}&+#~yaVoWJNls2qPEJlvPEJlv
cPR=Ie?_(4xF;~%+B>(^b07*qoM6N<$f@mMnr2qf`
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_date_range_black_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_date_range_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..907b69d83c702a08652ebf62fbbd4b3e183b0805
GIT binary patch
literal 718
zcmeAS@N?(olHy`uVBq!ia0vp^2SAvE1xWt5x}=AJfoZCzi(^OyDZOGOe^i9HEr*?
z-8&V!@=EMaWz}!q?>t)NPDY&icQZrI^Z4C~7e%bQ9`u#mnEF%m>5QA_cWTZ3x~X}7
zO8%0?dFN&o&rgxwX*~DK!esL|mrE{)&MbV@ru%f)mV1*mdpD&IDJiB?zJbfod1_K6$H9`k+x)>P}7#O}3Ffg21D#5_O
z#?Ww;VTQjU0|O63gB%}2L+cbrxdvOghAKvoe;ZsG7+!%wlYwCxm;@13oEvK9={vkU
z_;|YzL~sKWO!9(vLnxGeAc5)4*Hz4G7#RZ8!9pAOkW}%)4K@SY1d;+8%!;HW7p|lX
zCJIu*&EPN>%y)omgiA~G{GYI~cgwwyF4H`vwcnk)OyAw!a__n3wH^MKs?INucs$SV
z_1y`f?RhtX*7>s6KE1;G+hT6Xd(Z#AC$AM(TfJg_Zg(=yJ3V%?ebAd3emJxl%>V2;@7z{Il4}0Pyl!?;Y|639IUt97y85}Sb4q9e02kyA
AuK)l5
literal 0
HcmV?d00001
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_schedule_black_48dp.png b/app/src/main/res/drawable-xxxhdpi/ic_schedule_black_48dp.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e32a441ca5a8c8b0130b456cbbaa982abe197ff
GIT binary patch
literal 2718
zcmV;P3Ssq$P)G0000VQNkl6&`jI-@Fa@!w*XToP^kp1kUCq2m4T-l750XbLt&v;kL}Fzb%5uc=
z7H~2d5~wd^_aJSEscL>gJU55uIhSo|Pa!(6
zE$8wAa}m#d!N$bUo-9K=RL^+Mp&GAhIFE_cdptDVj+i-#CJ(1WZ*nvp@KZ;QVJwXv
zj*1Q;My^JR>~}`8HbGgJQT$Q#chE>;A;Y~$QB7uVf|p?+Q<0*&4(nxkqNq>TEA%By
z{do;3qPxgou`JIc1vifVL}7C#A_e!by(7r*I8tCgu_sX)$gf5G71*iZwSN^uX-U*t
zGJ@4eL0yl9u0jfG5@pz;qTuUuBe2W~hfkU4#pyT6m*L79o?`|Pkt!q
z)NETUQN>ckxF;yVR;4^s&<4duSfCx|pPL+KW4rUoA%=ZU8zT1{V%SOs5(h(Ag&6h#
z5j!0*>~H!J7n?B;G3+QJ)Xn&6*DR`tlN#nAMlGX^h_vP##Hhd6gt#eVn(?*ctlgW=
zv)F_gOn1|(_#a2}%8Om6}=$>?eqi5ozMw-L412-r48*Luqm
zH~^?L+WG27pk7AQhC(6-0HYDLrwLF6c|_@FS|)Y?t@z#GGlfc4Z{5JE~JTfNqG=0DN(&
z`al^{IRN-4oDB)>GUW5|9)SJtjP`tyb5lD2?OWg%d{CmEgl(JJ0c@|HjJ3hDUg}k_
z_Ng5}r!cnUhA1yF4N^M*n5Dcs1M%z}H%m^h`AB3)F1B;
zOZ5OoD(}vdcs5br^Gopn4h?>n>`Ub(c24yGc2l1w;n{TMC3>cM0DXc#MqHr0#QLco
zzy`{@GY_xS`$0RUdH`LNcV{VHslSaXN%a6qm3L<~Ua31l*;Ef8tL_HbKL9rXw**2CX0MEp17^#2Lj
z!HUhead`H$mD|yJ|8NY!8x{O^^v#w%O@9c}5W_yCU;Hn~oUOdXSi;tp%c(<*%5g7U
z;(bX{yC^@MC{*wkV%S1XrA0&+VrGl;Dg_zy){u$!C1twrJPF^{|r-~9OH|Zl$UvdsO@XM81Vx;RO^>jCpwUJBiPCxK>|2a}V=ufI
zuKq-+BR=^>d8vu$>|Bgqql{ur4exmo52^orxg$2IWE^5xEtk_ake{jEgKv&Nl#anR
z`!WMDY&!b|@cgiY@Xea!t=kdOm2f5Xh+z|`@pYTNiB9MIQ
z?TFd{;-iWQ2*Lu^z|6jg+KmLJj2xo$tG6w-_Cdnb!P?C^fPn0eTTp8$rC3VCq6d
z?MVW)6{5D93X-UrI)ekyJ_Kw6qBe!($?z_s_A-In0x{@pl4cm9mZv8ncpXuzqX$XS
z*Jv~ESwhj1oYDO^r6fgrelfb9P)SJcK@56^q<9H2=mtWwCQA^5&L;^*AO_8&10g!w
z@b3H}#NGbn5rd8=R4w=nF=!Q=5ocSm8bNHl7SfAG!#~X$;;K6f4DT(fBm!3;M$Ms&
zI4Wl@V$>)i(TXn-qo&1h1m(u}QoK(KB2vRD=RmHfpV50#yv|ZwrbCdh;j4S
z088vj17h5d^uk7c`2{hqmaVYJF^GB8aV{Bbl3^J2h;exiz%rL21@$(S*rHm$+7*Xw
z#ygOLs$~?dh+1ndqz);ltFTgrN00*hjlo1|U;ac2>~^fxf@hF|o5YqxVQZ!$1@|Bs
zEY^ZYks^AN%?Z<%j75s*b~0El!(B*Gy~|)S1TDi5-bae+Dq`Ytq{#kc4C@h;^|_E~
zNKxfEpBOogMx@A^7|-!^#!sC&fr&IBMOMoJ#LR9iK|IvJWQNiWuX-??sWc!Sn#Wee
zPzB#1p8K1Z8Oru_q!69hfnmJDKZxf(VMAi7gr^bTn#Ba}Wh95P8-3V-E|iibODSF0
zfIjTTp^V~QCNLZEt-EPOtewJYB&IFpFcP3EUm-ET5%T(}Be6#p{T5<#~omQez9oBi7W+i}WCMw&Fz#
zmZJt9qZg@F&K)dAB5EPmvjM4B%JF<0`l2(1LupN#D7tYOzaSy>HKQpbtrWevluyYc
z0o2I5jG_uhwFZat06)=;_)v~-xQqSiK!Kbt4CWGE;x}?deBOWLS;nv@9q`O)OLqow
z7B}$}6ZnGZ%x5XJng9R*
literal 0
HcmV?d00001
diff --git a/app/src/main/res/layout/activity_timed_task_setting.xml b/app/src/main/res/layout/activity_timed_task_setting.xml
new file mode 100644
index 00000000..bb8e461a
--- /dev/null
+++ b/app/src/main/res/layout/activity_timed_task_setting.xml
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_timed_task_setting.xml b/app/src/main/res/menu/menu_timed_task_setting.xml
new file mode 100644
index 00000000..51298029
--- /dev/null
+++ b/app/src/main/res/menu/menu_timed_task_setting.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/raw/mpl_20_full.txt b/app/src/main/res/raw/mpl_20_full.txt
index 319c95b6..92b4faeb 100644
--- a/app/src/main/res/raw/mpl_20_full.txt
+++ b/app/src/main/res/raw/mpl_20_full.txt
@@ -32,7 +32,7 @@ means a work that combines Covered Software with other material, in a separate f
means this document.
1.9. “Licensable”
-means having the right to grant, to the maximum extent possible, whether at the time of the initial grant or subsequently, any and all of the rights conveyed by this License.
+means having the right to grant, to the maximum extent possible, whether at the timeFlag of the initial grant or subsequently, any and all of the rights conveyed by this License.
1.10. “Modifications”
means any of the following:
@@ -127,7 +127,7 @@ If it is impossible for You to comply with any of the terms of this License with
5. Termination
-5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first time You have received toast of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the toast.
+5.1. The rights granted under this License will terminate automatically if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such Contributor explicitly and finally terminates Your grants, and (b) on an ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor notifies You of the non-compliance by some reasonable means, this is the first timeFlag You have received toast of non-compliance with this License from such Contributor, and You become compliant prior to 30 days after Your receipt of the toast.
5.2. If You initiate litigation against any entity by asserting a patent infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate.
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a48c192d..4eee01e2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -313,5 +313,13 @@
key_documentation_source
文档源
发送
- 定时运行
+ 定时任务
+ 运行中脚本
+ 完成
+ 只运行一次
+ 每天运行
+ 按星期运行
+ 定时
+ 任务时间小于当前时间
+ 下次运行
diff --git a/common/src/main/java/com/stardust/pio/PFile.java b/common/src/main/java/com/stardust/pio/PFile.java
index bbe5d2d4..ce826f54 100644
--- a/common/src/main/java/com/stardust/pio/PFile.java
+++ b/common/src/main/java/com/stardust/pio/PFile.java
@@ -47,10 +47,7 @@ public class PFile extends File {
} else {
mSimplifiedName = PFiles.getNameWithoutExtension(getName());
}
- mSimplifyPath = getPath();
- if (mSimplifyPath.startsWith(Environment.getExternalStorageDirectory().getPath())) {
- mSimplifyPath = mSimplifyPath.substring(Environment.getExternalStorageDirectory().getPath().length());
- }
+ mSimplifyPath = PFiles.getSimplifiedPath(getPath());
}
public boolean renameTo(String newName) {
diff --git a/common/src/main/java/com/stardust/pio/PFiles.java b/common/src/main/java/com/stardust/pio/PFiles.java
index cc3ff216..bf7988a1 100644
--- a/common/src/main/java/com/stardust/pio/PFiles.java
+++ b/common/src/main/java/com/stardust/pio/PFiles.java
@@ -354,4 +354,11 @@ public class PFiles {
String pre = "KMGTPE".substring(exp - 1, exp);
return String.format(Locale.getDefault(), "%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
+
+ public static String getSimplifiedPath(String path) {
+ if (path.startsWith(Environment.getExternalStorageDirectory().getPath())) {
+ return path.substring(Environment.getExternalStorageDirectory().getPath().length());
+ }
+ return path;
+ }
}