Closed Cornholio2108 closed 4 years ago
WakefulIntentService snippet:
In Receiver:
WakefulIntentService.acquireStaticLock(context); //acquire a partial WakeLock
context.startService(new Intent(context, TaskButlerService.class)); //start TaskButlerService
public class WakefulIntentService extends IntentService {
public static final String
LOCK_NAME_STATIC="edu.worcester.cs499summer2012.TaskButlerService.Static";;
public static final String
LOCK_NAME_LOCAL="edu.worcester.cs499summer2012.TaskButlerService.Local";
private static PowerManager.WakeLock lockStatic=null;
private PowerManager.WakeLock lockLocal=null;
public WakefulIntentService(String name) {
super(name);
}
/**
* Acquire a partial static WakeLock, you need too call this within the class
* that calls startService()
* @param context
*/
public static void acquireStaticLock(Context context) {
getLock(context).acquire();
}
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager
mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
LOCK_NAME_STATIC);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
@Override
public void onCreate() {
super.onCreate();
PowerManager mgr=(PowerManager)getSystemService(Context.POWER_SERVICE);
lockLocal=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
LOCK_NAME_LOCAL);
lockLocal.setReferenceCounted(true);
}
@Override
public void onStart(Intent intent, final int startId) {
lockLocal.acquire();
super.onStart(intent, startId);
getLock(this).release();
}
@Override
protected void onHandleIntent(Intent intent) {
lockLocal.release();
}
}
public class TaskButlerService extends WakefulIntentService{
public TaskButlerService() {
super("TaskButlerService");
}
@Override
protected void onHandleIntent(Intent intent) {
TasksDataSource db = TasksDataSource.getInstance(this); //get access to the instance of TasksDataSource
TaskAlarm alarm = new TaskAlarm();
List<Task> tasks = db.getAllTasks(); //Get a list of all the tasks there
for (Task task : tasks) {
// Cancel existing alarm
alarm.cancelAlarm(this, task.getID());
//Procrastinator and Reminder alarm
if(task.isPastDue()){
alarm.setReminder(this, task.getID());
}
//handle repeat alarms
if(task.isRepeating() && task.isCompleted()){
task = alarm.setRepeatingAlarm(this, task.getID());
}
//regular alarms
if(!task.isCompleted() && (task.getDateDue() >= System.currentTimeMillis())){
alarm.setAlarm(this, task);
}
}
super.onHandleIntent(intent);
}
}
JobScheduler for the SmartShutdownService? Trigger can be off by +-10minutes when device is in doze mode but timing doesn't matter much for this.
Start job:
public static void scheduleJob(Context context, AwakeAlarm awakeAlarm) {
Log.d(TAG, "scheduleJob: ");
ComponentName serviceComponent = new ComponentName(context, SmartShutdownJobService.class);
JobInfo.Builder builder = new JobInfo.Builder(NOTIFICATION_ID_SENSORS, serviceComponent);
builder.setMinimumLatency(awakeAlarm.alarmMillis-Calendar.getInstance().getTimeInMillis()- TimeUnit.MINUTES.toMillis(30)); // wait at least
builder.setOverrideDeadline(awakeAlarm.alarmMillis-Calendar.getInstance().getTimeInMillis()-TimeUnit.MINUTES.toMillis(20)); // maximum delay
//builder.setRequiresDeviceIdle(true); // device should be idle
JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
jobScheduler.schedule(builder.build());
}
SmartShutdownJobService
public class SmartShutdownJobService extends JobService {
private static final String TAG = SmartShutdownJobService.class.getName();
@Override
public boolean onStartJob(JobParameters params) {
Log.d(TAG, "onStartJob: "+params.getJobId());
//int alarmID=params.getJobId();
Intent serviceIntent = new Intent(getApplicationContext(), com.awake.cornholio.awake.receivers.MainService.class);
getApplicationContext().startService(serviceIntent);
// Or handle all sensor work in here?
//return false if job is finished -> wakelock will be released!
//return true if job needs to continue running -> wakelock will be held until jobFinished (JobParameters params, boolean wantsReschedule) is called.
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.d(TAG, "onStopJob: "+params.getJobId());
return true;
}
}
Cancel job:
JobScheduler scheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
scheduler.cancel(NOTIFICATION_ID_SENSORS);
Manifest:
<service
android:name=".receivers.SmartShutdownJobService"
android:label="SmartShutdownJobService"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
Handle sensor in JobService doesn't work well. Seems to be suspended alot by system. Holding wakelock in JobService improves it but still not good.
Start service to handle sensor from JobService works ok. Service seems to be suspended by system but not as much as JobService. Service holds wakelock.
Possibility: PowerManager ACTION_DEVICE_IDLE_MODE_CHANGED
fixed
Smart Shutdown Service not started when the device is sleeping some hours. Associated alarm are properly starting (30 mins later).
WakefulBroadcastReceiver?deprecatedor WorkManager(not exact!) (https://github.com/commonsguy/cwac-wakeful) (https://developer.android.com/reference/android/support/v4/app/JobIntentService)