use location instead of geolocator, stop play services from getting embedded

This commit is contained in:
Henry Hiles 2026-11-11 16:37:18 -05:00
commit 161d39322c
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
10 changed files with 65 additions and 99 deletions

View file

@ -1,7 +1,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- The location plugin only needs these for background location, which Nexus doesn't use -->
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE"
tools:node="remove" />
<uses-permission
android:name="android.permission.FOREGROUND_SERVICE_LOCATION"
tools:node="remove" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />

View file

@ -5,3 +5,5 @@ android.enableJetifier=true
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
# Leaves proprietary Google Play services out of the location plugin
location.playServices=false

View file

@ -2,7 +2,7 @@ import "dart:async";
import "dart:io";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:geolocator/geolocator.dart";
import "package:location/location.dart";
import "package:latlong2/latlong.dart";
import "package:nexus/controllers/portal.dart";
import "package:nexus/models/location_exception.dart";
@ -13,7 +13,7 @@ class CurrentLocationHelper(final Ref ref) {
/// The user's location and its accuracy in meters, or null if [askPermission]
/// is off and they haven't allowed it.
Future<(LatLng, double?)?> get({required bool askPermission}) async {
// geolocator talks to GeoClue directly, which Flatpak's sandbox blocks, so
// location talks to GeoClue directly, which Flatpak's sandbox blocks, so
// Linux uses the location portal, which also asks the user for permission
if (Platform.isLinux) {
// The portal can't say whether it's allowed without asking
@ -40,40 +40,36 @@ class CurrentLocationHelper(final Ref ref) {
}
}
if (!await Geolocator.isLocationServiceEnabled()) {
final location = Location.instance;
if (!await location.serviceEnabled()) {
if (!askPermission) return null;
throw LocationException.servicesOff;
}
var permission = await Geolocator.checkPermission();
var permission = await location.hasPermission();
if (permission == .denied && askPermission) {
permission = await Geolocator.requestPermission();
permission = await location.requestPermission();
}
if (permission == .denied || permission == .deniedForever) {
if (!askPermission) return null;
throw LocationException.denied;
}
Position? position;
LocationData? data;
try {
position = await Geolocator.getCurrentPosition(
locationSettings: Platform.isAndroid
// Play services' location can hang without Google, like on microG,
// so this uses Android's own, as other apps do
? AndroidSettings(forceLocationManager: true, timeLimit: _timeLimit)
: const LocationSettings(timeLimit: _timeLimit),
);
data = await location.getLocation().timeout(_timeLimit);
} on TimeoutException {
// A fix can take long indoors, but another app may have a recent one
position = await Geolocator.getLastKnownPosition(
forceAndroidLocationManager: true,
data = await location.getLastKnownLocation().onError(
(_, _) => throw LocationException.failed,
);
} catch (_) {
throw LocationException.failed;
}
if (position == null) throw LocationException.timedOut;
return (LatLng(position.latitude, position.longitude), position.accuracy);
if (data == null) throw LocationException.timedOut;
return (LatLng(data.latitude, data.longitude), data.accuracy);
}
static final provider = Provider<CurrentLocationHelper>(

View file

@ -9,6 +9,7 @@
#include <app_links_linux/app_links_plugin_linux.h>
#include <dynamic_color/dynamic_color_plugin.h>
#include <file_selector_linux/file_selector_plugin.h>
#include <location/location_plugin.h>
#include <media_kit_libs_linux/media_kit_libs_linux_plugin.h>
#include <media_kit_video/media_kit_video_plugin.h>
#include <pasteboard/pasteboard_plugin.h>
@ -24,6 +25,9 @@ void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) location_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "LocationPlugin");
location_plugin_register_with_registrar(location_registrar);
g_autoptr(FlPluginRegistrar) media_kit_libs_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "MediaKitLibsLinuxPlugin");
media_kit_libs_linux_plugin_register_with_registrar(media_kit_libs_linux_registrar);

View file

@ -6,6 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
app_links_linux
dynamic_color
file_selector_linux
location
media_kit_libs_linux
media_kit_video
pasteboard

View file

@ -9,7 +9,7 @@ import app_links
import dynamic_color
import file_selector_macos
import flutter_local_notifications
import geolocator_apple
import location
import media_kit_libs_macos_video
import media_kit_video
import package_info_plus
@ -23,7 +23,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))
LocationPlugin.register(with: registry.registrar(forPlugin: "LocationPlugin"))
MediaKitLibsMacosVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitLibsMacosVideoPlugin"))
MediaKitVideoPlugin.register(with: registry.registrar(forPlugin: "MediaKitVideoPlugin"))
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))

