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,
+ );
+ });
+}