add: timed task

This commit is contained in:
hyb1996
2017-11-28 02:26:05 +08:00
parent 9951ffae7a
commit e8bab643af
16 changed files with 190 additions and 125 deletions

3
.idea/modules.xml generated
View File

@@ -2,7 +2,8 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/NoRootScriptDroid.iml" filepath="$PROJECT_DIR$/NoRootScriptDroid.iml" /> <module fileurl="file://$PROJECT_DIR$/Auto.js.iml" filepath="$PROJECT_DIR$/Auto.js.iml" />
<module fileurl="file://C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" filepath="C:\Users\Stardust\Documents\AndroidProjects\Auto.js\NoRootScriptDroid.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" /> <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/autojs/autojs.iml" filepath="$PROJECT_DIR$/autojs/autojs.iml" /> <module fileurl="file://$PROJECT_DIR$/autojs/autojs.iml" filepath="$PROJECT_DIR$/autojs/autojs.iml" />
<module fileurl="file://$PROJECT_DIR$/automator/automator.iml" filepath="$PROJECT_DIR$/automator/automator.iml" /> <module fileurl="file://$PROJECT_DIR$/automator/automator.iml" filepath="$PROJECT_DIR$/automator/automator.iml" />

View File

@@ -124,10 +124,13 @@ dependencies {
exclude group: 'com.android.support' exclude group: 'com.android.support'
}) })
annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0'
//stor //dbflow
compile 'com.pushtorefresh.storio2:sqlite:2.1.0' annotationProcessor "com.github.Raizlabs.DBFlow:dbflow-processor:4.1.2"
compile 'com.pushtorefresh.storio2:sqlite-annotations:2.1.0' compile "com.github.Raizlabs.DBFlow:dbflow-core:4.1.2"
annotationProcessor 'com.pushtorefresh.storio2:sqlite-annotations-processor:2.1.0' compile "com.github.Raizlabs.DBFlow:dbflow:4.1.2"
compile "com.github.Raizlabs.DBFlow:dbflow-rx2:4.1.2"
//joda time
compile 'joda-time:joda-time:2.9.9'
// Tasker Plugin // Tasker Plugin
compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3' compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3'
compile 'com.flurry.android:analytics:7.0.0@aar' compile 'com.flurry.android:analytics:7.0.0@aar'

View File

@@ -206,8 +206,6 @@
</intent-filter> </intent-filter>
</service> </service>
<service android:name=".timing.TimedTaskService"/>
<receiver android:name=".external.widget.ScriptWidget"> <receiver android:name=".external.widget.ScriptWidget">
<intent-filter> <intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/> <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
@@ -224,7 +222,7 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<receiver android:name=".timing.TaskSchedulerReceiver"> <receiver android:name=".timing.TimedTaskScheduler">
<intent-filter> <intent-filter>
<action android:name="com.stardust.autojs.action.check_task"/> <action android:name="com.stardust.autojs.action.check_task"/>
</intent-filter> </intent-filter>

View File

