add: supports for daily task and disposable task

This commit is contained in:
hyb1996
2017-11-28 20:59:29 +08:00
parent e8bab643af
commit 97382965da
51 changed files with 1106 additions and 171 deletions

View File

@@ -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);

View File

@@ -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;

View 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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 +
'}';
}
}

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.timing;
package com.stardust.scriptdroid.storage.database;
import com.raizlabs.android.dbflow.annotation.Database;

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.io;
package com.stardust.scriptdroid.storage.file;
import android.content.Context;
import android.content.res.AssetManager;

View File

@@ -1,4 +1,4 @@
package com.stardust.scriptdroid.io;
package com.stardust.scriptdroid.storage.file;
import android.os.Environment;

View File

@@ -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;

View File

@@ -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;
/**

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;

View 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_;

View File

@@ -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_;

View File

@@ -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;

View File

@@ -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.
*/

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -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;