Register more than one event for backgrounding and background from starting at DND times

Hi,

I want to implement a widget with a nagging feature like the hydration widget. I need four events to trigger the background process:

1. registerForTemporalEvent(time)

2. registerForActivityCompletedEvent 

3. registerForSleepEvent 

4. registerForWakeEvent 

I am wondering how I can register register them? Currently I do it this way:

    function getInitialView() {
     	if(Toybox.System has :ServiceDelegate) {
    		// read the setting naggingFrequency: 1h=3600, 2h=7200, 4h= 14400
    		var nag = Application.getApp().getProperty("naggingFrequency");
    		if (nag > 0) {
    			Background.registerForTemporalEvent(new Time.Duration(nag));
    		}
     		Background.registerForActivityCompletedEvent();
     		Background.registerForSleepEvent();
     		Background.registerForWakeEvent();
    	} else {
    		System.println("No BG Data available");
    	}
    	
        return [ new MyView(), new MyDelegate() ];
    }

Furthermore I am wondering how I can prevent the main app from starting during the DND times.

It it possible like this?

function onTemporalEvent()
   if (!dnd) {
    Background.requestApplicationWake("Launch Cool App?");
   }
   Background.exit(null);
}
function onSleepTime() {
    dnd = true;
}

function onWakeTime() {
    dnd = false;
}

  • Have you tried it in the sim?  Maybe add println calls to onSleepTiime() and onWakeTime() so you can see that they are being called and start running the widget before the sleep time (I think that's something like 22:00 in the sim) and let it run overnight (till later than the wake time).

    (just checked - it's 22:00 to 8:00 in the sim)

    Toggling DND in the sim settings won't cause these to occur, as you can set DND outside of the sleep times, and "sleep mode" is  an old legacy thing for isSleepMode in CIQ (depreciated)

  • Ok, I understand your problem now.  Each time the background runs, dnd is reset (if var dnd=false;, it would always start as false).  and therefore  in onTemporalEvent() it would always be false.

    If you want things to be different when doNotDisturb is true, you need to check Sys.getDeviceSettings().doNotDisturb.

    If you want them different during the configured sleep times, you need to check the current time against those times in onTemporalEvent()

    In both cases, you don't need onSleepTime() and onWakeTime().

  • Hi Jim, you are my man. Didn't be aware that a dnd flag exist. You have really the entire API in your mind. 

    I can ask for the dnd flag in systems. Great.

    Just to clarify, the dnd variable of my code is initialized when the background service will get active each time, isn't it? 

  • You can call  Sys.getDeviceSettings().doNotDisturb in onTemporlEvernt and get the current value each time the background runs.  You don't need your dnd flag.

    But this is dnd and not the configured sleep times.  For that you grab the times from UserProfile.

  • OK, thanks for clearing things up. So in my case I would need the UserProfile thing. There, a duration is given evaluating to 79200 and 28800 seconds, respectively which is 8 am and 10 pm in the sim. Ok, I didn't expect a duration there. I would use following code but have no clue how efficient it is for the background process:

    		var profile    = Prof.getProfile();
    		var st  = profile.sleepTime;
    		var wt  = profile.wakeTime;
    
    		var todaysDuration = Time.now().subtract(Time.today());
    		
    		if (todaysDuration.greaterThan(st) or todaysDuration.lessThan(wt)) {
    			System.println("Do nothing");
    		}
    

    What do you think? Or is it more efficient to grab system time and compare it against the sleepTime and wakeTime value?

  • Be careful here as you can't assume sleep time is>wake time, or more specifically, when sleep doesn't span midnight.

  • Hi Jim,

    thanks for that hint. I implemented it in this way now:

    function onTemporalEvent() {
    
    		var profile    = Prof.getProfile();
    		var st  = profile.sleepTime;
    		var wt  = profile.wakeTime;
    		
    		var todaysDuration = Time.now().subtract(Time.today());
    		System.println("Sleeping Time: " + st.value());
    		System.println("Wake Time: " + wt.value());
    		System.println(todaysDuration.value());
    		
    		var dnd = false;
    		if (st.lessThan(wt)) {
    			if (todaysDuration.greaterThan(st) and todaysDuration.lessThan(wt)) {
    				dnd = true;
    			}
    		} else {
    			if (todaysDuration.greaterThan(st) or todaysDuration.lessThan(wt)) {
    				dnd = true;
    			}
    		}
    		if (!dnd) {
    			System.println("Do not disturb is not set");
    			// do some stuff here
    		}
    		System.println("exiting Background");
            Background.exit(1);
        }
    

    Today I was pretty surprised that my background widget came up at 6:30 and 7:30 although my wake time is set to 8 am.

    Therefore I started the simulator before 8 am and integrated some println commands. And voila: the dnd variable was set to true but it seems not to work on the real watch....

  • OK, sorry for this post. I printed out my waketime directly on the watch and it was set to 6 am. Everything working fine.