Lyokone / flutterlocation

A Flutter plugin to easily handle realtime location in iOS and Android. Provides settings for optimizing performance or battery.
MIT License
1.11k stars 820 forks source link

getLocation() and onLocationChanged() blocks with no response. #83

Closed zedan185 closed 5 years ago

zedan185 commented 6 years ago

Now I added the package in my pubspec.yaml in the following way:

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^0.1.0
  progress_hud:
     git: https://github.com/LampeMW/progress_hud/
  crypto: any
  validate: "^1.6.0"
  json_annotation: ^0.2.4
  image_picker: "^0.4.1"
  after_layout: "^1.0.4"
  firebase_messaging: #0.2.1
  device_info: ^0.2.1
#  geolocator: '^2.0.1'
  location: 
    git: https://github.com/Lyokone/flutterlocation.git/

And I tried the following two ways - both of them block and never return


//This method blocks
  Map<String, double> location = await new Location().onLocationChanged().single;

//This method also blocks and never continues
  currentLocation  = await  myLocation.Location().getLocation();

Here is the output from my flutter doctor

[✓] Flutter (Channel beta, v0.6.0, on Mac OS X 10.13.6 17G65, locale en-US) • Flutter version 0.6.0 at /Users/admin/Flutter/flutter • Framework revision 9299c02cf7 (8 weeks ago), 2018-08-16 00:35:12 +0200 • Engine revision e3687f70c7 • Dart version 2.1.0-dev.0.0.flutter-be6309690f

[✓] Android toolchain - develop for Android devices (Android SDK 28.0.0) • Android SDK at /Users/hsheikh/Library/Android/sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-28, build-tools 28.0.0 • ANDROID_HOME = /Users/admin/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01) • All Android licenses accepted.

[✓] iOS toolchain - develop for iOS devices (Xcode 9.4.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 9.4.1, Build version 9F2000 • ios-deploy 1.9.2 • CocoaPods version 1.5.0

[✓] Android Studio (version 3.1) • Android Studio at /Applications/Android Studio.app/Contents ✗ Flutter plugin not installed; this adds Flutter specific functionality. ✗ Dart plugin not installed; this adds Dart specific functionality. • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b01)

[✓] IntelliJ IDEA Ultimate Edition (version 2018.1.1) • IntelliJ at /Applications/IntelliJ IDEA.app • Flutter plugin version 24.0.2 • Dart plugin version 181.4445.29

[✓] Connected devices (1 available) • Android SDK built for x86 • emulator-5554 • android-x86 • Android 7.1.1 (API 25) (emulator)

• No issues found!

Any suggestions on what might be happening here. I tried the package geolocator and it behaves the same way except sometimes it would work (by not blocking). Why is this happening and how can I fix this ?

timtraversy commented 6 years ago

Did you request user permission before calling these? Does the permission dialogue pop up?

mohlam12 commented 6 years ago

Same problem! await _location.getLocation(); gets stuck while await _location.hasPermissions() returns true.

It only works when I reinstall the app!

Also, this seems to have happened after my latest flutter upgrade.


[√] Flutter (Channel beta, v0.9.4, on Microsoft Windows [version 10.0.17134.345], locale fr-FR) • Flutter version 0.9.4 at C:\flutter • Framework revision f37c235c32 (3 weeks ago), 2018-09-25 17:45:40 -0400 • Engine revision 74625aed32 • Dart version 2.1.0-dev.5.0.flutter-a2eb050044

[√] Android toolchain - develop for Android devices (Android SDK 27.0.3) • Android SDK at C:\Users\lamha\AppData\Local\Android\sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-27, build-tools 27.0.3 • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02) • All Android licenses accepted.

[√] Android Studio (version 3.1) • Android Studio at C:\Program Files\Android\Android Studio • Flutter plugin version 28.0.1 • Dart plugin version 173.4700 • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1024-b02)

[√] Connected devices (1 available) • Android SDK built for x86 • emulator-5554 • android-x86 • Android 8.1.0 (API 27) (emulator)

timtraversy commented 6 years ago

You're actually calling _location.getLocation() not _location.getLocation right?

mohlam12 commented 6 years ago

Yes, forgot the parenthesis!

mohlam12 commented 6 years ago

When I use _location.getLocation().then((val){}); this pops out

E/flutter ( 3845): [ERROR:flutter/shell/common/shell.cc(181)] Dart Error: Unhandled exception:
E/flutter ( 3845): PlatformException(ERROR, Failed to get location., null)
E/flutter ( 3845): #0      StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:551:7)
E/flutter ( 3845): #1      MethodChannel.invokeMethod (package:flutter/src/services/platform_channel.dart:279:18)
E/flutter ( 3845): <asynchronous suspension>
E/flutter ( 3845): #2      Location.getLocation (package:location/location.dart:12:8)
timtraversy commented 6 years ago

That is an error thrown by the Android implementation of the library when it fails to fetch a location: https://github.com/Lyokone/flutterlocation/blob/5919fed5fb689823cdce9a837e8a9711b892a6af/android/src/main/java/com/lyokone/location/LocationPlugin.java#L246

So it really feels like this would be a permissions error. Did you this line to your AndroidManifest.xml?

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
mohlam12 commented 6 years ago

I do. And it does work fine when I kill/relaunch or reinstall the app.

It only stops working when the app resumes after a long break or on the emulator after a couple hot reloads

gimox commented 5 years ago

same error here! hangs on await _locationProvider.getLocation() only if i reject permission.

 _permission = await _locationProvider.hasPermission();

// on first run _permission = true, but i haven't confirmed yet the permission !!!
 if (_permission == false) {
     ....
  // on first run not enter here!!!!!!
 }

// hang here!!
 locationFirst = await _locationProvider.getLocation(); 
MustafaProgramer commented 5 years ago

same here, any solution?!

I do. And it does work fine when I kill/relaunch or reinstall the app.

It only stops working when the app resumes after a long break or on the emulator after a couple hot reloads

gimox commented 5 years ago

my solution is to use simple_permission plugin with location, now work very good.

I think we can consider to remove check permission from location plugin and let the user to use a more complete and update permission plugin

  Future<bool> checkPermission() async {
    bool hasPermission =
        await SimplePermissions.checkPermission(Permission.WhenInUseLocation);

    debugPrint(
        "*location_state_handler* permission for location: $hasPermission");

    if (hasPermission) {
      return true;
    }

    PermissionStatus permissionStatus =
        await SimplePermissions.requestPermission(Permission.WhenInUseLocation);

    debugPrint("permission request result is $permissionStatus");

    if (permissionStatus == PermissionStatus.authorized ||
        permissionStatus == PermissionStatus.restricted) {
      return true;
    }

    _setErrorLocation('permission denied');
    return false;
  }

  /// get position and observe or future changes
  Future<bool> getPosition([bool skipPermission = false]) async {
    if (skipPermission == false) {
      bool hasPermission = await checkPermission();

      if (hasPermission == false) {
        _setErrorLocation('permission denied');
        return false;
      }
    }

    /// get current position
    Location location = new Location();

    /// get current position, non blocking
    _getCurrentPosition(location);

    /// observe for future position
    _observePosition(location);

    return true;
  }
Lyokone commented 5 years ago

Hey ! I've modified the way permission is handled so it should be more reliable now ;)