Weird MapTrackView crash - no logs generated - blinking IQ!

Hi everyone, 

I am getting random crashes in my app, that are not triggered by any user interaction. 

The app is based on the Comm sample, I am sending the heartrate to an android app. 

I do not do anything unusual in the onUpdate method, nor in the onSensor / onPosition methods. 

When the app crashes, it seems that only the MapTrackView is crashing - it is blinking IQ!, but my menus are still operational (although 

System.exit() doesn't work anymore).
No logs are being generated for the crash.

Any ideas on how to approach debugging of such issues?

My onSensor/onPosition/onUpdate methods:

function onSensor(sensorInfo as Sensor.Info) as Void {    
        hr = sensorInfo.heartRate;
        if (hr != null) {
                var msg = [];
                msg.add("stats");
                msg.add(hr.toString());
                var stats = System.getSystemStats();
                if (stats != null) {
                    var pwr = stats.battery;
                    var batStr = Lang.format( "$1$", [ pwr.format( "%2d" ) ] );
                    msg.add(batStr);
                }
                Communications.transmit(msg, null, view.listener);
        }
    }
    function onPosition(loc as Toybox.Position.Info)  as Void {
        if (view.vectorTarget != null) { // vectorTarget is null in my testing, so that code is not triggered
            view.drawVector(view.vectorTarget);
        }
    }
function onUpdate(dc) {
       
        dc.clear();
        // Show time (green if connected, red if disconnected)
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
        dc.fillPolygon([[0,screenHeight-40], [screenWidth,screenHeight-40],  [screenWidth,screenHeight], [0,screenHeight]]);
        var out;
        var isBTConnected  = Toybox.System.getDeviceSettings().phoneConnected;
        var col = isBTConnected ? Graphics.COLOR_DK_GREEN : Graphics.COLOR_DK_RED;
        dc.setColor(col, Graphics.COLOR_TRANSPARENT);

        if (distance != null) {
            out = distance;
        } else {    
            var clockTime = System.getClockTime();
            out = Lang.format(
                "$1$:$2$",
                [
                    clockTime.hour.format("%02d"),
                    clockTime.min.format("%02d")
                ]
            );      
        }

        dc.drawText(screenWidth / 2, screenHeight - 40 ,  Graphics.FONT_TINY, out, Graphics.TEXT_JUSTIFY_CENTER);
    }
  • I will also add that I cannot get it to log the println() calls. 

    My app is generated as TWatchIQ.prg, I tried all lower/uppercase options in Garmin\Apps\Logs and nothing gets written there.

  • Additional question is - in all samples I see Communications.ConnectionListener() being instantiated for every message, like so:

    Communications.transmit(msg, null, new Communications.ConnectionListener());
    I have instantiated one listener, and I'm using it everywhere in the app - can that cause issues? I am sending the HR/Battery info every second...
    Thanks
  • First. have you looked at this?  https://developer.garmin.com/connect-iq/connect-iq-faq/how-do-i-use-a-mapview/#howdoiuseamapview

    Second, is your code in the class where you extend MapTrackView?

    Third, understand that MapView and MapTrackView are native views and on a device, pretty much handle themselves when it comes to things like screen updates

    Forth, is that in both cases, what you see in the sim is different that want to see on a real device and can also vary based on the device.  It's really most notable with MapTrackView - you don't see the track in the sim, but if your app starts up GPS, you see the track on real devices.  Here for example is a screen shot from a 955 with one of my apps.  It's pretty basic as I just walked around the house for a few minutes.

    The green icon is where I started, the blue, my current location, the red line is my track, and the curve and dots is related to pan/zoom so I could see a track.  Also, notice the scale at the bottom. And my apps doesn't draw any of this!  It's the native view itself.  In the sim, you don't see the red track or the scale

    Here's it's a bit more interesting as I have drawn the square for a waypoint and am displaying a message, so I do a few minor things

    What I would do is comment out things in your code, starting with the Communications.transmit() and adding return; as the first line in your onUpdate to see if that works or crashes.  With MapTrackView, understand that the screen gets updated very often on it's own (more than every second) - each time you move, your direction changes, etc - maybe 10 times a second - I've not timed it myself.  In the onUpdate for a MapTrackView, you do not want to do things like dc.clear() as you are actually drawing on top of the map (see my second screen shot)

  • The text in green I display in onUpdate() in the MapTrackView.

    As far as the Communications.transmit(), I'd do that in a separate timer every second, outside of MapTrackView.

  • Jim, thanks a lot for a detailed reply.

    I will respond properly to your comments when I'm back home. I was just testing the app, it seems it only crashes when it's outside with a gps fix, it doesn't seem to do that when testing at home. It crashed after about 10-12 minutes - perhaps it is all the drawing I do in onUpdate...

    I am testing the connection status in that method -  probably not the best idea.

    The transmit() method is called from onSensor(), although I have changed that to transmit at 5 secs interval and it did not help. 

    More comments soon.

  • Ok, back home now. 

    So of course I have read all the docs, and half the forum before posting Slight smile

    My onPosition and onSensor are outside of my mapview class, I have just pasted them as a single snippet here.

    I have learned quickly that the sim is not working quite like the devices, there are few differences making it not ideal for any testing. I am running all the tests on fenix7x.

    I have removed the whole onUpdate method for now. I don't think I need to display any additional details on that view, if it is causing any issues. I will just add another view for clock and some other information.

    However it seems that the devices is refreshing the MapView every second, not more often. That's what I see in the sim, but also when rotating the device it adjusts the bearing with a delay of about one sec. 

    I will do some more testing and update you with the results.

    Thanks

  • Hi, I think there might be a problem if you try to transmit more than one message at a time. The connection listener can be set up to keep track of the concurrent request. If there's more than one pending I'd recommend, not send the next message. I've had sporadic crashes in the past relating to this issue.

    On another note, is the companion app always registered for app messages to the watch? If your watch tries to transmit after the phone has unregistered from that watch, sometimes the communication between the two devices gets messed up.

    You should be fine using the same listener.

  • It seems that it doesn't care if the app on the phone is on or off, as long as the bluetooth is connected. 

    Few new questions - when I compile, should I use the latest SDK or the SDK that I have on my watch?

    Also, I am facing an issue that is described here:

    https://forums.garmin.com/developer/connect-iq/i/bug-reports/mapview-and-maptrackview-classes-are-broken---even-more-on-ciq3-1

    "if users used maps in native apps before opening CIQ app - it may put MapView/MapTrackView to wrong states like showing UI for zooming while reporting MAP_MODE_PREVIEW. In this case it is imposible to do any workaround in app to return classes or map screens to proper states. "

    But that thread is 4 years old, is it possible that it still exists? :D

    Another issue is that MapTrackView doesn't allow me to call setMapVisibleArea even in BROWSE_MODE. 

    Is that correct? I would like to focus screen on a marker when selected by the user. 

    I am calling setMapVisibleArea once in initialize(), after that any subsequent calls are ignored.

  • In general you always want to use the newest SDK (6.3.0 right now).

    I started using MapView and MapTrackView when they were first introduced.  I don't recall the bug you linked to, but I'd guess it's fixed now.

    In most cases, MapTrackView centers things based on your current location, even after you pan.  If you want to see how it works in a real app on your device, use my Hike2+ app: https://apps.garmin.com/en-US/apps/116a5b59-29ae-4397-a70e-907d7e5f8e44  Run the app, and after it gets GPS. start recording, and you then up/down to get to the map screen.  In that app, long press of the middle left button is pan/zoom as start is used for pause/resume/save/discard.

  • The issue is definitely still there.

    Fenix 7x, latest software.

    Run my app, it starts preview mode as expected.

    Close it.

    Run the built in Map application. Close it.

    Run my app, it starts in browse mode (even though the code forces preview), can't change it, since my code assumes it is in preview, but the up/down buttons are now mapped to +/-.