【问题标题】:GeoLocation package doesn't work in flutter while running on a real device在真实设备上运行时,GeoLocation 包无法正常工作
【发布时间】:2021-08-18 19:57:12
【问题描述】:
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:geolocator/geolocator.dart';
//import 'package:provider/provider.dart';

class Map extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _MapState();
}

class _MapState extends State<Map> {
  Completer<GoogleMapController> _controllerGoogleMap = Completer();
  GoogleMapController newGoogleMapController;

  Position currentPosition;
  var geoLocator = Geolocator();

  void locatePosition() async {
    Position position = await Geolocator.getCurrentPosition(
        desiredAccuracy: LocationAccuracy.best);
    currentPosition = position;

    LatLng latLngPos = LatLng(position.latitude, position.longitude);

    CameraPosition cameraPosition =
        CameraPosition(target: latLngPos, zoom: 15.0);

    newGoogleMapController
        .animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
  }

  static final CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(37.42796133580664, -122.085749655962),
    zoom: 14.4746,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: GoogleMap(
          mapType: MapType.normal,
          myLocationButtonEnabled: true,
          initialCameraPosition: _kGooglePlex,
          myLocationEnabled: true,
          zoomGesturesEnabled: true,
          zoomControlsEnabled: true,
          onMapCreated: (GoogleMapController controller) {
            _controllerGoogleMap.complete(controller);
            newGoogleMapController = controller;
            locatePosition();
          },
        ),
      ),
    );
  }
}

调试终端下

Launching lib\main.dart on vivo 1906 in debug mode... 
lib\main.dart:1 √ Built build\app\outputs\flutter-apk\app-debug.apk. I/flutter ( 9154):
Observatory listening on ************************************ I/flutter ( 9613): 
Observatory listening on ************************************ E/flutter ( 9613): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception:
User denied permissions to access the device's location. E/flutter ( 9613): 
#0 MethodChannelGeolocator._handlePlatformException package:geolocator_platform_interface/…/implementations/method_channel_geolocator.dart:199 
E/flutter ( 9613): #1 MethodChannelGeolocator.getCurrentPosition package:geolocator_platform_interface/…/implementations/method_channel_geolocator.dart:
118 E/flutter ( 9613): <asynchronous suspension> E/flutter ( 9613): #2 _MapState.locatePosition package:donation_yoga/screens/maps.dart:
21 E/flutter ( 9613): <asynchronous suspension> E/flutter ( 9613):

我从未拒绝过我的许可, 此外,即使我已启用它以获取当前位置,地图也不会显示我的位置按钮, 只显示放大和缩小按钮以及地图。

使用 Flutter 2.2.1 google_maps_flutter:^2.0.6 地理定位器:^7.0.3

PS:我尝试过定位包,但是它会抛出很多错误,例如找不到 location_web 等,

【问题讨论】:

  • 您是否按照安装说明并在您的 AndroidManifest.xml 文件中添加了权限声明?你能包括你的android/app/src/main/AndroidManifest.xml吗?
  • .....

标签: flutter google-maps


【解决方案1】:

对于所有用户获取“未处理的异常:用户拒绝访问设备位置的权限”

pubspec.yaml

在依赖项下添加geolocator: ^8.0.1

dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  geolocator: ^8.0.1

AndroidManifest.xml

您将看到以下内容:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.get_weather">

在上述代码下添加以下内容:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.hardware.location.gps" />

main.dart

import 'package:flutter/material.dart';
import 'package:get_weather/screens/loading_screen.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: LoadingScreen(),
    );
  }
}

loading_screen.dart

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

class LoadingScreen extends StatefulWidget {
  @override
  _LoadingScreenState createState() => _LoadingScreenState();
}

class _LoadingScreenState extends State<LoadingScreen> {
  void getLocation() 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, we cannot request permissions.');
    }

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

    print(position);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            //Get the current location
            getLocation();
          },
          child: Text('Get Location'),
        ),
      ),
    );
  }
}

loading_screen.dart 中的代码将帮助您解决“用户拒绝权限”问题。

【讨论】:

    【解决方案2】:

    尝试将 forceLocationManager 子句添加到您的函数中:

      void locatePosition() async {
    
      Position position = await Geolocator.getLastKnownPosition({ bool forceAndroidLocationManager = true}
        );
      currentPosition = position;
    
    
      LatLng latLngPos = LatLng(position.latitude, position.longitude);
    
      CameraPosition cameraPosition =
        CameraPosition(target: latLngPos, zoom: 15.0);
    
      newGoogleMapController
        .animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
      }
    

    还要检查您的 android manifest 以了解位置:

    <manifest ... >
     <!-- To request foreground location access, declare one of these 
     permissions. -->
      <uses-permission 
      android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" 
     />
     </manifest>
    

    还要保持您想要的低准确度,准确度充其量会在设备上造成隐私混乱,因此需要额外的步骤

    【讨论】:

    • ``` 不能将“bool”类型的值分配给“Geolocator”类型的变量。尝试更改变量的类型,或将右侧类型转换为“Geolocator”。dartinvalid_assignment 未为“Geolocator”类型定义设置器“forceAndroidLocationManager”。尝试导入定义“forceAndroidLocationManager”的库,将名称更正为现有设置器的名称,或定义名为“forceAndroidLocationManager”的设置器或字段。dartundefined_setter ```
    • 在更改代码之前检查您的 android 清单,然后尝试新方法
    • 哪种新方法,我的清单还可以吗?具有所需的所有权限
    • 是的,谢谢,不过有一个问题,根据您的说法,哪个软件包更适合定位和地图,定位还是地理位置?
    • 如果你问我没有,哪个效果更好就是正确的。它们都适用于相同的代码并且有不同的用途。如果您的地理定位器似乎适合您,请使用它你喜欢的方式。
    猜你喜欢
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多