24 hour Alarm

399 views
Skip to first unread message

Vinetwigs.

unread,
Aug 29, 2016, 3:43:15 PM8/29/16
to DroidScript
How can i execute a function every 24 hours ?

Steve Garman

unread,
Aug 29, 2016, 3:49:50 PM8/29/16
to DroidScript
One way would be to set an alarm in your app.

See the sample that comes with DroidScript "Alarms -
Set alarms to wake up your App"

When the alarm fires, you can call your function, set the next alarm and exit the app.

A more professional method would be to use a background service but that will take a bit more research, especially if it is your first service.

Vinetwigs.

unread,
Aug 29, 2016, 4:03:42 PM8/29/16
to DroidScript
Can you explain me show to create a background app Please?
Maybe you could post the code...

Steve Garman

unread,
Aug 29, 2016, 4:17:23 PM8/29/16
to DroidScript
You could start by examining one of the sample background services on the wiki http://wiki.droidscript.me.uk/doku.php?id=sample_code:file_service .

Vinetwigs.

unread,
Aug 30, 2016, 1:45:30 PM8/30/16
to DroidScript
Can you send me the code of a 24hour timer?

Symbroson Development

unread,
Aug 30, 2016, 1:58:22 PM8/30/16
to DroidScript
Just modified the timer sample a bit :


//Called when application is started.
function OnStart()
{
//Create a layout with objects vertically centered.
lay = app.CreateLayout( "linear", "VCenter,FillXY" );

//Create a 'Set Repeat' button.
btnRepeat = app.CreateButton( "Set Repeat", 0.4, 0.1 );
btnRepeat.SetMargins( 0, 0.05, 0, 0 );
btnRepeat.SetOnTouch( btnRepeat_OnTouch );
lay.AddChild( btnRepeat );

//Create a 'Cancel Repeat' button.
btnCancel = app.CreateButton( "Cancel Repeat", 0.4, 0.1 );
btnCancel.SetMargins( 0, 0.05, 0, 0 );
btnCancel.SetOnTouch( btnCancel_OnTouch );
lay.AddChild( btnCancel );

//Add layout to app.
app.AddLayout( lay );

//Create media player and load file.
player = app.CreateMediaPlayer();
player.SetFile( "/Sys/Snd/Poing.ogg" );
}

//Called when alarm is triggered.
//(Even if your app is closed)
function OnAlarm( id )
{
app.ShowPopup( "Got Alarm: id = " + id );
player.SeekTo( 0 );
player.Play();
}

//Called when user touches our 'Set Repeating' button.
function btnRepeat_OnTouch()
{
//Get current time in milliseconds.
var now = new Date().getTime();

//Set alarm for 3 seconds time and repeat every day (1000*60*60*24)
app.SetAlarm( "Repeat", 4321, OnAlarm, now + 3000, 86400000 );
}

//Called when user touches our 'Cancel Repeat' button.
function btnCancel_OnTouch()
{
//Cancel the alarm with id 4321.
//(All alarms will be cancelled by a reboot)
app.SetAlarm( "Cancel", 4321 );
}

Vinetwigs.

unread,
Aug 30, 2016, 2:02:00 PM8/30/16
to DroidScript
Thanks you so much!

Mark van der Velden

unread,
Sep 15, 2019, 8:50:56 AM9/15/19
to DroidScript
I want to do exactly what is asked here: having an app that checks a condition every 24 hours on a certain time and create a notification. Preferably without a UI so the user is only confronted with the notification. I studied a lot of questions and example programs on this forum and try to have a better understanding of design choices. 

Any feedback on my findings so far are highly appriciated.

Exact?
Setting an alarm and setting it again when it fires seems easy (better to set the alarm again explicitly instead of a repeat pattern such that unreliablity does not accumulate). Since by default alarms are more or less unreliable I can either except this, or add "exact" as the last option to SetAlarm. 

Reboot
Since alarms are cleared by a reboot, a background process that checks the time at a regular interval might be more reliable. AutoBoot can be used to make sure the app survives a phone reboot. Since the background process is only generated once, there is no worry about orphan background processes.

Battery
Is a background process that wakes up every 5 minutes or so not much more battery draining that setting an alarm and leaving the check to Android?

Additional background: I have a working app with a UI that works fine, but lacks an alarm feature. I also have a small JavaScript script that  checks a condition: this script is ran with a Tasker profile every day at 7am and Tasker creates the notification. Basically I like to add this Tasker functionality to my app.

regards
Mark

