Cornholio2108 / BestAlarm

0 stars 0 forks source link

Smart Shutdown Service not started after a few hours #29

Closed Cornholio2108 closed 4 years ago

Cornholio2108 commented 4 years ago

Smart Shutdown Service not started when the device is sleeping some hours. Associated alarm are properly starting (30 mins later).

Cornholio2108 commented 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);
    }
}
Cornholio2108 commented 4 years ago

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>
Cornholio2108 commented 4 years ago

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.

Cornholio2108 commented 4 years ago

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.

Cornholio2108 commented 4 years ago

Possibility: PowerManager ACTION_DEVICE_IDLE_MODE_CHANGED

Cornholio2108 commented 4 years ago

fixed