简体   繁体   English

Flutter Geolocator 不适用于 Android,但可以在 iOS 上完美运行

[英]Flutter Geolocator not working on Android, but working perfectly on iOS

I've built an app using Flutter, for both iOS and Android platforms.我已经使用 Flutter 为 iOS 和 Android 平台构建了一个应用程序。 It uses the Geolocator package, version 7.7.0.它使用 Geolocator 包,版本 7.7.0。 The strange thing is, whilst it works on the iOS simulator and physical devices, it doesn't work at all on either the Android emulator, or physical devices.奇怪的是,虽然它适用于 iOS 模拟器和物理设备,但它在 Android 模拟器或物理设备上根本不起作用。 This is the geolocator-based asynchronous function I have created to check permissions and get the current position of the user, based off the guidance from pub.dev:这是我创建的基于地理定位器的异步函数,用于根据 pub.dev 的指导检查权限并获取用户的当前位置:

  _determineCurrentPositionStarting() async {
    bool serviceEnabled;
    LocationPermission permission;

    // Test if location services are enabled.
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      // Location services are not enabled don't continue
      // accessing the position and request users of the
      // App to enable the location services.
      return Future.error('Location services are disabled.');
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.denied) {
        // Permissions are denied, next time you could try
        // requesting permissions again (this is also where
        // Android's shouldShowRequestPermissionRationale
        // returned true. According to Android guidelines
        // your App should show an explanatory UI now.
        return Future.error('Location permissions are denied.');
      }
    }

    if (permission == LocationPermission.deniedForever) {
      // Permissions are denied forever, handle appropriately.
      return Future.error(
          'Location permissions are permanently denied, so we cannot request permissions.');
    }

    // When we reach here, permissions are granted and we can
    // continue accessing the position of the device.

    return await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.best,
      forceAndroidLocationManager: true,
    ).then((Position position) {
      setState(() {
        gcStartingLatitudeGEODEG.text = position.latitude.toStringAsFixed(6);
        gcStartingLongitudeGEODEG.text = position.longitude.toStringAsFixed(6);
      });
    }).catchError((e) {
      print(e);
    });
  }

In addition, the onPressed command that calls the above function, in a button, looks like this:此外,调用上述函数的 onPressed 命令,在一个按钮中,如下所示:

        onPressed: () async {
          _determineCurrentPositionStarting();
        },

On iOS it works fine, getting the user's location.在 iOS 上它工作正常,可以获取用户的位置。 It just doesn't work on Android.它只是不适用于Android。 The problem is, there's no error log produced for it at all, so there's no obvious target for me to work on.问题是,根本没有为它生成错误日志,所以没有明显的目标供我处理。 Everything appears to be working fine in the terminal.在终端中一切似乎都运行良好。 I've done a bit of trial and error, to see if I can work out at which stage the process is getting stuck.我已经做了一些试验和错误,看看我是否能弄清楚这个过程在哪个阶段卡住了。 This is what I have found:这是我发现的:

  1. The function is able to check if location services are enabled and shows a popup warning if it isn't.该功能能够检查位置服务是否已启用,如果未启用则显示弹出警告。
  2. The function is able to check for permissions and request it through a popup if it doesn't already have them (always, only while using the app, never etc.).该函数能够检查权限并在没有权限的情况下通过弹出窗口请求权限(总是,仅在使用应用程序时,从不等)。 If never is selected, a warning is generated, as expected.如果选择从不,则按预期生成警告。
  3. The function is able to give a warning if permissions are denied forever.如果永远拒绝权限,该功能能够发出警告。
  4. Nothing is returned at all when we reach return await Geolocator.getCurrentPosition...当我们到达 return await Geolocator.getCurrentPosition 时,什么都没有返回......

This makes me think that there is an issue with the android platform and the await Geolocator.getCurrentPosition() function.这让我觉得 android 平台和 await Geolocator.getCurrentPosition() 函数存在问题。

Since everything works fine on my iOS device and simulator, but it doesn't on Android, I'm thinking it has got to be something to do with the Android-specific settings.由于在我的 iOS 设备和模拟器上一切正常,但在 Android 上却没有,我认为这与特定于 Android 的设置有关。

Within my androidmanifest.xml file I have, as far as I can tell, the correct permissions noted:在我的 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" />

I am using gradle version 7.0.0 and in my build.gradle file (android > app > build.gradle) my SDK versions are:我正在使用 gradle 7.0.0 版,在我的 build.gradle 文件(android > app > build.gradle)中,我的 SDK 版本是:

  • compileSdkVersion: 31编译SDK版本:31
  • minSdkVersion: 23最小SDK版本:23
  • targetSdkVersion: 31目标SDK版本:31

If it helps, there are no errors with the Flutter Doctor:如果有帮助,则 Flutter Doctor 没有错误:

[✓] Flutter (Channel stable, 2.5.3, on macOS 11.6 20G165 darwin-x64, locale en-GB)
[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 2020.3)
[✓] Connected device (2 available)