Steve Garman

unread,
Sep 15, 2019, 12:23:10 PM9/15/19
to DroidScript
If you're happy using tasker for this, take a look at the sample that comes with DroidScript

"Receive Intent
Receive intents from other apps"

//This example shows how to receive data from other apps
//like 'Tasker' which allow sending of Android Intents.

Steve Garman

unread,
Sep 15, 2019, 12:30:50 PM9/15/19
to DroidScript

Mark van der Velden

unread,
Sep 15, 2019, 1:57:18 PM9/15/19
to DroidScript
Hi,

Thanks, I will look into this info. However, I want to stop using tasker for this, such that I only have my own app. Using intents seems more complicated than the tasker based solution that I currently have.

Regards.

Steve Garman

unread,
Sep 15, 2019, 4:30:37 PM9/15/19
to DroidScript
I would use AutoBoot for the service.

I would do as much work as possible in Service.js to avoid having to display the main app.

I would code the service to set a new alarm (always using the same id) every time OnStart is called or OnAlarm is called.

In the OnStart function of Service.js, I recommend also adding
//////////
//Force service to foreground on newer devices (required).
if( app.GetBuildNum() > 25 )
app.SetInForeground( "Alarm set" );
//////////

This is how I calculate the alarm time for the next 8:30 pm

If you don't know the JavaScript Date object, it's quite helpful and you don't need to deal with things like month or year boundaries yourself.

{
// target time = next 8:30 pm
var tim = { hr: 20, min: 30, sec: 0, ms:0 };
var alrm = new Date();
var now = new Date();

alrm.setHours(tim.hr);
alrm.setMinutes(tim.min);
alrm.setSeconds(tim.sec);
alrm.setMilliseconds(tim.ms);

// check if 8:30pm is earlier today
if(now.getTime() > alrm.getTime())
alrm.setDate(alrm.getDate() + 1);

app.SetAlarm( "Set", 5432, OnAlarm, alrm );
}

Mark van der Velden

unread,
Sep 15, 2019, 5:20:15 PM9/15/19
to DroidScript
This is interesting, thanks a lot! I will let you know the result.

Steve Garman

unread,
Sep 15, 2019, 5:40:34 PM9/15/19
to DroidScript
Google are working very hard to make it difficult for an ordinary app to keep Android awake.
This is an understandable reaction to every developer thinking their app is so important that all their users must put up with a flat battery every 3 hours so they can run a pretty animation every time they feel like it..

As they change the rules with every new version, we are always playing catch-up.

Your battery question brings up a case in point.
If any app proceeds without user-input for a significant length of time, it leaves longer and longer pauses between checking for alarms, even if you have a separate alarm being repeated every five minutes to try to keep it awake.

You may find that with its special status, Tasker can keep further ahead of the curve than DroidScript can so I suggest keeping Tasker in mind as a last resort if this is for a personal project.
Obviously you don't want to ask other users to install Tasker if they don't already have it.

Keep us informed of how you get on.

If you have problems let us know. Ideally post runnable code that demonstrates any problem you are having if that is practical.

Mark van der Velden

unread,
Sep 16, 2019, 2:20:17 AM9/16/19
to DroidScript
Hi Steve,

Yes, it is a personal project, but more people are going to use it when they do not have to rely on Tasker. So I thought to give it a try. I will post my results, might take some time, because it is a bit harder than I thought to do it properly  ;-).

Mark

Mark van der Velden

unread,
Sep 18, 2019, 1:48:10 AM9/18/19
to DroidScript
Hi Steve,

Thanks to your help, I managed to have a working background service that gives a notification on a certain time each day (reliably, although I have tested it for two days only). No real problems apart from programming mistakes with earlier versions :-). The attached SPK includes the full source code.

Some questions I still have:
- I do not understand how to use SetAutoBoot. An example on the forum suggest SetAutoBoot('Service') to activate and SetAutoBoot('None') to cancel. The docs seem to indicate SetAutoBoot(true) and SetAutoBoot(false).
- Is it possible to make the notification silent?

And some minor things:
- Is the name of the background service always "Service.js"?
- Can I change the info in the permanent notification after it is created (by SetInForeground)?
- I wanted to call theService.SendMessage from onServiceReady, but that does not seem to work?
- When do I need a notification id?
TestService.spk

Steve Garman

unread,
Sep 18, 2019, 3:55:24 AM9/18/19
to DroidScript
app.SetAutoboot("Service")
should cause cause the service to start without opening the main app.
It is a requirement on recent versions of Android to call SetInForeground soon after it starts or the service will be shut down.

