fix(android): drop geolocator for a native LocationManager channel

Removes the geolocator dependency, which transitively embedded
com.google.android.gms.* (play-services-location) — proprietary classes
that F-Droid's scanner rejects. The optional coarse-location button now
talks to Android's own LocationManager over a small platform channel
(org.comunes.tane/coarse_location): permission prompt, single coarse fix
with a 12s timeout, last-known fallback, null on any failure. Behavior
is unchanged and the CoarseLocationProvider interface is preserved, so
the UI, i18n and widget tests need no changes.

Also sets dependenciesInfo.includeInApk/Bundle = false so the AGP
dependency-metadata block (also flagged by F-Droid) is not embedded.
Neither change affects the Google Play build.
This commit is contained in:
vjrj 2026-07-17 09:19:05 +02:00
parent 7f1118a243
commit d0fabb80a9
9 changed files with 264 additions and 93 deletions

View file

@ -0,0 +1,59 @@
import 'package:tane/services/coarse_location.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
const channel = MethodChannel('org.comunes.tane/coarse_location');
final messenger =
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
tearDown(() {
messenger.setMockMethodCallHandler(channel, null);
debugDefaultTargetPlatformOverride = null;
});
test('returns the lat/lon the platform channel provides', () async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
messenger.setMockMethodCallHandler(channel, (call) async {
expect(call.method, 'getCoarseLatLon');
return {'lat': 41.39, 'lon': 2.16};
});
final loc = await const NativeCoarseLocation().currentCoarseLatLon();
expect(loc, isNotNull);
expect(loc!.lat, 41.39);
expect(loc.lon, 2.16);
});
test('returns null when the platform reports no fix (denied/off)', () async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
messenger.setMockMethodCallHandler(channel, (call) async => null);
expect(await const NativeCoarseLocation().currentCoarseLatLon(), isNull);
});
test('returns null instead of throwing on a channel error', () async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
messenger.setMockMethodCallHandler(channel, (call) async {
throw PlatformException(code: 'boom');
});
expect(await const NativeCoarseLocation().currentCoarseLatLon(), isNull);
});
test('returns null off Android without touching the channel', () async {
debugDefaultTargetPlatformOverride = TargetPlatform.linux;
var invoked = false;
messenger.setMockMethodCallHandler(channel, (call) async {
invoked = true;
return {'lat': 1.0, 'lon': 1.0};
});
expect(await const NativeCoarseLocation().currentCoarseLatLon(), isNull);
expect(invoked, isFalse);
});
}