Syncing applications when doing background service with communications

Hi,
I'm running a background service that receives data from the CIQ app and views it in a datafield. The data comes from another app that sends messages in specific intervals when a device is connected. The problem is that the background service can only run every five minutes. Does there exist a straight forward way to sync the applications so that the bgs is running when the message is sendt from the phone? Or do I have to add a pause/delay in the background service so that the phone can send messages within this window?

Thanks.
  • Former Member
    Former Member over 7 years ago
    I think there are a couple of options for this type of communication.

    One option is to have the background process send a "ping" message to the phone application when it wakes up, and then wait for the response from the phone.

    Another option is to just send the messages periodically from the phone to the watch, with no regard for the timing of the background service. These messages will be saved by the watch until the background process runs and registers to receive them. It will receive any messages that were sent since the last time it ran when it does.

    If you need these messages to be synced up, you can attempt to send the last run time from the background process to the phone application, and attempt to wake up synchronously, but the background process on the watch is not guaranteed to wake up at its earliest scheduled opportunity if something else on the device is running that prevents it from having memory available to spawn the process.
  • With a DF, I'd probably lean towards the first option Brian mentioned, in that you may want to control the temporal events so it only runs when the DF is being used, and not 24/7. Last I looked, the background process for a DF ran 24/7, but there are ways to handle that by using deleteTemporalEvent when the DF exits. (by run, I mean at most every 5 minutes, and then for a max of 30 seconds). With the second option, you might be sending a bunch of data to the watch that's not used or needed.

    Left the background process determine when data is needed and should be sent..
  • Thanks! I think I'll go for the second option, yes. I will keep you posted.
  • So I got the communications up and running and the watch is pinging the app for updates. Problem is, I can't seem to get the background service to wait until it has received the message before it closes and returns to main.

    using Toybox.WatchUi as Ui;
    using Toybox.System as Sys;
    using Toybox.Communications as Comm;
    using Toybox.Time.Gregorian;


    (:background)
    class RequestListener extends Comm.ConnectionListener {

    function initialize() {
    Sys.println("CommListener:");
    ConnectionListener.initialize();
    }

    function onComplete() {
    Sys.println( "Request sendt" );
    }

    function onError() {
    Sys.println( "Request Failed" );
    }

    }


    (:background)
    class BgbgServiceDelegate extends Toybox.System.ServiceDelegate {
    function initialize(){
    ServiceDelegate.initialize();
    Sys.println("BgbgServiceDelegate initialized.");

    Sys.println("Setting mailboxlistener");
    Comm.setMailboxListener(method(:onMail));
    Sys.println("Mailboxlistener ready");

    }


    function onTemporalEvent() {
    var message = "-";
    //--------Open connection, ask for data and wait to receive it-----------------

    var listener = new RequestListener();

    try {
    Comm.transmit(0, null, listener);

    }
    catch( ex ) {
    Sys.println("Transmission failed");
    }
    finally {
    Sys.println("Temporal event occured.");
    }





    while (Comm.getMailbox() == null){
    //wait...
    Sys.println("Waiting for message from application");
    }


    //--------------------------------------------------------------------

    Sys.println("onTemporalEvent: Exiting event. Mailbox = " + Comm.getMailbox().Array);
    //Return data to the main process. This is caught by onBackGroundData:
    Background.exit(message);

    }

    function onMail(mailIter) {
    var mail = mailIter.next();
    message = mail;
    Sys.printl("Mail received: " + mail);
    Comm.emptyMailbox();
    }
    }
  • You may want to move this discussion to the developer forum (one level up).
  • Former Member
    Former Member over 7 years ago
    You are misunderstanding the process flow of Connect IQ.

    Things like the mail callback cannot run concurrently with your other code. Everything executes on a single thread. The while loop you inserted will block your process until the system decides to kill it for running too long.

    Your background process will not exit until it explicitly calls an exit function, or it runs too long and the system terminates it. Your temporal callback does not have to exit if it is expecting to receive a message. It just needs to set up the callback and send the ping. Your mailbox callback will receive the message and exit.

    (:background).
    class BgbgServiceDelegate extends Toybox.System.ServiceDelegate {
    function onTemporalEvent() {
    Comm.emptyMailbox();
    Comm.setMailboxListener(method(:onMail));
    Comm.transmit(0, null, listener);
    }

    function onMail(mailIter) {
    var mail = mailIter.next();
    Sys.println("Mail received: " + mail);
    Background.exit(mail);
    }
    }

  • That makes sence. It works!

    Really appreciate your help here. This is my term project this fall and without much programming knowledge it has become kind of time consuming. Couldn't have done it without the help of this forum.