"Service.js" is a hard-coded filename and you're stuck with it.

you can call SetInForeground repeatedly with different info to change the display.

SendMessage from onServiceReady should work but if it doesn't seem to work, try wrapping it in setTimeout with a 100ms delay

notifications need an id for Android to use. It doesn't matter much what it is.

If I only want one notification from my app, I tend to use app.GetAppName() to generate the id, so it doesn't get muddled with other apps when testing in DroidScript.

The above was written before I looked at your spk.

Now I have looked at it, my main thought is that I'm probably not the person to help you.

Following what you are doing in testservicemain.js does not come naturally to me, even before any complexity is added.

Mark van der Velden

unread,
Sep 18, 2019, 8:29:57 AM9/18/19
to DroidScript
Hi Steve,

You are more than helpfull The stuff in testservicemain is just some UI stuff to help me test the hard part, my questions where about DroidScript and your answers are spot-on! By repeating SetInForeground I can add the "next alarm" to the permanent notification, which is a nice addition. So now I still have to find a way to make the notification silent ;-).

Thanks again for you quick and adequate responses!
Mark

Mark van der Velden

unread,
Sep 19, 2019, 2:51:50 PM9/19/19
to DroidScript
Hi Steve,

Maybe you will help me one more time. I have the following: my test app runs completely as expected when I run it from within DroidScript. But when I make an APK and run the standalone program there is no permanent notification. Do you have any idea what might cause this?

Just in case that was the problem I rewrote the testapp as a native app.

Mark
TestService.spk

Steve Garman

unread,
Sep 20, 2019, 1:53:13 AM9/20/19
to DroidScript
If I build an apk on my Oreo phone it works for me. I assume you would have noticed if you got a message when you built it saying "Your apkbuilder plugin is out of date." It could be a difference between Oreo and Pie I suppose.

One thing to be aware of is that if my phone has a lot of notifications to show, it will consolodate multiple notifications from one app into a single notification.
It displays +1 or +2 in the notification and provides a drop-down arrow to view the restl.. This can happen whether you are running in the IDE or from an APK but it won't always do it.

I attach the spk I've been testing with. I added some icons and made some changes to the SetInForeground to help me see what's going on. I used app.GetName() so it should display "TestService" or "DroidScript" depending on whether it's run from an apk. Sorry, I should have renamed the spk. Take care you don't overwrite your own project.



TestService.spk

Mark van der Velden

unread,
Sep 20, 2019, 3:49:12 PM9/20/19
to DroidScript
Hi Steve,

Thanks again for your effort. But it didn't help... I reinstalled the plugin (version 1,76) and checked the number of icons. When running from DroidScript, it works as expected. Even if I kill the main app the service keep giving an alarm every 10 sec (as expected). To cancel the alarms I first need to press On before Off works.

When run as a standalone app there is no permanenet notication (the 'start' icon is not shown). But the alarm come every 10 sec as expected. If I kill that app before the first alarm nothing happens. If I kill the app after the first alarm there are no new alarms.

If I remember correctly an alarm wakes up your app, and it should do that also when there if no permanent notification isn't it? Anyway it still puzzles me ;-).

I have a Samsung Galaxy A8 (2018), with Android 9.


Steve Garman

unread,
Sep 20, 2019, 4:20:03 PM9/20/19
to DroidScript
No.
Alarms used to do that but in recent versions of Android, if there is no user interaction the times it wakes up to check for alarms stretch longer and longer apart until an alarm can be literally hours late.

The fifth parameter to SetInForeground is importance. Try setting it to "high"

app.SetInForeground(theAlarmHour + ':' + theAlarmMinutes,"Time "+lastStarted+" "+app.GetName(),"Img/TestService.png","Img/notify.png","high");

Mark van der Velden

unread,
Sep 21, 2019, 1:17:42 AM9/21/19
to DroidScript
Hi Steve,

I tried, but no difference.

Mark

Mark van der Velden

unread,
Sep 21, 2019, 4:35:15 AM9/21/19
to DroidScript
I might have additional information.

When I do not use SetInForeground, but create my own Ongoing notification everything seems to work as expected, both from within DroidScript and as stand alone APK. The drawback is that I cannot kill te service any more without rebooting my phone (I alo added code to test AutoBoot but you understand why I have not tested that yet ;-).

Code in the attachment.

Mark
TestService.spk
Reply all
Reply to author
Forward
0 new messages