Conditional onTemporalEvent and requestApplicationWake for user interaction

Can't seem to figure this out even after looking at some code from starttorun.info as well as the forums.

The call -->  requestApplicationWake gets executed even though there is no temporal event registered. Is this the correct behaviour or likely I'm doing it all wrong

Widget Logic

1) widget In foreground -> Grabs a location and user has ability to store it into object store.

2) user goes back to watch face (Widget dismissed)--> a BG Event is registered.

3) Upon Temporal Event happening (using the sim), onTemporalEvent gets called requestApplicationWake comes out.

if there are NO location stored in the Object Store, then I would not register the Background Event, but requestApplicationWake gets executed anyways

Now, if I were to remove any references to registerTemporalEvent, I stop the App in the simulator, then execute a Background Event from the simulator, the requestApplicationWake still gets executed. I'm sure that there was ways to do some sort of conditional checks within onTemporalEvent hence I'm likely missing something.

Appreciate any pointers.

App.AppBase

(:background)


    function onStop(state) {
    	System.println("App.onStop");

		if(Sys has :ServiceDelegate) {
	    	if ( App.Storage.getValue(A_COORDINATES) == null ) {
	    		Sys.println("App.Deleting Temporal Event");
	    		Bg.deleteTemporalEvent();
	    	} else {
	    		Sys.println("App.Temporal Event Present");
	    	}
	    }
    	
    	
    function getInitialView() {
		System.println("App.getInitialView");
		 if(Sys has :ServiceDelegate) {
	    	if ( App.Storage.getValue(A_COORDINATES) != null ) {
	      		Sys.println("App.Registering Temporal Event " + App.Storage.getValue(A_COORDINATES));
//	      		Bg.registerForTemporalEvent(new Time.Duration(5 * 60));
	      	} else {
	      		Sys.println("App.Not Registering Temporal Event");
	      	}
	    }

System.ServiceDelegate

function onTemporalEvent() {
  	Background.requestApplicationWake("Your timer has expired!");  	}
  	Background.exit();
  }

I've also tried to do a conditional check, but it seems like whether the object store is NULL or NON-NULL, the requestApplicationWake doesn't get executed anyways.

 

function onTemporalEvent() {
  	if ( App.Storage.getValue(A_COORDINATES) != null ) {
  		Background.requestApplicationWake("Your timer has expired!");
  	}
  	Background.exit();
  }

  • Once there is something written to Storage for A_COORDINATES, how/when is it cleared?  Maybe add a println in onTemporalEvent() just to make sure it's null when you expect it to be null.

    Couple things to note.  onStop() gets called for both the widget and the background process.  I don't think there's an issue in this code, but something to keep in mind.

    Even if you have no temporalEvent registered, if you trigger a background temporal event in the sim, the background does run and onTemporalEvet is called.

    You could be running into something where requestApplicationWake isn't doing anything if the widget is already running.

  • Q: A_COORDINATES, how/when is it cleared?

    A: User will manually clear it within the Widget menu.

    Initially I placed registerForTemporalEvent in onStop() but then like you said, it's executed both the widget and background. (called 2x essentially) and It also made it such that when the A_COORDINATES is cleared, the BG is already registered. Technically, I think the desired behaviour _should_ be that I check If A_COORDINATES is non-null when user exits the widget and then registerForTemporalEvent If it's non-null.

    Q: Maybe add a println in onTemporalEvent() just to make sure it's null when you expect it to be null.

    I tried that, but I guess I was doing it wrong and I didn't get any printouts. (only later I realised that I could do the BG temporal trigger when the widget is running in the foreground in the simulator. I was doing "Kill-App" then "Background Events" in the sim.) Anyways, I confirmed that it is indeed NULL when I expect it to be.

    Q: Even if you have no temporalEvent registered, if you trigger a background temporal event in the sim, the background does run and onTemporalEvet is called.

    This is diff behaviour than on a real device correct? (I didn't try side loading it - cos I figured that the sim was supposedly doing the right thing. I think I'll have to try it out on the real device and see the logs. Also I didn't want to keep waiting for 5mins)

    Q: You could be running into something where requestApplicationWake isn't doing anything if the widget is already running

    Does the actual device process requestApplicationWake when there I didn't register a temporal event? I'll give it a try

  • This is diff behaviour than on a real device correct? (I didn't try side loading it - cos I figured that the sim was supposedly doing the right thing. I think I'll have to try it out on the real device and see the logs. Also I didn't want to keep waiting for 5mins)

    The trigger in the sim is simply for testing, so you can get the background to run at any time testing.  There is no way to force the background to run on a real device.

    I did just notice something in your code.  You're not passing anything to Background.exit().  You're background is crashing, though you may not see it in the sim, but the result is onStop() isn't being called when the BG runs.

    for Background.exit() try Background.exit(null) instead.

    Error: Not Enough Arguments Error
    Details: Failed invoking <symbol>
    Stack: 
      - receiveWeather() at C:\Users\James\AppData\Local\Temp\BgWu.barrel6109072879434857646\content\BgWu.mc:95 0x1000045c 
    

  • Background.exit() try Background.exit(null) instead.

    Thanks ...  I am using that now and uploaded to the watch

    1) 1st exit (coordinate is not null) - the BG Timer doesn't get executed after 5mins

    2) 2nd exit (coordinate is not null) - the BG Timer gets executed after 5mins. (I get the application wake "your timer has expired" on the watch. However, clicking "Launch" just gets me back to the watch face. (Isn't the behaviour supposed to laugh the widget?)

  • More testing

    seems like the background event gets triggered almost immediately instead of waiting for 5mins. Not entirely sure why this doesn't work:

    Bg.registerForTemporalEvent(new Time.Duration(5 * 60));

    So I tried the code from the samples and it worked which is basically, from the code, trigger a BG event 5mins into the future from now(). 

    var mTimerDuration = 5;
    var time = new Time.Moment(Time.now().value());
    time = time.add(new Time.Duration(mTimerDuration * 60));
    Background.registerForTemporalEvent(time);

    Also once requestForApplicationWake gets triggered, clicking on Launch doesn't; launch the widget. How can I get it to launch the widget?

     

    function onTemporalEvent() {
      	System.println("SD onTemporalEvent coordinates:" + App.Storage.getValue(A_COORDINATES));
    	  	if ( App.Storage.getValue(A_COORDINATES) != null ) {
    	  	  	System.println("<><><> SD - A_COORDINATES is not null. calling requestApplicationWake");
    	  		Background.requestApplicationWake("Your timer has expired!");
    	  	} 
        Background.exit(true);
    
      }

    I also found out that doing either for Background.exit() try Background.exit(null) will not have requestForApplicationWake trigger. I have to change it to Background.Exit(true). Once this was changed, (and with the set temporal 5mins into future) then the widget started to work as it should.

    The only thing that remains is _why_ does it not go back to launching the widget once I click "launch" upon RequestForApplicationWake gets triggered?

  • The only thing that remains is _why_ does it not go back to launching the widget once I click "launch" upon RequestForApplicationWake gets triggered?

    Did you find out why this happened? I am facing the same issue.

    Appreciate any hint. Thank you!!