@@ -1,8 +1,5 @@
package com.stardust.scriptdroid; package com.stardust.scriptdroid;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
@@ -15,14 +12,14 @@ import com.bumptech.glide.request.transition.Transition;
import com.flurry.android.FlurryAgent; import com.flurry.android.FlurryAgent;
import com.nickandjerry.dynamiclayoutinflator.lib.ImageLoader; import com.nickandjerry.dynamiclayoutinflator.lib.ImageLoader;
import com.nickandjerry.dynamiclayoutinflator.lib.util.Drawables; import com.nickandjerry.dynamiclayoutinflator.lib.util.Drawables;
import com.raizlabs.android.dbflow.config.FlowManager;
import com.squareup.leakcanary.LeakCanary; import com.squareup.leakcanary.LeakCanary;
import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.autojs.key.GlobalKeyObserver; import com.stardust.scriptdroid.autojs.key.GlobalKeyObserver;
import com.stardust.scriptdroid.autojs.record.GlobalRecorder; import com.stardust.scriptdroid.autojs.record.GlobalRecorder;
import com.stardust.scriptdroid.network.GlideApp; import com.stardust.scriptdroid.network.GlideApp;
import com.stardust.scriptdroid.timing.TaskSchedulerReceiver; import com.stardust.scriptdroid.timing.TimedTaskScheduler;
import com.stardust.scriptdroid.tool.CrashHandler; import com.stardust.scriptdroid.tool.CrashHandler;
import com.stardust.scriptdroid.tool.JsBeautifierFactory;
import com.stardust.scriptdroid.ui.error.ErrorReportActivity; import com.stardust.scriptdroid.ui.error.ErrorReportActivity;
import com.stardust.theme.ThemeColor; import com.stardust.theme.ThemeColor;
import com.stardust.theme.ThemeColorManager; import com.stardust.theme.ThemeColorManager;
@@ -71,14 +68,14 @@ public class App extends MultiDexApplication {
} }
private void init() { private void init() {
FlowManager.init(this);
ThemeColorManager.setDefaultThemeColor(new ThemeColor(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorAccent))); ThemeColorManager.setDefaultThemeColor(new ThemeColor(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorPrimaryDark), getResources().getColor(R.color.colorAccent)));
ThemeColorManager.init(this); ThemeColorManager.init(this);
AutoJs.initInstance(this); AutoJs.initInstance(this);
JsBeautifierFactory.initJsBeautify(this, "js/jsbeautify.js");
GlobalKeyObserver.getSingleton(); GlobalKeyObserver.getSingleton();
GlobalRecorder.initSingleton(this); GlobalRecorder.initSingleton(this);
setupDrawableImageLoader(); setupDrawableImageLoader();
TaskSchedulerReceiver.setupRepeating(this); TimedTaskScheduler.setupRepeating(this);
} }
private void setupDrawableImageLoader() { private void setupDrawableImageLoader() {

View File

@@ -1,26 +1,79 @@
package com.stardust.scriptdroid.timing; package com.stardust.scriptdroid.timing;
import android.content.Intent; 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 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;
/** /**
* Created by Stardust on 2017/11/27. * Created by Stardust on 2017/11/27.
*/ */
@Table(database = TimedTaskDatabase.class)
public class TimedTask { public class TimedTask {
private static final int FLAG_DISPOSABLE = 0;
public final static int FLAG_SUNDAY = 0x1;
public final static int FLAG_MONDAY = 0x2;
public final static int FLAG_TUESDAY = 0x4;
public final static int FLAG_WEDNESDAY = 0x8;
public final static int FLAG_THURSDAY = 0x10;
public final static int FLAG_FRIDAY = 0x20;
public final static int FLAG_SATURDAY = 0x40;
private static final int FLAG_EVERYDAY = 0x7F;
@PrimaryKey(autoincrement = true)
@Column(name = "id")
int mId; int mId;
boolean mDisposable; @Column(name = "days_of_week")
int mDaysOfWeek;
@Column(name = "scheduled")
boolean mScheduled; boolean mScheduled;
public boolean isDisposable() { @Column(name = "delay")
return mDisposable; private long mDelay = 0;
@Column(name = "interval")
private long mInterval = 0;
@Column(name = "loop_times")
private int mLoopTimes = 1;
@Column(name = "millis")
private long mMillis;
@Column(name = "script_path")
private String mScriptPath;
public TimedTask() {
} }
public void setDisposable(boolean disposable) { public TimedTask(long millis, int daysOfWeek, String scriptPath, ExecutionConfig config) {
mDisposable = disposable; mMillis = millis;
mDaysOfWeek = daysOfWeek;
mScriptPath = scriptPath;
mDelay = config.delay;
mLoopTimes = config.loopTimes;
mInterval = config.interval;
}
public boolean isDisposable() {
return mDaysOfWeek == FLAG_DISPOSABLE;
} }
public boolean isScheduled() { public boolean isScheduled() {
@@ -32,7 +85,16 @@ public class TimedTask {
} }
public long getNextTime() { public long getNextTime() {
return 0; if (isDisposable()) {
return mMillis;
}
// TODO: 2017/11/28 day of week
LocalTime time = LocalTime.fromMillisOfDay(mMillis);
long nextTimeMillis = time.toDateTimeToday().getMillis();
if (System.currentTimeMillis() > nextTimeMillis) {
return nextTimeMillis + TimeUnit.DAYS.toMillis(1);
}
return nextTimeMillis;
} }
public int getId() { public int getId() {
@@ -40,6 +102,20 @@ public class TimedTask {
} }
public Intent createIntent() { public Intent createIntent() {
return null; return new Intent(TaskReceiver.ACTION_TASK)
.putExtra(TaskReceiver.EXTRA_TASK_ID, mId)
.putExtra(ScriptIntents.EXTRA_KEY_PATH, mScriptPath)
.putExtra(ScriptIntents.EXTRA_KEY_DELAY, mDelay)
.putExtra(ScriptIntents.EXTRA_KEY_LOOP_TIMES, mLoopTimes)
.putExtra(ScriptIntents.EXTRA_KEY_LOOP_INTERVAL, mInterval);
} }
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);
}
} }

View File

@@ -0,0 +1,10 @@
package com.stardust.scriptdroid.timing;
import com.raizlabs.android.dbflow.annotation.Database;
/**
* Created by Stardust on 2017/11/28.
*/
@Database(version = 1)
public class TimedTaskDatabase {
}

View File

@@ -1,11 +1,18 @@
package com.stardust.scriptdroid.timing; package com.stardust.scriptdroid.timing;
import com.pushtorefresh.storio2.sqlite.StorIOSQLite; import android.content.Context;
import com.pushtorefresh.storio2.sqlite.impl.DefaultStorIOSQLite; import android.database.sqlite.SQLiteDatabase;
import com.pushtorefresh.storio2.sqlite.queries.Query; import android.database.sqlite.SQLiteOpenHelper;
import io.reactivex.Observable; import com.raizlabs.android.dbflow.config.FlowManager;
import com.raizlabs.android.dbflow.rx2.language.RXSQLite;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import com.raizlabs.android.dbflow.structure.ModelAdapter;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.schedulers.Schedulers;
/** /**
* Created by Stardust on 2017/11/27. * Created by Stardust on 2017/11/27.
@@ -13,46 +20,59 @@ import io.reactivex.Observable;
public class TimedTaskManager { public class TimedTaskManager {
static final String TABLE_NAME = "timed_tasks"; private static TimedTaskManager sInstance;
private ModelAdapter<TimedTask> mTimedTaskModelAdapter;
private static TimedTaskManager sInstance = new TimedTaskManager();
private StorIOSQLite mStorIOSQLite;
public static TimedTaskManager getInstance() { public static TimedTaskManager getInstance() {
if (sInstance == null) {
sInstance = new TimedTaskManager();
}
return sInstance; return sInstance;
} }
public TimedTaskManager() { public TimedTaskManager() {
/* mStorIOSQLite = DefaultStorIOSQLite.builder() mTimedTaskModelAdapter = FlowManager.getModelAdapter(TimedTask.class);
.sqliteOpenHelper()
.build();*/
} }
public void notifyTaskFinished(int id) { public void notifyTaskFinished(int id) {
getTaskById(id).subscribe(timedTask -> { getTaskById(id).subscribe(timedTask -> {
if (timedTask.isDisposable()) { if (timedTask.isDisposable()) {
removeTask(id); removeTask(id).subscribe();
} else { } else {
timedTask.setScheduled(false);
mTimedTaskModelAdapter.update(timedTask);
} }
}); });
} }
private Observable<TimedTask> getTaskById(int id) { private Flowable<TimedTask> getTaskById(int id) {
return null; return RXSQLite.rx(SQLite.select()
.from(TimedTask.class)
.where(TimedTask_Table.id.is(id)))
.queryStreamResults()
.subscribeOn(Schedulers.io());
} }
private void removeTask(int id) { private Completable removeTask(int id) {
return RXSQLite.rx(SQLite.delete(TimedTaskDatabase.class)
.where(TimedTask_Table.id.is(id)))
.execute()
.subscribeOn(Schedulers.io());
} }
public Observable<TimedTask> getAllTasks() { public Flowable<TimedTask> getAllTasks() {
return null; return RXSQLite.rx(SQLite.select().from(TimedTask.class))
.queryStreamResults()
.subscribeOn(Schedulers.io());
} }
public Observable<TimedTask> getFutureTasksInMillis(long millis) { public void notifyTaskScheduled(TimedTask timedTask) {
long current = System.currentTimeMillis(); timedTask.setScheduled(true);
return getAllTasks().filter(timedTask -> mTimedTaskModelAdapter.update(timedTask);
timedTask.getNextTime() - current <= millis);
} }
} }

