termux / termux-api

Termux add-on app which exposes device functionality as API to command line programs.
https://f-droid.org/en/packages/com.termux.api/
2.36k stars 462 forks source link

Could termux-job-scheduler schedule jobs at a particular time (like cron) #282

Open Noexpert opened 5 years ago

Noexpert commented 5 years ago

Hi there,

firstly, thanks for taking the time to maintain this.

I was wondering whether termux-job-scheduler could schedule cron-like jobs at a particular time?

Thank you

xalexalex commented 5 years ago

Hey, this is something I've been thinking about but still haven't had the time to research. I think this should be doable using, for example, AlarmManager. The place for this issue should then be termux/termux-api, to which I'm moving it.

Meanwhile, if you want to schedule a job to run at a specified time, a quick and dirty hack could be

# ~/bin/check
# run ~/bin/script once a day, after 6 am 
fname="$HOME/.tmp/check-$(date -I)"
hour=$(date +%k)
if [[ ! -e "$fname" ]] && (( hour > 05 )); then
       rm -fv $HOME/.tmp/check-*
       ~/bin/script
       touch "$fname"
fi

and then use termux-job-scheduler to run ~/bin/check every 15m or every hour, depending on your needs and the precision you require.

Edited to add: several months ago I've actually had a good experience using the real cron and termux-wake-lock to keep the session alive. I haven't seen the enormous battery drain I was expecting. You may try this route if you have to schedule many scripts with complex rules.

nerd190 commented 4 years ago

Hi! I remember reading this issue when it was fresh, and with the hit-and-miss nature of cron on Android, I too looked for something other than 'Tasker' for automation (I think that integration with a FOSS automation app like 'Easer' would be much better, I and some others dont use closed-source, I run Android google-less etc), anyways... I found an amazing app! one that could kick-start this issue! I totally forgot to share it here earlier, its open-source, available from Github/F-Droid, and it uses AlarmManager to run scripts, hasnt had an update in a few years but still works perfectly on my Android 10 device! (OnePlus 5T, Oxygen OS) only problem is it requires root, not a problem for me but will be for thousands of others that want this functionality, because if its integrated into the termux-api it wouldn't need root as it would have the correct perms. Memory usage? ... around 1.5mb!! even with battery optimisation disabled. thats impressive! This is by-far the most stable, consistent way to schedule jobs, its never let me down once! I would love to see this merged into the API!

Screenshot_20201005-141641 Screenshot_20201005-141407 Screenshot_20201005-141425

crond - Github crond - F-Droid

THANK YOU FOR ALL YOU DO, IT IS TRULY APPRECIATED!

lvogt commented 10 months ago

Hi,

EDIT: There are now a couple of PRs open to implement this: https://github.com/termux/termux-api/pull/657

I have some more or less working CronAPI implementation locally. It is currently still missing to "re-add all alarms after reboot" and I have tested it until now only with an emulator. It also still needs a bit of cleaning up. However, before I start creating PRs I wanted to ask whether this will be welcomed at all since I did a few design decision which might not be accepted:

Here is the general flow: The handling is more or less like the termux-job-scheduler api - this means you supply a script and a cron expression for when this shall be run. Additionally you can specify constraints (network, charging, etc).

Scheduling is done via AlarmManager. Jobs are not scheduled "periodically" but once a job finishes the next execution is scheduled. This allows to better handle more complex cron expression but has the drawback(?) that only a single "instance" of the script is executed at a time.

Once a job's start time is reached, a WorkRequest via WorkManager is created. This is the place where the constraints are evaluated. Meaning: "Work" is created at the scheduled time, but execution will wait until constraints are met. Here is it is possible to cancel the WorkRequest if it takes too long to fulfill the constraints.

When the worker request is executed, it will trigger termux and run the script. The worker thread will wait until termux finishes, or until a maximum runtime. If that is reached the worker thread will try to kill the termux script. When the worker thread waits for script to finish, it will also get terminated if the constraints are no longer met, it will then (if configured) also kill the termux script execution.

Another issue is that I (at least for the moment) raised the minSdkVersion=26 meaning Android 8+ - I can probably get it back down to 24 as there are only some minor things which made raising the version necessary.

Sorry for the long wall of text, and thank you if you read it all ;)