Is there anything I am missing?有什么我想念的吗? Is there any reason you can see as to why it just isn't working on Android?有什么理由可以解释为什么它不能在 Android 上运行? Any help would be gratefully appreciated!任何帮助将不胜感激!

EDIT编辑

I've just tried it on an Android Emulator running Android 11.0, instead of 12.0 and it works fine.我刚刚在运行 Android 11.0 而不是 12.0 的 Android 模拟器上尝试过它,它运行良好。 That suggests to me it could be related to how the breaking changes in the package version 7.0.0 are interacting could be interacting with the Android 12.0 emulator.这向我表明,这可能与包版本 7.0.0 中的重大更改交互方式可能与 Android 12.0 模拟器交互有关。 I'll look through them and if I can work it out, I'll post it as an answer to my query.我会仔细查看它们,如果我能解决,我会将其发布为我的查询的答案。

Firstly, I modified the function used to get the coordinates, based on the breaking changes described by the plugin author for version 7.0.0, mainly related to the permissions section.首先,我根据插件作者描述的7.0.0版本的重大变化,修改了用于获取坐标的函数,主要涉及权限部分。

  _determineCurrentPositionStarting() async {
    bool serviceEnabled;
    LocationPermission permission;

    // Test if location services are enabled.
    serviceEnabled = await Geolocator.isLocationServiceEnabled();
    if (!serviceEnabled) {
      // Location services are not enabled don't continue
      // accessing the position and request users of the
      // App to enable the location services.
      return;
    }

    permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
      if (permission == LocationPermission.deniedForever) {
        // Permissions are denied forever, handle appropriately.
        return;
      }
    }

    if (permission == LocationPermission.denied) {
      // Permissions are denied, next time you could try
      // requesting permissions again (this is also where
      // Android's shouldShowRequestPermissionRationale
      // returned true. According to Android guidelines
      // your App should show an explanatory UI now.
      return;
    }

    // When we reach here, permissions are granted and we can
    // continue accessing the position of the device.

    return await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.bestForNavigation,
      forceAndroidLocationManager: true,
      timeLimit: null,
    ).then((Position position) {
      setState(() {
        gcStartingLatitudeGEODEG.text = position.latitude.toStringAsFixed(6);
        gcStartingLongitudeGEODEG.text = position.longitude.toStringAsFixed(6);
      });
    }).catchError((e) {
      print(e);
    });
  }

Then, I decided to do a timing test and it seems that basically, even for the Android devices on which I originally thought it didn't work, it actually did, just with a long delay.然后,我决定做一个计时测试,看起来基本上,即使对于我最初认为它不起作用的 Android 设备,它实际上起作用了,只是延迟了很长时间。

For example, on my Android physical device, Samsung Galaxy A21s, it took anywhere from 48 seconds to a couple of minutes, but it did return coordinates.例如,在我的 Android 物理设备 Samsung Galaxy A21s 上,它花费了 48 秒到几分钟的时间,但它确实返回了坐标。

Therefore, I can only assume that it does work on all platforms and it is entirely dependent on the type of device, the quality of the GPS module within it and the GPS connectivity at the user's location, as to the speed of the result.因此,我只能假设它确实适用于所有平台,并且它完全取决于设备类型、其中 GPS 模块的质量以及用户所在位置的 GPS 连接,以及结果的速度。

That's why it hadn't resulted in an error log.这就是为什么它没有导致错误日志。 It was working, just taking a while.它正在工作,只是需要一段时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Flutter 地理定位器 5.0.1 无法正常工作 - Flutter Geolocator 5.0.1 not working properly 将我的 flutter 应用程序嵌入到 android 应用程序键盘重叠文本字段后,但 iOS 键盘工作正常 - after embed my flutter app into android app keyboard overlapping text field but iOS keyboard working perfectly 地理定位器 6.0.0+1 distanceBetween() 在 flutter 中不起作用 - geolocator 6.0.0+1 distanceBetween() not working in flutter Alert.alert 在 React native iOS 中不起作用,但在 Android 中完全正常 - Alert.alert not working in React native iOS, but perfectly fine in Android 使用WebView在Android中滚动完美运行 - Scrolling in Android with WebView Working Perfectly Flutter App 在 Android 上运行流畅,但在 iOS 上无法运行 - Flutter App running smooth on Android but not working on iOS 在 Android(仅在 iOS 上)上无法使用 Google 登录 - Flutter - Sign in with Google is not working on Android (only on iOS) - Flutter 在 iOS 上使用时,flutter geolocator 返回 null - flutter geolocator returns null when used on iOS Android应用程式在Phablets上崩溃但在手机上可完美运行 - Android App Crashing On Phablets But Working Perfectly On Phones 使用处理程序进行对话框无法在android中完美运行 - Progess Dialog not working perfectly in android using handler
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM