From aa56bc219e28a18407ffe8e1184ef33b7efae437 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sun, 1 Nov 2026 22:11:44 +0100 Subject: [PATCH] Sandbox: keep a launch intent for the FGS 2811f78 hid the sandbox from the launcher by removing its LAUNCHER category. flutter_foreground_task builds its notification from getLaunchIntentForPackage, which then returned null; the NPE meant startForeground never ran and Android killed the app with ForegroundServiceDidNotStartInTimeException on the first set tap and on every resume. A separate MAIN+INFO filter (checked before LAUNCHER) restores the intent and leaves the launcher entry hidden. The daily flavor keeps LAUNCHER and was never affected. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01WzxdWYdwRAtMg7ki6TKxuU --- .../app/src/sandbox/AndroidManifest.xml | 8 ++++ .../test/sandbox/sandbox_manifest_test.dart | 42 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 stronglift_replacement/workout_app/test/sandbox/sandbox_manifest_test.dart diff --git a/stronglift_replacement/workout_app/android/app/src/sandbox/AndroidManifest.xml b/stronglift_replacement/workout_app/android/app/src/sandbox/AndroidManifest.xml index 62832c7..c0db318 100644 --- a/stronglift_replacement/workout_app/android/app/src/sandbox/AndroidManifest.xml +++ b/stronglift_replacement/workout_app/android/app/src/sandbox/AndroidManifest.xml @@ -14,6 +14,14 @@ android:name="android.intent.category.LAUNCHER" tools:node="remove"/> + + + + + diff --git a/stronglift_replacement/workout_app/test/sandbox/sandbox_manifest_test.dart b/stronglift_replacement/workout_app/test/sandbox/sandbox_manifest_test.dart new file mode 100644 index 0000000..3c63022 --- /dev/null +++ b/stronglift_replacement/workout_app/test/sandbox/sandbox_manifest_test.dart @@ -0,0 +1,42 @@ +// The sandbox flavor is hidden from the launcher, which removes the only +// intent filter `getLaunchIntentForPackage` used to find. flutter_foreground_task +// builds its notification from that intent; null made `startForeground` throw, +// so Android killed the app with ForegroundServiceDidNotStartInTimeException. +import 'dart:io'; + +import 'package:flutter_test/flutter_test.dart'; + +/// Relative to the package root, which is `flutter test`'s cwd. +const _manifestPath = 'android/app/src/sandbox/AndroidManifest.xml'; + +void main() { + late String manifest; + + setUpAll(() => manifest = File(_manifestPath).readAsStringSync()); + + test('the sandbox stays out of the launcher', () { + expect( + manifest, + matches( + RegExp( + r'category\s+android:name="android\.intent\.category\.LAUNCHER"' + r'\s+tools:node="remove"', + ), + ), + ); + }); + + test('a MAIN + INFO filter keeps the package launchable by intent', () { + final filters = RegExp(r'(.*?)', dotAll: true) + .allMatches(manifest) + .map((m) => m.group(1)!); + expect( + filters.where( + (f) => + f.contains('android.intent.action.MAIN') && + f.contains('android.intent.category.INFO'), + ), + isNotEmpty, + ); + }); +}