feat(todo): reminders on arriving and leaving, on Android (ADR 0033, D32)

The system's proximity alerts, 150 m, no Google services, with a two-minute
dwell so that driving past doesn't remind (LocationDwell, with JUnit tests):
once a task until it changes, an alternative that reminded stopping the
task's others. Kept in the app's private preferences, registered anew after
a restart or an update. The position first, then "Allow all the time".
A debug build logs to `adb logcat -s HalkyonLocation`, and installs beside
the release as app.halkyon.todo.debug, "Todo Debug". With both installed
Android asks which answers SimpleLogin's way back, the scheme the instance
allows being one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
Tizian 「ティツィアーン」 2026-11-05 15:24:01 +01:00
commit e669c8d5b0
Signed by: raisondetredev
GPG key ID: 07F6FCF405488B64

View file

@ -0,0 +1,41 @@
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
/// Reminders at a place need the position with the app closed (ADR 0033,
/// D32), and their receiver stays the app's own.
void main() {
final manifest = File(
'android/app/src/main/AndroidManifest.xml',
).readAsStringSync();
bool declared(String permission) => manifest.contains(
'<uses-permission android:name="android.permission.$permission"/>',
);
test('the position is declared, precise and in the background', () {
expect(declared('ACCESS_COARSE_LOCATION'), isTrue);
expect(declared('ACCESS_FINE_LOCATION'), isTrue);
expect(declared('ACCESS_BACKGROUND_LOCATION'), isTrue);
});
test('no other app can tell the receiver a place was crossed', () {
expect(
manifest,
contains(
'<receiver android:exported="false" '
'android:name=".LocationReminderReceiver">',
),
);
});
test('a debug build installs beside the release, under its own name', () {
final gradle = File('android/app/build.gradle.kts').readAsStringSync();
expect(gradle, contains('applicationIdSuffix = ".debug"'));
expect(gradle, contains('manifestPlaceholders["appLabel"] = "Todo Debug"'));
expect(
gradle,
contains('manifestPlaceholders["appLabel"] = "Halkyon Todo"'),
);
});
}