View File

@@ -18,12 +18,13 @@ import io.reactivex.schedulers.Schedulers;
* Created by Stardust on 2017/11/27. * Created by Stardust on 2017/11/27.
*/ */
public class TaskSchedulerReceiver extends BroadcastReceiver { public class TimedTaskScheduler extends BroadcastReceiver {
public static final String ACTION_CHECK_TASK = "com.stardust.autojs.action.check_task"; public static final String ACTION_CHECK_TASK = "com.stardust.autojs.action.check_task";
private static final String LOG_TAG = "TaskSchedulerReceiver"; private static final String LOG_TAG = "TimedTaskScheduler";
private static final int REQUEST_CODE = 4056; private static final int REQUEST_CODE = 4000;
private static final long INTERVAL = 60 * 1000; private static final long INTERVAL = 60 * 1000;
private static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1);
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
@@ -33,29 +34,46 @@ public class TaskSchedulerReceiver extends BroadcastReceiver {
public static void checkTasks(Context context) { public static void checkTasks(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
TimedTaskManager.getInstance().getFutureTasksInMillis(TimeUnit.HOURS.toMillis(1)) TimedTaskManager.getInstance().getAllTasks()
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(timedTask -> scheduleTask(context, alarmManager, timedTask)); .subscribe(timedTask -> scheduleTaskIfNeeded(context, alarmManager, timedTask));
} }
private static void scheduleTask(Context context, AlarmManager alarmManager, TimedTask timedTask) { public static void scheduleTaskIfNeeded(Context context, AlarmManager alarmManager, TimedTask timedTask) {
long millis = timedTask.getNextTime(); long millis = timedTask.getNextTime();
if (timedTask.isScheduled() || millis - System.currentTimeMillis() > ONE_HOUR) {
return;
}
scheduleTask(context, alarmManager, timedTask, millis);
TimedTaskManager.getInstance()
.notifyTaskScheduled(timedTask);
}
public static void scheduleTaskIfNeeded(Context context, TimedTask timedTask) {
scheduleTaskIfNeeded(context, (AlarmManager) context.getSystemService(Context.ALARM_SERVICE), timedTask);
}
private static void scheduleTask(Context context, AlarmManager alarmManager, TimedTask timedTask, long millis) {
if (millis <= System.currentTimeMillis()) {
context.sendBroadcast(timedTask.createIntent());
return;
}
// FIXME: 2017/11/28 requestCode may > 65535
PendingIntent op = PendingIntent.getBroadcast(context, REQUEST_CODE + 1 + timedTask.getId(), PendingIntent op = PendingIntent.getBroadcast(context, REQUEST_CODE + 1 + timedTask.getId(),
timedTask.createIntent().setAction(TaskReceiver.ACTION_TASK), timedTask.createIntent(), PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, millis, op); alarmManager.setExact(AlarmManager.RTC_WAKEUP, millis, op);
} else { } else {
alarmManager.set(AlarmManager.RTC_WAKEUP, millis, op); alarmManager.set(AlarmManager.RTC_WAKEUP, millis, op);
} }
} }
public static void setupRepeating(Context context) { public static void setupRepeating(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000,
INTERVAL, PendingIntent.getBroadcast(context, REQUEST_CODE, INTERVAL, PendingIntent.getBroadcast(context, REQUEST_CODE,
new Intent(TaskSchedulerReceiver.ACTION_CHECK_TASK), PendingIntent.FLAG_UPDATE_CURRENT)); new Intent(TimedTaskScheduler.ACTION_CHECK_TASK), PendingIntent.FLAG_UPDATE_CURRENT));
} }
} }

View File

@@ -1,41 +0,0 @@
package com.stardust.scriptdroid.timing;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
/**
* Created by Stardust on 2017/11/27.
*/
public class TimedTaskService extends Service {
private static final int REQUEST_CODE_CHECK_TASK = 4056;
private AlarmManager mAlarmManager;
@Override
public void onCreate() {
super.onCreate();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
}
}

View File

@@ -1,25 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.annotation.SuppressLint;
import android.app.Application;
import com.stardust.autojs.script.JsBeautifier;
/**
* Created by Stardust on 2017/4/18.
*/
public class JsBeautifierFactory {
@SuppressLint("StaticFieldLeak")
private static JsBeautifier jsBeautifier;
public static JsBeautifier getJsBeautify() {
return jsBeautifier;
}
public static void initJsBeautify(Application context, String path) {
jsBeautifier = new JsBeautifier(context, path);
jsBeautifier.prepare();
}
}

View File

@@ -26,7 +26,6 @@ import com.stardust.scriptdroid.BuildConfig;
import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.timing.TimedTaskService;
import com.stardust.scriptdroid.ui.common.NotAskAgainDialog; import com.stardust.scriptdroid.ui.common.NotAskAgainDialog;
import com.stardust.scriptdroid.ui.doc.OnlineDocsFragment_; import com.stardust.scriptdroid.ui.doc.OnlineDocsFragment_;
import com.stardust.scriptdroid.ui.floating.FloatyWindowManger; import com.stardust.scriptdroid.ui.floating.FloatyWindowManger;

View File

@@ -22,8 +22,8 @@ android {
compileOptions { compileOptions {
targetCompatibility 1.8 sourceCompatibility JavaVersion.VERSION_1_8
sourceCompatibility 1.8 targetCompatibility JavaVersion.VERSION_1_8
} }
} }

View File

@@ -13,6 +13,10 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false

View File

@@ -13,6 +13,7 @@ android {
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
buildTypes { buildTypes {
release { release {
minifyEnabled false minifyEnabled false

View File

@@ -1,4 +1,4 @@
#Thu Oct 26 16:01:06 CST 2017 #Mon Nov 27 21:40:02 CST 2017
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

View File

@@ -20,6 +20,10 @@ android {
disable 'MissingTranslation' disable 'MissingTranslation'
disable 'ExtraTranslation' disable 'ExtraTranslation'
} }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes { buildTypes {
debug { debug {
minifyEnabled false minifyEnabled false