opt(timing): request for ignore battery optimization; optimize TimedTaskScheduler to schedule task

This commit is contained in:
hyb1996
2018-09-09 15:10:31 +08:00
parent f62958655a
commit e09966505c
8 changed files with 73 additions and 31 deletions

Binary file not shown.

View File

@@ -8,8 +8,8 @@ android {
applicationId "org.autojs.autojs"
minSdkVersion 17
targetSdkVersion 23
versionCode 410
versionName "4.0.2 Alpha5"
versionCode 411
versionName "4.0.2 Alpha6"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {

View File

@@ -12,6 +12,7 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<!-- 非Auto.js运行必需不会主动申请某些脚本可以自行申请-->

View File

@@ -27,7 +27,6 @@ import org.autojs.autojs.tool.CrashHandler;
import org.autojs.autojs.ui.error.ErrorReportActivity;
import com.stardust.theme.ThemeColor;
import com.stardust.theme.ThemeColorManager;
import com.stardust.util.UiHandler;
import java.lang.ref.WeakReference;
@@ -81,7 +80,7 @@ public class App extends MultiDexApplication {
GlobalKeyObserver.init();
}
setupDrawableImageLoader();
TimedTaskScheduler.setupRepeating(this);
TimedTaskScheduler.checkTasksRepeatedlyIfNeeded(this);
MobileAds.initialize(this, Constants.ADMOB_APP_ID);
}

View File

@@ -12,13 +12,11 @@ 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.app.GlobalAppContext;
import org.autojs.autojs.App;
import org.autojs.autojs.storage.database.ModelChange;
import org.autojs.autojs.storage.database.TimedTaskDatabase;
import java.util.List;
import io.reactivex.Completable;
import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.schedulers.Schedulers;
@@ -53,7 +51,7 @@ public class TimedTaskManager {
if (action == BaseModel.Action.DELETE && countTasks() == 0) {
TimedTaskScheduler.stopRtcRepeating(mContext);
} else if (action == BaseModel.Action.INSERT) {
TimedTaskScheduler.startRtcRepeatingIfNeeded(mContext);
TimedTaskScheduler.checkTasksRepeatedlyIfNeeded(mContext);
}
}

View File

@@ -1,16 +1,14 @@
package org.autojs.autojs.timing;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Parcelable;
import android.util.Log;
import com.twofortyfouram.spackle.AlarmManagerCompat;
import java.util.concurrent.TimeUnit;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -25,17 +23,21 @@ public class TimedTaskScheduler extends BroadcastReceiver {
public static final String ACTION_CHECK_TASK = "com.stardust.autojs.action.check_task";
private static final String LOG_TAG = "TimedTaskScheduler";
private static final int REQUEST_CODE = 4000;
private static final long INTERVAL = 60 * 1000;
private static final int REQUEST_CODE_CHECK_TASK_REPEATEDLY = 4000;
private static final long INTERVAL = TimeUnit.MINUTES.toMillis(1);
private static final long ONE_HOUR = TimeUnit.HOURS.toMillis(1);
private static PendingIntent sCheckTasksPendingIntent;
private static long mNextRtcWakeupMillis = -1;
@Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "onReceive");
Log.d(LOG_TAG, "onReceiveRtcWakeup");
checkTasks(context);
setupNextRtcWakeup(context, System.currentTimeMillis() + INTERVAL);
}
public static void checkTasks(Context context) {
@SuppressLint("CheckResult")
private static void checkTasks(Context context) {
TimedTaskManager.getInstance().getAllTasks()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
@@ -63,7 +65,13 @@ public class TimedTaskScheduler extends BroadcastReceiver {
assert alarmManager != null;
// FIXME: 2017/11/28 requestCode may > 65535
PendingIntent op = timedTask.createPendingIntent(context);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setExactCompat(alarmManager, op, millis);
}
private static void setExactCompat(AlarmManager alarmManager, PendingIntent op, long millis) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, millis, op);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
alarmManager.setAlarmClock(new AlarmManager.AlarmClockInfo(millis, null), op);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, millis, op);
@@ -72,35 +80,46 @@ public class TimedTaskScheduler extends BroadcastReceiver {
}
}
public static void setupRepeating(Context context) {
if (TimedTaskManager.getInstance().countTasks() > 0) {
startRtcRepeatingIfNeeded(context);
public static void checkTasksRepeatedlyIfNeeded(Context context) {
if (TimedTaskManager.getInstance().countTasks() > 0 && mNextRtcWakeupMillis > 0) {
setupNextRtcWakeup(context, System.currentTimeMillis() + 5000);
}
}
public static void startRtcRepeatingIfNeeded(Context context) {
Log.v(LOG_TAG, "startRtcRepeating");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000,
INTERVAL, createTaskCheckPendingIntent(context));
private static void setupNextRtcWakeup(Context context, long millis) {
Log.v(LOG_TAG, "setupNextRtcWakeup: at " + millis);
if (millis <= 0) {
throw new IllegalArgumentException("millis <= 0: " + millis);
}
AlarmManager alarmManager = getAlarmManager(context);
setExactCompat(alarmManager, createTaskCheckPendingIntent(context), millis);
mNextRtcWakeupMillis = millis;
}
public static void cancel(Context context, TimedTask timedTask) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
AlarmManager alarmManager = getAlarmManager(context);
alarmManager.cancel(timedTask.createPendingIntent(context));
}
public static void stopRtcRepeating(Context context) {
Log.v(LOG_TAG, "stopRtcRepeating");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
AlarmManager alarmManager = getAlarmManager(context);
alarmManager.cancel(createTaskCheckPendingIntent(context));
}
private static AlarmManager getAlarmManager(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
assert alarmManager != null;
return alarmManager;
}
private static PendingIntent createTaskCheckPendingIntent(Context context) {
return PendingIntent.getBroadcast(context, REQUEST_CODE,
new Intent(TimedTaskScheduler.ACTION_CHECK_TASK), PendingIntent.FLAG_UPDATE_CURRENT);
if (sCheckTasksPendingIntent == null) {
sCheckTasksPendingIntent = PendingIntent.getBroadcast(context, REQUEST_CODE_CHECK_TASK_REPEATEDLY,
new Intent(TimedTaskScheduler.ACTION_CHECK_TASK), PendingIntent.FLAG_UPDATE_CURRENT);
}
return sCheckTasksPendingIntent;
}
}

