App misbehaving on ForeRunner 935. Fine on simulator

Hi,

I have a watch app which works fine on a couple of watches, but on a 935 it misbehaves.  It's mean to draw lines on the screen, which are downloaded as a json file. This constitutes a map.

It works in the simulator, but on the watch the screen is blank and having got some debug logs off the watch itself, I get a strange output and hoped someone might be able to shed some light.

Each json file has an ID which is a string. This string is number/number/number (eg. 32754/25849/17) respresenting a map tile location

I print the current tiles which are being displayed. The code to populate the tile ids is:

var tiles = new [totalTilesX * totalTilesY];

var x = topLeftTileX;
var i = 0;
while(x <= bottomRightTileX){
var y = topLeftTileY;
while(y <= bottomRightTileY){
tiles[i]= x + "/" + y + "/" + z;
i++;
y++;
}
x++;
}

return tiles;

Then, later on, the code to print the ids

System.println(tiles);

On the 935 Simulator, and on my watch (vivoactive) and a fenix it prints the strings when I print the array.

[32739/25972/17, 32739/25973/17, 32739/25974/17, 32740/25972/17, 32740/25973/17, 32740/25974/17]

On the watch where it doesn't work, when I print the array of values, it prints

[f.a.q.b.l@92a741b2, f.a.q.b.l@92a7b611, f.a.q.b.l@92b1b63b, f.a.q.b.l@86f0b2d1, f.a.q.b.l@86f12730, f.a.q.b.l@86fb275a, f.a.q.b.l@7b3a23f0, f.a.q.b.l@7b3a984f, 
  • In general, what this kind of sounds like to me is that your app seems to think you have good data from a webRequest if the call back has been called.

    This is something you won't see in the sim unless you do something like set the BLE connection off in Connection Types in the sim, but can easily happen on a device.

    I actually detect this in the app and don't bother to make requests so I hope that's not the problem. I have experimented with BLE off to support offline maps.

    I've managed to have it download the maps for a given route onto the watch storage and verified that I can take those with me on my vivoactive3 when I go for a run so I don't need any connectivity at all. It's a bit experimental at the moment as I'm not quite sure how it's fitting in the supposed 128k storage I thought my app had access to, but it definitely works for the map sections I'm working with.

  • I found menu2 on the button based watches strangely didn't cancel the exit even if you returned false from the method, so I had to use the DMenu component that someone else kindly posted here.  I digress...

    I posted DMenu (most recently). Unless you're referring to the original version by Dave Baldwin. (In that case, I would recommend using my fork, as it's got a few fixes that haven't been incorporated into his version.)

    I do prefer to use Menu2 for any watches that support it, for aesthetics, usability and consistency. 

    I don’t get why you need to cancel the exit for the menu tho. Don’t you want people to be able to exit the pause menu (return to activity screen) on a BACK or right swipe?

    Also, you cancel the exit from a Menu2 by overriding onBack() in the Menu2InputDelegate. I don't think it matters what you return from the method itself. (It's not like a regular InputDelegate().)

    At least that's what the docs indicate, and IIRC I don't think I've seen otherwise in the sim or real device.

  • Cancelling the menu by returning false still exits the app if you press back from the main screen, and stops my activity.  Dmenu doesn't do this, and I used it elsewhere to dynamically load menu items so it was easy to swap it out. I didn't dwell on it for too long

    Thanks for posting it!

  • Cancelling the menu by returning false still exits the app if you press back from the main screen, and stops my activity

    But...you're not using DMenu or Menu2 for the main screen, right?

  • I use it in a couple of places. When you press back on the map screen I believe I open the dmenu and return true to indicate I've handled the button press. This works fine. Returning true and loading a menu2 seemed to work until you exit the menu. At that point the app exits as if it hasn't registered that return value. I also use it under menu-> routes to load routes from the web. I think I use it in a couple of other places too.

    I actually added the ability to add a description as well as main title to the menu screen for dmenu as it was easier to achieve than with custom menu.

  • Right I’m just saying the main view itself is not a DMenu or a Menu2. I just don’t get how exiting a Menu2 view is going to exit the app, assuming you pushed it while on the main view. (If you push view B on top of view A, the type of view B should have no impact on what happens when you pop B.)

    Anyway, since you’re not using Menu2 it doesn’t matter, but i was just curious about that.

  • If the user presses the back button on the map screen the default action exits the app. If it's recording I catch that and pop up a dmenu to ask them to confirm. If I use a menu2, when they hit cancel to stay in the app it exits anyway. I return true from the method which catches the back press. Dmenu doesn't do this, it stays in the app. No idea why.

  • Sure I get it.

    I'm just saying that if your main view's behavior delegate has code like this:

    function onBack() {
      var newView = // ... create new view
      WatchUi.pushView(newView, ...)
      return true;
    }

    ...logically it shouldn't matter what the type of newView is.

    (If you use switchToView(), then there's the restriction that newView has to be user-defined, unless your watch has CIQ 3.1 or higher -- which most VA3s should.)

  • I return true from the method if there's a session running. I you substitute the DMenu for a menu 2 it exits the app when you leave the menu

    function leaveMap() {
        System.println("Back pressed on map page");
        if (mSessionManager!=null && mSessionManager.isSessionActive()) {
    
            if (System.getDeviceSettings().isTouchScreen) {
                var exitView = new ExitView();
                WatchUi.pushView(exitView, 
                    new ExitDelegate(exitView, mSessionManager), 
                    WatchUi.SLIDE_UP);
            } else {
    
                var items = [new DMenuItem(:item_exit, "Exit", null, null),
                    new DMenuItem(:item_cancel, "Cancel", null, null)];
    
                var view = new DMenu(items, "Quit App?", null);
                WatchUi.pushView(view, 
                    new DMenuDelegate(view, new ExitMenuDelegate()), 
                    WatchUi.SLIDE_UP);
    
            }
    
            return true;
        }
    
        return false;
    }

  • What's the base class of the input delegate that would be passed to the Menu2 view?

    To be clear, the doc states that it should be Menu2InputDelegate (which does not derive from BehaviorDelegate or InputDelegate.) If you pass in the wrong kind of delegate, I don't think it would work properly.

    You said this:

    "Cancelling the menu by returning false still exits the app if you press back from the main screen, and stops my activity."

    But that's not how you "cancel" the default back action on a Menu2. According to the docs, the way you do it is simply override OnBack in the Menu2InputDelegate. (I realize this is different than BehaviorDelegate/InputDelegate which makes me wonder which delegate you actually used.)

    developer.garmin.com/.../Menu2InputDelegate.html