如何使用 Flutter 中的 Geolocator 插件获取用户位置

简介

地理位置是在用户与您的应用程序交互时识别用户当前物理位置的过程。

有一个可用于地理定位的geolocator和一个用于颤动的Geocoding

在本文中,您将创建一个使用geolocatorgecoding包来确定用户位置的示例Flight应用程序。

前提条件

要完成本教程,您需要:

本教程使用Ffltter v1.22.2、Android SDK v30.0.2和Android Studio v4.1进行了验证。本教程中的代码已更新,支持geolocator6+和gecoding1+。

第一步-设置项目

将环境设置为颤动后,可以运行以下命令来创建新应用程序:

1flutter create flutter_geolocator_example

导航到新项目目录:

1cd flutter_geolocator_example

使用fltter create将生成一个演示应用程序,其中将显示按钮被点击的次数。

在代码编辑器中打开pubspec.yaml,添加以下插件:

1[label pubspec.yaml]
2dependencies:
3  flutter:
4    sdk: flutter
5
6  geocoding: ^1.0.5
7  geolocator: ^6.1.1

<$>[备注] 注意: 您需要确保您的Android项目使用的是Android。如果您在版本1.7之后创建了颤振应用程序,则默认情况下会出现此情况。如果没有,请遵循以下指南:androidX Migration. <$>

然后,您需要通过编辑ios/Runner/Info.plistandroid/app/src/main/androidManifest.xml为Android和iOS添加权限。

iOS权限

在代码编辑器中打开Info.plist,添加NSLocationWhenInUseUsageDescriptionNSLocationAlway sUsageDescriptionNSLocationAlwaysAndWhenInUseUsageDescription

从iOS和Info.plist开始,添加以下键值对,并根据自己的喜好进行定制:

1[label ios/Runner/Info.plist]
2<key>NSLocationWhenInUseUsageDescription</key>
3<string>This app needs access to location when open.</string>
4
5<key>NSLocationAlwaysUsageDescription</key>
6<string>This app needs access to location when in the background.</string>
7
8<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
9<string>This app needs access to location when open and in the background.</string>

如果您不打算支持早于iOS 10的iOS应用程序,并且不想在不使用该应用程序时获取用户位置,则可以放弃添加NSLocationAlways UsageDescriptionNSLocationAlwaysAndWhenInUseUsageDescription.

Android权限

在代码编辑器中打开androidManifest.xml,然后添加以下内容之一。

加入时间:清华2007年01月25日下午3:33

1[label android/app/src/main/AndroidManifest.xml]
2<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

ACCESS_COARSE_LOCATION

1[label android/app/src/main/AndroidManifest.xml]
2<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

ACCESS_FINE_LOCATION是最精确的,而ACCESS_COARSE_LOCATION给出的结果大约相当于一个城市街区。

完成此设置后,您可以创建将触发并显示用户当前位置的小部件。

Step 2 -搭建项目

接下来,您需要更新main.dart文件并创建一个新的home_page.dart文件。

在代码编辑器中打开main.dart,导入home_page.dart并将homeMyHomePage更改为HomePage

 1[label lib/main.dart]
 2import 'package:flutter/material.dart';
 3import 'home_page.dart';
 4
 5void main() {
 6  runApp(MyApp());
 7}
 8
 9class MyApp extends StatelessWidget {
10  @override
11  Widget build(BuildContext context) {
12    return MaterialApp(
13      title: 'Flutter Demo',
14      theme: ThemeData(
15        primarySwatch: Colors.blue,
16        visualDensity: VisualDensity.adaptivePlatformDensity,
17      ),
18      home: HomePage(),
19    );
20  }
21}

然后,创建新的home_page.dart文件,并添加以下代码:

 1[label lib/home_page.dart]
 2import 'package:flutter/material.dart';
 3
 4class HomePage extends StatefulWidget {
 5  @override
 6  _HomePageState createState() => _HomePageState();
 7}
 8
 9class _HomePageState extends State<HomePage> {
10  @override
11  Widget build(BuildContext context) {
12    return Scaffold(
13      appBar: AppBar(
14        title: Text("Location"),
15      ),
16      body: Center(
17        child: Column(
18          mainAxisAlignment: MainAxisAlignment.center,
19          children: <Widget>[
20            FlatButton(
21              child: Text("Get location"),
22              onPressed: () {
23                // Get location here
24              },
25            ),
26          ],
27        ),
28      ),
29    );
30  }
31}

这将创建一个带有消息Get Location的按钮。

第三步-获取纬度和经度

下一步是添加地理定位功能。

你可以通过创建一个Geolocator的实例并调用getCurrentPosition来实现。这应该询问用户是否有兴趣使用位置功能,如果有兴趣,则将当前位置作为位置

重新访问home_page.dart,添加_getCurrentLocation()

 1[label lib/home_page.dart]
 2import 'package:flutter/material.dart';
 3import 'package:geolocator/geolocator.dart';
 4
 5class HomePage extends StatefulWidget {
 6  @override
 7  _HomePageState createState() => _HomePageState();
 8}
 9
10class _HomePageState extends State<HomePage> {
11  Position _currentPosition;
12
13  @override
14  Widget build(BuildContext context) {
15    return Scaffold(
16      appBar: AppBar(
17        title: Text("Location"),
18      ),
19      body: Center(
20        child: Column(
21          mainAxisAlignment: MainAxisAlignment.center,
22          children: <Widget>[
23            if (_currentPosition != null) Text(
24              "LAT: ${_currentPosition.latitude}, LNG: ${_currentPosition.longitude}"
25            ),
26            FlatButton(
27              child: Text("Get location"),
28              onPressed: () {
29                _getCurrentLocation();
30              },
31            ),
32          ],
33        ),
34      ),
35    );
36  }
37
38  _getCurrentLocation() {
39    Geolocator
40      .getCurrentPosition(desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true)
41      .then((Position position) {
42        setState(() {
43          _currentPosition = position;
44        });
45      }).catchError((e) {
46        print(e);
47      });
48  }
49}

编译你的代码并让它在模拟器中运行:

在仿真器中运行的应用程序的两个屏幕截图。第一个屏幕截图描述了允许应用程序访问位置的提示。第二个屏幕截图描绘了user.位置的纬度和经度

当你与获取位置 按钮互动时,你最初可能会看到一个提示,要求访问你的应用程序。一旦您允许访问您的位置,您当前位置的纬度经度就会出现在屏幕上。

第四步-将纬度和经度转换为可读地址

下一步是转换坐标以显示地址。

atitudeLongitude坐标传递给PlacemarkFromOrganates将返回一个PlacemarkPlacemark包含LocalitypostalCodeCountry等信息。

重新访问home_page.dart,添加_getAddressFromLatLng_()

 1[label lib/home_page.dart]
 2import 'package:flutter/material.dart';
 3import 'package:geocoding/geocoding.dart';
 4import 'package:geolocator/geolocator.dart';
 5
 6class HomePage extends StatefulWidget {
 7  @override
 8  _HomePageState createState() => _HomePageState();
 9}
10
11class _HomePageState extends State<HomePage> {
12  Position _currentPosition;
13  String _currentAddress;
14
15  @override
16  Widget build(BuildContext context) {
17    return Scaffold(
18      appBar: AppBar(
19        title: Text("Location"),
20      ),
21      body: Center(
22        child: Column(
23          mainAxisAlignment: MainAxisAlignment.center,
24          children: <Widget>[
25            if (_currentAddress != null) Text(
26              _currentAddress
27            ),
28            FlatButton(
29              child: Text("Get location"),
30              onPressed: () {
31                _getCurrentLocation();
32              },
33            ),
34          ],
35        ),
36      ),
37    );
38  }
39
40  _getCurrentLocation() {
41    Geolocator
42      .getCurrentPosition(desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true)
43      .then((Position position) {
44        setState(() {
45          _currentPosition = position;
46          _getAddressFromLatLng();
47        });
48      }).catchError((e) {
49        print(e);
50      });
51  }
52
53  _getAddressFromLatLng() async {
54    try {
55      List<Placemark> placemarks = await placemarkFromCoordinates(
56        _currentPosition.latitude,
57        _currentPosition.longitude
58      );
59
60      Placemark place = placemarks[0];
61
62      setState(() {
63        _currentAddress = "${place.locality}, ${place.postalCode}, ${place.country}";
64      });
65    } catch (e) {
66      print(e);
67    }
68  }
69}

编译代码并让其在模拟器中运行:

显示在模拟器中运行的应用程序的屏幕截图,地址为San Francisco,94108,United States。

当你与获取位置 按钮互动时,你最初可能会看到一个提示,要求访问你的应用程序。一旦您允许访问您的位置,您的LocalitypostalCodeCounty将显示在屏幕上。

总结

在本教程中,您在颤动应用程序中使用了geolocatorgecoding包。

如果您想了解更多有关Ffltter的知识,请查看我们的Ffltter主题页面以获取练习和编程项目。

Published At
Categories with 技术
comments powered by Disqus