View File

@@ -3,6 +3,7 @@ package org.autojs.autojs.ui.main;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.FloatingActionButton;
@@ -32,6 +33,7 @@ import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
import org.autojs.autojs.autojs.AutoJs;
import org.autojs.autojs.storage.file.StorageFileProvider;
import org.autojs.autojs.timing.TimedTaskManager;
import org.autojs.autojs.tool.AccessibilityServiceTool;
import org.autojs.autojs.ui.BaseActivity;
import org.autojs.autojs.ui.common.NotAskAgainDialog;

View File

@@ -1,12 +1,19 @@
package org.autojs.autojs.ui.timing;
import android.Manifest;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@@ -54,6 +61,8 @@ 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");
private static final int REQUEST_CODE_IGNORE_BATTERY = 27101;
private static final String LOG_TAG = "TimedTaskSettings";
@ViewById(R.id.toolbar)
Toolbar mToolbar;
@@ -199,7 +208,7 @@ public class TimedTaskSettingActivity extends BaseActivity {
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())
, date.getYear(), date.getMonthOfYear() - 1, date.getDayOfMonth())
.show();
}
@@ -254,12 +263,26 @@ public class TimedTaskSettingActivity extends BaseActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_done) {
createOrUpdateTimedTask();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !((PowerManager) getSystemService(POWER_SERVICE)).isIgnoringBatteryOptimizations(getPackageName())) {
startActivityForResult(new Intent().setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
.setData(Uri.parse("package:" + getPackageName())), REQUEST_CODE_IGNORE_BATTERY);
} else {
createOrUpdateTimedTask();
}
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_IGNORE_BATTERY) {
Log.d(LOG_TAG, "result code = " + requestCode);
createOrUpdateTimedTask();
}
super.onActivityResult(requestCode, resultCode, data);
}
private void createOrUpdateTimedTask() {
TimedTask task = createTimedTask();
if (task == null)