View file

@ -633,70 +633,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
geoclue:
dependency: transitive
description:
name: geoclue
sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f
url: "https://pub.dev"
source: hosted
version: "0.1.1"
geolocator:
dependency: "direct main"
description:
name: geolocator
sha256: "2b3bc0f7320d5a5fa02f8209ffcf1aaa7c2cabb7b2bedbc0cfeb5ff2778b8b09"
url: "https://pub.dev"
source: hosted
version: "14.1.2"
geolocator_android:
dependency: transitive
description:
name: geolocator_android
sha256: e67583809a1fab5f4a2255902978e2bc095ace9451fde0d9624e54facd0a5c22
url: "https://pub.dev"
source: hosted
version: "5.2.1"
geolocator_apple:
dependency: transitive
description:
name: geolocator_apple
sha256: a1e177f3081089724f2095856aeb96eb8d7d1c59e425aed8dd4de7aa2c11ab66
url: "https://pub.dev"
source: hosted
version: "2.4.3"
geolocator_linux:
dependency: transitive
description:
name: geolocator_linux
sha256: "3da7420f11c3496511a5bd3c18fd67b88e5659f12e46b7ce00a788f6996e850a"
url: "https://pub.dev"
source: hosted
version: "0.2.6"
geolocator_platform_interface:
dependency: transitive
description:
name: geolocator_platform_interface
sha256: e012af6b7e2674e7500237ab11e44ac9119e87fd0105e7bb55cde1750e8e5d80
url: "https://pub.dev"
source: hosted
version: "4.4.1"
geolocator_web:
dependency: transitive
description:
name: geolocator_web
sha256: "19e485a0f8d6a88abcf9c53cba3a4105e14b7435ed8ac1c108c067b938fe8429"
url: "https://pub.dev"
source: hosted
version: "4.1.4"
geolocator_windows:
dependency: transitive
description:
name: geolocator_windows
sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6"
url: "https://pub.dev"
source: hosted
version: "0.2.5"
glob:
dependency: transitive
description:
@ -713,14 +649,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.2"
gsettings:
dependency: transitive
description:
name: gsettings
sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c"
url: "https://pub.dev"
source: hosted
version: "0.2.8"
hooks:
dependency: "direct main"
description:
@ -959,6 +887,31 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.1"
location:
dependency: "direct main"
description:
path: "packages/location"
ref: "feat/optional-play-services"
resolved-ref: "70e2fbe87a4a8769de08f1692412d731063dcfc0"
url: "https://github.com/Henry-Hiles/flutterlocation"
source: git
version: "10.1.0"
location_platform_interface:
dependency: transitive
description:
name: location_platform_interface
sha256: a47b6d790eeb7308147293aedec0efb3b62d9f1b10899679be04f91cff664821
url: "https://pub.dev"
source: hosted
version: "7.1.0"
location_web:
dependency: transitive
description:
name: location_web
sha256: da3812c65ca683c6180790838f551de10122a4887ffbd569360c9cb2d85859b7
url: "https://pub.dev"
source: hosted
version: "7.0.1"
logging:
dependency: transitive
description:

View file

@ -119,7 +119,11 @@ dependencies:
avif_native: 0.2.0
flutter_map: 8.3.2
latlong2: 0.10.1
geolocator: 14.1.2
location:
git:
url: https://github.com/Henry-Hiles/flutterlocation # Adds an option to leave out proprietary Google Play services, unreleased
ref: feat/optional-play-services
path: packages/location
dev_dependencies:
flutter_test:
sdk: flutter

View file

@ -9,7 +9,7 @@
#include <app_links/app_links_plugin_c_api.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <file_selector_windows/file_selector_windows.h>
#include <geolocator_windows/geolocator_windows.h>
#include <location/location_plugin.h>
#include <media_kit_libs_windows_video/media_kit_libs_windows_video_plugin_c_api.h>
#include <media_kit_video/media_kit_video_plugin_c_api.h>
#include <pasteboard/pasteboard_plugin.h>
@ -22,8 +22,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("DynamicColorPluginCApi"));
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
GeolocatorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("GeolocatorWindows"));
LocationPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("LocationPlugin"));
MediaKitLibsWindowsVideoPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("MediaKitLibsWindowsVideoPluginCApi"));
MediaKitVideoPluginCApiRegisterWithRegistrar(

View file

@ -6,7 +6,7 @@ list(APPEND FLUTTER_PLUGIN_LIST
app_links
dynamic_color
file_selector_windows
geolocator_windows
location
media_kit_libs_windows_video
media_kit_video
pasteboard