Flutter-geolocator: bekam `LocationServiceDisabledException` wenn `Geolocator.isLocationServiceEnabled() true zurückgibt

Erstellt am 6. Nov. 2020  ·  20Kommentare  ·  Quelle: Baseflow/flutter-geolocator

🐛 Fehlerbericht

Erwartetes Verhalten

Versuchen Sie, den aktuellen Standort abzurufen, nachdem die Standortberechtigung erteilt wurde und der Standortdienst ebenfalls aktiviert ist, aber ich habe LocationServiceDisabledException wenn getCurrentPosition aufgerufen wird

Reproduktionsschritte

try {
      final enabled = await Geolocator.isLocationServiceEnabled();

      print("enabled $enabled"); // true

      final permission = await Geolocator.checkPermission();

      print("permission $permission"); // whileInUse

      final position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.medium,
      ); // throw exception here

    } catch (e) {
        // i got `LocationServiceDisabledException` here
    }

Aufbau

alle damit verbundenen Berechtigungen werden erteilt und alle Konfigurationen in Android sind abgeschlossen.

Version: 6.1.5

Plattform:

  • [ ] :iphone: iOS
  • [x] :Roboter: Android
android triage

Hilfreichster Kommentar

Ich habe gerade die Version 6.1.10 des Geolocator-Plugins veröffentlicht, die dieses Problem lösen sollte.

Es stellte sich heraus, dass in Android die Callback-Methode onLocationAvailability häufig meldet, dass ein Standort nicht verfügbar ist und nicht nur, wenn die Standortdienste deaktiviert sind. Ich habe die Handhabung dieser Methode verfeinert und Sie sollten keine falschen LocationServiceDisabledException Ausnahmen mehr erfahren.

Vielen Dank an alle, die das Problem gemeldet, geklärt und geholfen haben, das Problem zu reproduzieren.

Alle 20 Kommentare

Ich habe den gleichen Fehler, aber nur, wenn ich LocationAccuracy vom Standardwert auf etwas anderes ändere

StreamSubscription _streamSubscription = Geolocator.getPositionStream( // desiredAccuracy: LocationAccuracy.medium, <-- LocationServiceDisabledException error if I use a different accuracy distanceFilter: 500 ).listen(_listenData)..onError((e, stk) => print(e));

Ich bin auf der Suche nach diesem Problem, aber es fällt mir schwer, es zu reproduzieren. Vielleicht können Sie die folgenden Fragen beantworten und mir helfen, dieses Problem zu beheben:

  1. Sehen Sie das auf einem Emulator oder auch auf echten Geräten?
  2. Sind die Google Play-Dienste installiert (je nachdem verwendet der Geolocator entweder das FusedLocationProvider SDK oder das LocationManager SDK, dies könnte mir helfen, das Problem einzugrenzen)?

Wir freuen uns auf Feedback, damit wir diese Sache angehen können.

Ich habe das gleiche Unhandled Exception: The location service on the device is disabled. wenn ich es tue

Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.low);

auch wenn der Ortungsdienst für diese App aktiviert ist.

  1. Ein echtes Gerät bei Android 10
  2. Google Play-Dienste sind installiert

Ich habe es ausprobiert und es funktioniert mit mittlerer Genauigkeit. Aber mit anderen Einstellungen nicht.

  1. Emulatoren.
  2. Habe beides probiert.

Habe den gleichen Fehler und es funktioniert auch nicht mit irgendwelchen Einstellungen. Getestet sowohl auf dem Emulator als auch auf einem echten Gerät, wobei der Standort immer aktiviert ist.

Es scheint, als würde ich nur mit bester Genauigkeit arbeiten. Aber für andere nicht.

  1. Emulator.
  2. Google Play-Dienste installiert

Ich danke Ihnen allen, dass Sie weitere Rückmeldungen gegeben haben. Wir prüfen es derzeit, können es aber immer noch nicht reproduzieren. Dies hat wahrscheinlich etwas damit zu tun, dass bestimmte Einstellungen aktiviert/deaktiviert wurden.

Wenn wir es erfahren, werden wir Sie natürlich darüber informieren. In der Zwischenzeit sind wir für weitere Informationen offen (dh geschieht dies bei allen Android-APIs oder nur bei Android 10).

Ich habe den gleichen Fehler. https://prnt.sc/vr3glj

Ich erhalte das gleiche Problem nur, wenn das Gerät nicht mit einem Netzwerk (WIFI oder MOBILE) verbunden ist und ich mich in einem Gebäude befinde (dh: schlechte GPS-Verbindung)

aktuelle Stream-Einstellungen:
StreamSubscription<Position> positionStream = Geolocator.getPositionStream( desiredAccuracy: LocationAccuracy.best, distanceFilter: 0) .listen((Position position) {}

AndroidManifest.xml: <!--Location--> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Standorteinstellungen des Geräts: Hohe Genauigkeit (Verwenden Sie GPS, Wi-Fi, Bluetooth und mobile Netzwerke, um den Standort zu bestimmen)
Bearbeiten: Physisches Gerät verwenden

Danke @seb3n das sind sehr hilfreiche Informationen. Ich bin sicher, das wird mir etwas zum Weitermachen geben.

Ich danke Ihnen allen, dass Sie weitere Rückmeldungen gegeben haben. Wir prüfen es derzeit, können es aber immer noch nicht reproduzieren. Dies hat wahrscheinlich etwas damit zu tun, dass bestimmte Einstellungen aktiviert/deaktiviert wurden.

Wenn wir es erfahren, werden wir Sie natürlich darüber informieren. In der Zwischenzeit sind wir für weitere Informationen offen (dh geschieht dies bei allen Android-APIs oder nur bei Android 10).

@mvanbeusekom Ich habe das gleiche Problem auf Android 9

E/flutter (31570): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: The location service on the device is disabled.
E/flutter (31570): #0      MethodChannelGeolocator._handlePlatformException (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:192:9)
E/flutter (31570): #1      MethodChannelGeolocator.getCurrentPosition (package:geolocator_platform_interface/src/implementations/method_channel_geolocator.dart:121:7)
E/flutter (31570): <asynchronous suspension>
E/flutter (31570): #2      Geolocator.getCurrentPosition (package:geolocator/geolocator.dart:258:35)

isLocationServiceEnabled ist wahr
Code

      bool isLocationServiceEnabled =
          await Geolocator.isLocationServiceEnabled();
      AppLog.d(isLocationServiceEnabled);
      if (isLocationServiceEnabled) {
        Position position = await Geolocator.getCurrentPosition(
            desiredAccuracy: LocationAccuracy.high);
        return {"position": position.toString()};
      }

position = await Geolocator.getCurrentPosition( desiredAccuracy: LocationAccuracy.medium, forceAndroidLocationManager: true) .timeout(Duration(seconds: 10));

Dieser Code hat bei mir funktioniert.

Dies ist mein Versuch, einen minimalen reproduzierbaren Fehler zu erzeugen

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'dart:async';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  <strong i="6">@override</strong>
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Flutter Demo',
        home: SafeArea(
          child: Scaffold(body: GeoLocatorWidget()),
        ));
  }
}

class GeoLocatorWidget extends StatefulWidget {
  const GeoLocatorWidget({
    Key key,
  }) : super(key: key);

  <strong i="7">@override</strong>
  _GeoLocatorWidgetState createState() => _GeoLocatorWidgetState();
}

class _GeoLocatorWidgetState extends State<GeoLocatorWidget> {
  StreamSubscription<Position> _streamSubscription;
  String message = 'empty';

  <strong i="8">@override</strong>
  void initState() {
    super.initState();
    _streamSubscription = Geolocator.getPositionStream(
            //desiredAccuracy: LocationAccuracy.medium,
            distanceFilter: 500)
        .listen(_onData, onError: _onError);
  }

  void _onData(Position position) {
    ScaffoldState _scaffoldKey = Scaffold.of(context, nullOk: true);
    if ((_scaffoldKey?.mounted ?? false)) _scaffoldKey.hideCurrentSnackBar();
    setState(() {
      message = 'latitude: ${position.latitude}, longitude: ${position.longitude}';
    });
  }

  void _onError(dynamic error) {
    bool geoService = error is LocationServiceDisabledException ||
        error is PermissionDeniedException;
    ScaffoldState _scaffoldKey = Scaffold.of(context, nullOk: true);
    if (!(_scaffoldKey?.mounted ?? false)) return;
    _scaffoldKey.hideCurrentSnackBar();
    _scaffoldKey.showSnackBar(SnackBar(
      content: Text('$error'),
      duration: const Duration(minutes: 2),
      action: geoService
          ? SnackBarAction(
              label: 'Change',
              onPressed: () async {
                if (error is LocationServiceDisabledException) {
                  bool locationEnabled =
                      await Geolocator.isLocationServiceEnabled();
                  if (!locationEnabled) await Geolocator.openLocationSettings();
                  else setState(() {
                    message = '''
                      locationService is enabled but the error says 
                      its of type LocationServiceDisabledException anyway :(
                    ''';
                  });
                } else await Geolocator.openAppSettings();
              },
            )
          : null,
    ));
  }

  <strong i="9">@override</strong>
  void dispose() {
    _streamSubscription?.cancel();
    super.dispose();
  }

  <strong i="10">@override</strong>
  Widget build(BuildContext context) {
    return Center(
      child: Text(message),
    );
  }
}

Alle Berechtigungen im AndroidManifest hinzufügen

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

SCHRITTE ZUM REPRODUZIEREN

  1. Das streamSubscription wird initialisiert und fragt nach Erlaubnis und Standortdienst, wir gewähren beides und es zeigt sowohl den Breiten- als auch den Längengrad korrekt auf dem Bildschirm an
  2. Schalten Sie den Bildschirm bei geöffneter App aus (simulieren Sie, dass der Benutzer abgelenkt ist und nach einer Minute wiederkommt)
  3. Schalten Sie den Bildschirm ein / entsperren Sie und die App zeigt nun eine Snackbar mit dem Fehler ( LocationServiceDisabledException ) und eine snackBarAction-Schaltfläche "Ändern"
  4. Wenn die Schaltfläche angetippt wird, wird asynchron überprüft, ob der Ortungsdienst wirklich deaktiviert ist, wenn er deaktiviert ist, wird versucht, Geolocator.openLocationSettings(); zu öffnen, wenn er aktiviert ist, auch wenn der Fehler vom Typ LocationServiceDisabledException ( das Problem dieses Threads), dann ändern Sie einfach den Bildschirmtext, der Ihnen mitteilt, dass er aktiviert ist und nicht wirklich nichts tun kann

Überlegungen

  • Getestet mit einem echten Gerät mit Android 8.1.0 und Android 10, funktionierte alles in Android 8.1.0 einwandfrei (aus- und einschalten, nach einer Weile zur App zurückkehren und keinen Fehler anzeigen), aber das Problem blieb mit Android bestehen 10
  • Der Fehler konnte im Emulator nicht auftreten (vielleicht hat dies mit dem Doze- oder Batteriesparmodus zu tun)
  • Ich verstehe, dass das Plugin keine Hintergrundspeicherung zulässt, aber es sollte diesen Fehler nicht senden, wenn der Standort eindeutig aktiviert ist, und den Stream einfach fortsetzen, wenn die App wieder im Vordergrund ist (oder vielleicht eine andere Nachricht senden, um zu wissen, ob es sich wirklich um eine Problem mit dem Standortdienst)
  • Dies hängt auch mit # 568 zusammen, wo die Berechtigung / der Dienst deaktiviert und dann aktiviert wird. Eine Möglichkeit besteht darin, WidgetsBindingObserver zu verwenden, um den Stream beim Verlassen der App neu zu erstellen (Beim Öffnen von Einstellungen zum Ändern des Standorts oder der Berechtigungen der App)
<strong i="5">@override</strong>
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.paused:
        if (_streamSubscription != null) {
          _streamSubscription.cancel();
          _streamSubscription = null;
        }
        break;
      case AppLifecycleState.resumed:
        _streamSubscription ??= Geolocator.getPositionStream(
            //desiredAccuracy: LocationAccuracy.medium,
            distanceFilter: 500).listen(_onData, onError: _onError);
        break;
      default:
        break;
    }
  }

Was gut funktioniert, wenn der Benutzer auf die Schaltfläche "Ändern" tippt, zu den Standortdiensteinstellungen weitergeleitet wird, ihn einschaltet und zur App zurückkehrt, aber es funktioniert nicht, wenn der Benutzer es einfach über die Statusleiste aktiviert (der Stream hört danach einfach auf, Werte zurückzugeben).

Eine andere Idee ist, die Methoden cancelOnError: true und HandleError verwenden, um einige Fehler des Streams abzufangen und das Schließen zu verhindern, wenn es nicht so wichtig ist (etwas, das nicht behandelt werden kann), aber weil es LocationServiceDisabledException zurückgibt HandleError

Ich habe einen weiteren Test auf einem physischen Gerät mit frisch installiertem Android 8.0.0 durchgeführt

API-Aufruf

Position position = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.$accuracy$,
    ).timeout(Duration(seconds: 10));

Ergebnisse für jeden $accuracy$-Wert:
| $Genauigkeit$ | Ergebnis |
|------------------|-------------------------------------- -----|
| niedrigste | TimeoutException |
| niedrig | LocationServiceDisabledException |
| mittel | LocationServiceDisabledException |
| hoch | TimeoutException |
| am besten | LocationServiceDisabledException |
| bestForNavigation | TimeTimeoutException |

AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Geräteeinstellungen

Gerätestandorteinstellungen: Hohe Genauigkeit (Verwenden Sie GPS, Wi-Fi und mobile Netzwerke)
WLAN: Verbunden
VPN: Keine
GPS-Signalstärke: Sei stark
Standortinformationen: On
Letzte Standortanfragen: Zeigt die App an, die die Geolocation-API aufgerufen hat

Ich habe gerade die Version 6.1.10 des Geolocator-Plugins veröffentlicht, die dieses Problem lösen sollte.

Es stellte sich heraus, dass in Android die Callback-Methode onLocationAvailability häufig meldet, dass ein Standort nicht verfügbar ist und nicht nur, wenn die Standortdienste deaktiviert sind. Ich habe die Handhabung dieser Methode verfeinert und Sie sollten keine falschen LocationServiceDisabledException Ausnahmen mehr erfahren.

Vielen Dank an alle, die das Problem gemeldet, geklärt und geholfen haben, das Problem zu reproduzieren.

Ich habe den gleichen Fehler, ich habe ihn auf dem xiaomi Redmi Note 8 reproduziert, während er auf einem huawei p20 lite einwandfrei funktioniert.
Ich stelle fest, dass die folgende Methode true zurückgibt, wenn Dienste auf dem xiaomi deaktiviert sind. Sie sollte false zurückgeben, genau wie es auf dem Huawei der Fall ist.
Die Plugin-Version ist: Geolocator: ^6.1.13
wait Geolocator.isLocationServiceEnabled ()

Wie @sejr1996 habe ich das gleiche Problem mit Version 6.1.13 in Nokia 3.1 (android 9), Galaxy A10s (android 10) festgestellt.

The location service on the device is disabled.
       at MethodChannelGeolocator._handlePlatformException(MethodChannelGeolocator.java:192)
       at MethodChannelGeolocator.<fn>(MethodChannelGeolocator.java:171)

Wie @sejr1996 habe ich das gleiche Problem mit Version 6.1.13 in Nokia 3.1 (android 9), Galaxy A10s (android 10) festgestellt.

The location service on the device is disabled.
       at MethodChannelGeolocator._handlePlatformException(MethodChannelGeolocator.java:192)
       at MethodChannelGeolocator.<fn>(MethodChannelGeolocator.java:171)

Mir geht es gleich

Ich glaube, es ist schon behoben. Mein letzter Ausweg, um den Standort des Dienstes zu reparieren, bestand darin, das Standortpaket zu verwenden. aber jetzt mit der neuen Version des Geolocator-Pakets. die Standortberechtigung kommt zuerst, dann folgt der Dienststandort.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen