add: supports for daily task and disposable task
@@ -86,6 +86,7 @@
|
||||
<activity android:name=".ui.log.LogActivity_"/>
|
||||
<activity android:name=".ui.doc.DocumentationActivity_"/>
|
||||
<activity android:name=".ui.shortcut.ShortcutIconSelectActivity_"/>
|
||||
<activity android:name=".ui.timing.TimedTaskSettingActivity_"/>
|
||||
<activity
|
||||
android:name=".ui.shortcut.ShortcutCreateActivity"
|
||||
android:theme="@style/AppTheme.Transparent"/>
|
||||
@@ -102,6 +103,7 @@
|
||||
android:name=".ui.error.IssueReporterActivity"
|
||||
android:theme="@style/IssueReporterTheme"/>
|
||||
|
||||
|
||||
<service android:name=".external.ScriptExecutionIntentService"/>
|
||||
|
||||
<activity android:name=".external.tasker.TaskPrefEditActivity_"/>
|
||||
|
||||
@@ -234,14 +234,14 @@ exports.puts = util.deprecate(function() {
|
||||
<p>When called, <code>util.deprecate()</code> will return a function that will emit a
|
||||
<code>DeprecationWarning</code> using the <code>process.on('warning')</code> event. By default,
|
||||
this warning will be emitted and printed to <code>stderr</code> exactly once, the first
|
||||
time it is called. After the warning is emitted, the wrapped <code>function</code>
|
||||
timeFlag it is called. After the warning is emitted, the wrapped <code>function</code>
|
||||
is called.</p>
|
||||
<p>If either the <code>--no-deprecation</code> or <code>--no-warnings</code> command line flags are
|
||||
used, or if the <code>process.noDeprecation</code> property is set to <code>true</code> <em>prior</em> to
|
||||
the first deprecation warning, the <code>util.deprecate()</code> method does nothing.</p>
|
||||
<p>If the <code>--trace-deprecation</code> or <code>--trace-warnings</code> command line flags are set,
|
||||
or the <code>process.traceDeprecation</code> property is set to <code>true</code>, a warning and a
|
||||
stack trace are printed to <code>stderr</code> the first time the deprecated function is
|
||||
stack trace are printed to <code>stderr</code> the first timeFlag the deprecated function is
|
||||
called.</p>
|
||||
<p>If the <code>--throw-deprecation</code> command line flag is set, or the
|
||||
<code>process.throwDeprecation</code> property is set to <code>true</code>, then an exception will be
|
||||
@@ -447,7 +447,7 @@ via the <code>util.inspect.styles</code> and <code>util.inspect.colors</code> pr
|
||||
<li><code>regexp</code> - <code>red</code></li>
|
||||
<li><code>null</code> - <code>bold</code></li>
|
||||
<li><code>undefined</code> - <code>grey</code></li>
|
||||
<li><code>special</code> - <code>cyan</code> (only applied to functions at this time)</li>
|
||||
<li><code>special</code> - <code>cyan</code> (only applied to functions at this timeFlag)</li>
|
||||
<li><code>name</code> - (no styling)</li>
|
||||
</ul>
|
||||
<p>The predefined color codes are: <code>white</code>, <code>grey</code>, <code>black</code>, <code>blue</code>, <code>cyan</code>,
|
||||
|
||||
@@ -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) (<C-v>) 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).
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<M> {
|
||||
|
||||
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 +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.stardust.scriptdroid.timing;
|
||||
package com.stardust.scriptdroid.storage.database;
|
||||
|
||||
import com.raizlabs.android.dbflow.annotation.Database;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.stardust.scriptdroid.io;
|
||||
package com.stardust.scriptdroid.storage.file;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetManager;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.stardust.scriptdroid.io;
|
||||
package com.stardust.scriptdroid.storage.file;
|
||||
|
||||
import android.os.Environment;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<TimedTask> mTimedTaskModelAdapter;
|
||||
private Context mContext;
|
||||
private PublishSubject<ModelChange<TimedTask>> 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<TimedTask>() {
|
||||
@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<TimedTask> 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<TimedTask> getAllTasks() {
|
||||
return RXSQLite.rx(SQLite.select().from(TimedTask.class))
|
||||
@@ -69,10 +105,31 @@ public class TimedTaskManager {
|
||||
|
||||
}
|
||||
|
||||
public Observable<ModelChange<TimedTask>> getTimeTaskChanges() {
|
||||
return mTimedTaskChanges;
|
||||
}
|
||||
|
||||
public void notifyTaskScheduled(TimedTask timedTask) {
|
||||
timedTask.setScheduled(true);
|
||||
mTimedTaskModelAdapter.update(timedTask);
|
||||
|
||||
}
|
||||
|
||||
public List<TimedTask> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<Task> {
|
||||
|
||||
protected List<Task> mTasks = new ArrayList<>();
|
||||
private String mTitle;
|
||||
|
||||
protected TaskGroup(String title) {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Task> 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<TimedTask> 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<ScriptEngine> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<ScriptEngine> mScriptEngines = new ArrayList<>();
|
||||
private final List<TaskGroup> 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<TimedTask> 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<ViewHolder> {
|
||||
private class Adapter extends ExpandableRecyclerAdapter<TaskGroup, Task, TaskGroupViewHolder, TaskViewHolder> {
|
||||
|
||||
public Adapter(@NonNull List<TaskGroup> 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<Task> {
|
||||
|
||||
@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<TaskGroup, Task> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
BIN
app/src/main/res/drawable-hdpi/ic_date_range_black_48dp.png
Normal file
|
After Width: | Height: | Size: 249 B |
BIN
app/src/main/res/drawable-hdpi/ic_schedule_black_48dp.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
app/src/main/res/drawable-mdpi/ic_date_range_black_48dp.png
Normal file
|
After Width: | Height: | Size: 187 B |
BIN
app/src/main/res/drawable-mdpi/ic_schedule_black_48dp.png
Normal file
|
After Width: | Height: | Size: 687 B |
BIN
app/src/main/res/drawable-xhdpi/ic_date_range_black_48dp.png
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
app/src/main/res/drawable-xhdpi/ic_schedule_black_48dp.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
app/src/main/res/drawable-xxhdpi/ic_date_range_black_48dp.png
Normal file
|
After Width: | Height: | Size: 481 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_schedule_black_48dp.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_date_range_black_48dp.png
Normal file
|
After Width: | Height: | Size: 718 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_schedule_black_48dp.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
192
app/src/main/res/layout/activity_timed_task_setting.xml
Normal file
@@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<com.stardust.theme.widget.ThemeColorToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:layout_marginTop="12dp"
|
||||
app:cardBackgroundColor="@android:color/white"
|
||||
app:cardCornerRadius="2dp"
|
||||
app:cardElevation="1dp"
|
||||
app:cardUseCompatPadding="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/text_timing"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/timing_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/daily_task_radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:text="@string/text_daily_task"/>
|
||||
|
||||
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
|
||||
android:id="@+id/daily_task_relative_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:ael_expanded="false"
|
||||
app:ael_interpolator="fastOutSlowIn"
|
||||
app:ael_orientation="vertical">
|
||||
|
||||
<TimePicker
|
||||
android:id="@+id/daily_task_time_picker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:timePickerMode="spinner"/>
|
||||
|
||||
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/disposable_task_radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:text="@string/text_disposable_task"/>
|
||||
|
||||
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="36dp"
|
||||
app:ael_expanded="false"
|
||||
app:ael_interpolator="fastOutSlowIn"
|
||||
app:ael_orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/disposable_task_time_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="6dp"
|
||||
android:paddingTop="6dp">
|
||||
|
||||
<com.stardust.theme.widget.ThemeColorImageViewCompat
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center"
|
||||
android:src="@drawable/ic_schedule_black_48dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/disposable_task_time"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#202020"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/disposable_task_date_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@+id/disposable_task_time_container"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="6dp">
|
||||
|
||||
<com.stardust.theme.widget.ThemeColorImageViewCompat
|
||||
android:id="@+id/disposable_task_date_icon"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center"
|
||||
android:src="@drawable/ic_date_range_black_48dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/disposable_task_date"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#202020"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/weekly_task_radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:text="@string/text_weekly_task"/>
|
||||
|
||||
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:ael_expanded="false"
|
||||
app:ael_interpolator="fastOutSlowIn"
|
||||
app:ael_orientation="vertical">
|
||||
|
||||
<TimePicker
|
||||
android:id="@+id/weekly_task_time_picker"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:timePickerMode="spinner"/>
|
||||
|
||||
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
|
||||
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
</LinearLayout>
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
||||
10
app/src/main/res/menu/menu_timed_task_setting.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_done"
|
||||
android:icon="@drawable/ic_done_white_48dp"
|
||||
android:title="@string/text_done"
|
||||
app:showAsAction="always"/>
|
||||
</menu>
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -313,5 +313,13 @@
|
||||
<string name="key_documentation_source">key_documentation_source</string>
|
||||
<string name="text_documentation_source">文档源</string>
|
||||
<string name="text_send">发送</string>
|
||||
<string name="text_timed_task">定时运行</string>
|
||||
<string name="text_timed_task">定时任务</string>
|
||||
<string name="text_running_task">运行中脚本</string>
|
||||
<string name="text_done">完成</string>
|
||||
<string name="text_disposable_task">只运行一次</string>
|
||||
<string name="text_daily_task">每天运行</string>
|
||||
<string name="text_weekly_task">按星期运行</string>
|
||||
<string name="text_timing">定时</string>
|
||||
<string name="text_disposable_task_time_before_now">任务时间小于当前时间</string>
|
||||
<string name="text_next_run_time">下次运行</string>
|
||||
</resources>
|
||||
|
||||