Acknowledged
CIQQA-3357

Battery drain after app exit caused by ActivityRecording API

I have noticed behavior that the GPS gets turned on when I start an ActivityRecording session, without me needing to enable GPS events with 
Position.enableLocationEvents(Position.LOCATION_CONTINUOUS, method( :onPosition ));
When inspecting the FIT file after recording it is full of all the gps information, and when vieing the activity in the Connect app all the location data is as I would expect from an app utilizing GPS. I am using SPORT_RUNNING with a sub sport. I can't find anything in the documentation around whether this is expected or not. This seems reasonable to me and I am fine with this behavior.

The reason I bring this up is I have gotten reports, and have noticed myself, that there are battery drain issues after the app is closed. I have seen the other threads on this topic and have made sure to close the sensors, disable gps events, and close and null out the session and timers.
I clean up the Session as described in the documentation:
session.stop();
session.save();
session = null;

Yet the issue persists.
I have created an alternative version of my app where I don't use the Activity Recording and instead enable/disable the Sensors and GPS directly and I don't see the battery issue.
This leads me to believe there is an issue in the ActivityRecording API that turns on GPS/Sensors for its own use, but does not clean them up appropriately. Resulting in the battery drain.

I have primarily tested on FR955 but have gotten reports of it on Venu3S as well. I know one other person with FR245 and they claim not to be seeing the issue.
Given these API Versions: FR245 => 3.3, FR 955 + venu3s => 5.1, The issue might be localized to a later ConnectIQ API version.
  • Follow-up to my comment of 2026-09-09: a second device, a different model, same result.

    Recap of what that comment carried: a purpose-built test app (Connect IQ, ActivityRecording only, no Sensor subscriptions, no position request) that records a 60 s session, saves it and exits by the book, then asks the wearer whether the optical HR LED is still lit after the app is gone. It ran twice on a Forerunner 265 (software 29.05 beta) and the LED was solid after every by-the-book exit; no app-side workaround cleared it; only a watch restart did.

    The obvious objection to that report was that it rested on one watch on beta firmware. It no longer does.

    Second device: Forerunner 255, software bundle 29.05, a wearer unrelated to the first, running the same app installed from the Connect IQ store. One pass, from a watch restart, six steps, each one answered by looking at the back of the watch about 30 seconds after the app closed itself.

    1. Record 60 s as RACKET / PADEL, save, exit. LED ON.
    2. On the leaked watch: LOCATION_CONTINUOUS, then LOCATION_DISABLE, exit. LED ON.
    3. On the leaked watch: Sensor.setEnabledSensors([]) and Sensor.enableSensorEvents(null), exit. LED ON.
    4. On the leaked watch: a throwaway GENERIC session created, started, stopped and discarded, exit. LED ON.
    5. Record 60 s as GENERIC / GENERIC, save, exit. LED ON.
    6. Record 60 s as RACKET / PADEL, DISCARD instead of save, exit. LED ON.

    Every exit is stop(), then save() or discard(), then the session reference dropped, then the app exits; nothing is left recording, and the app never requests a position or subscribes to a sensor at any point.

    What the two devices agree on:

    - The leak is produced by a single 60 s recording from a fresh restart. It does not need a long session or a GPS session.
    - It is sport-independent. GENERIC / GENERIC leaks exactly like RACKET / PADEL on both watches. I mention this because the thread carries an earlier report that it was sport-dependent; on these two devices it is not.
    - It is save-independent. Discarding the session instead of saving it leaks the same way.
    - Nothing the application can do clears it. Releasing the position receiver, clearing the sensor subscriptions, and a throwaway start/stop/discard were each tried on an already-leaked watch. Counting an earlier variant where the throwaway session was held open five seconds before being stopped (three attempts on the FR265), that is eight attempted workarounds across the two watches, of which exactly one appeared to clear the leak once and then failed three of three when repeated. I read that one as noise.
    - A watch restart clears it every time, on both devices.

    So this reproduces on two models in the family this ticket already names (CIQ 5.2.0: FR255, FR265, FR955), on two separate wearers, and the second device is a different product from the beta-firmware one.

    Two limits I want to state plainly rather than have someone find:

    - The LED reading is the wearer's eyes, not an API. Connect IQ cannot read the optical sensor state, so every ON above is a human observation made at the back of the watch after the app closed.
    - I have no overnight drain figure from either tester, and I am not going to get one: both are volunteers who have already given me a careful run, and I am not sending them back to their watches for a third errand. What I have is the LED and the fact that a restart is the only cure - the same fingerprint the earlier reports in this thread describe, and the PDF already attached to this ticket has the percentages.

    The offer from my last comment stands: the test app is a single PRG I can send, and its full source is available - one app, no libraries, about ten short files, and every step above is one function. If someone on the Connect IQ side wants either, say so here and I will attach it or mail it. Both testers are ordinary users of my app rather than developers, and their summary photos show their wrists and device identifiers, so I am not posting those publicly; I can share a cropped copy of either privately with an engineer who wants it.

    In the meantime the only thing I can give my users is a store note telling them to restart the watch after playing, which is not a good place for a scorekeeping app to be.

  • I'm curious. 

    My app has an issue of freezing the watch fully and causing the GPS ect to stay on and thus battery drain.

    Even a reboot keeps the battery drain. The only thing that works is starting a Run activity and quitting it.

    Could you test this instead of a reboot. It's visible if it works if the drain goes back to gray. I tha battery widget.

  • Also happening with Fenix 9 pro 51 Solar.  Restarting still required :( 

  • Some thoughts:

    - Most of the thread hints it's a GPS thing, your test hints it's a HR thing.

    - If the assumption is that it's a GPS thing, then it would make sense to test it with an Indoor Walk or Indoor something activity, that doesn't turn GPS on. I don't think the activity type is what matters, but if different activity types turn on different hardware, then it might make a difference.

    - At least in your case there's a visible way to see that there's a problem, unlike when the GPS stays on

  • Another reproduction, on a Forerunner 265 - and two assumptions in this thread ruled out on that device.

    I maintain a padel scorekeeper device app on the Connect IQ store. A user reported ~25% overnight drain (about 2.5%/h, roughly 10x his normal) after playing, with the watch face showing and the app exited normally. The visible symptom is the optical HR LED staying solid after the app closes. Device: Forerunner 265, firmware 29.05 (beta), Android phone.

    Rather than guess, I built a guided diagnostics device app and had him run it. Each step records one 60-second ActivityRecording session, exits, and he looks at the back of the watch about 30 seconds later and answers ON/OFF at the next open. Steps that need it start from a watch restart. The recording path is exactly this, nothing else in it:

    var s = ActivityRecording.createSession({
    :sport => Activity.SPORT_RACKET, :subSport => Activity.SUB_SPORT_PADEL, :name => "..."
    });
    s.start();
    // 60 s
    s.stop();
    s.save(); // or s.discard()
    System.exit();

    Run 1 (broad, 8 steps). ON = LED solid after the app closed.

    - padel session (RACKET/PADEL), saved, exit -> ON. One 60-second session from a fresh restart is enough; it does not take a long activity.
    - Position.enableLocationEvents(LOCATION_CONTINUOUS, cb) then LOCATION_DISABLE on the leaked watch, exit -> ON (does not clear it).
    - Sensor.setEnabledSensors([]) + Sensor.enableSensorEvents(null) on the leaked watch, exit -> ON (does not clear it).
    - a second, scratch GENERIC session, start()/stop()/discard() in one call, exit -> OFF (cleared), once.
    - re-leak -> ON; the same scratch again -> ON. So 1 of 2.
    - GENERIC/GENERIC session instead of RACKET/PADEL, saved, from a fresh restart -> ON.
    - padel session discarded instead of saved, from a fresh restart -> ON.

    Run 2 (narrow, next day). Same watch, same firmware.

    - leak run -> ON.
    - scratch GENERIC session held open 5 seconds before stop(), then discard(), then exit -> ON, three times in a row. 0 of 3.

    A watch restart clears it every time, as everyone else in this thread reports.

    What that rules out on this device:

    1. Not sport-dependent. GENERIC/GENERIC leaks exactly like RACKET/PADEL. The thread's working assumption is that the bug depends on the Sport/SubSport; on the FR265 it does not.
    2. Not the saving. A discarded session leaks the same as a saved one - it is the session itself that leaves the state behind.
    3. Not fixable from inside the app. Releasing location events and sensors before exit changes nothing, and re-entering and leaving recording clears it only by coincidence: 1 of 5 attempts across both runs, and 0 of 3 when the second session was given time to actually run.

    Brandon asked earlier in this thread for a PRG that reproduces it. I have one: the diagnostics app above is on the Connect IQ store as "PU Diagnostics", and I can attach the PRG plus the relevant source here or send it wherever is convenient - it is a small app whose only job is this test.

    A second user, on a Forerunner 255, is running the same test now, and I will post his rows here. If it matters for triage: this FR265 is on beta firmware 29.05, which is why I want the second device on public firmware before anyone concludes it is a beta-only regression.

    In the meantime the only advice I can give my users is to restart the watch after playing, and my store listing carries a note about it.