flutter获取地理位置
Ever wanted to get a user’s location within your Flutter application? We’re going to be building an application that does exactly that by taking advantage of the Geolocator
plugin.
是否曾经想在Flutter应用程序中获取用户的位置? 我们将要利用Geolocator
插件来构建一个可以做到这一点的应用程序。
创建一个新的Flutter项目 (Creating a new Flutter project)
As always, we’ll start off by setting up a new project and adding the plugin:
与往常一样,我们将从建立一个新项目并添加插件开始:
# New Flutter project
$ flutter create my_location_project
# Open this up inside of VS Code
$ cd my_location_project && code .
添加Geolocator插件 (Adding the Geolocator plugin)
Head over to your pubspec.yaml
and add the following plugin:
转到您的pubspec.yaml
并添加以下插件:
dependencies:
flutter:
sdk: flutter
geolocator: ^5.1.3
Note: You’ll need to make sure that your Android project uses AndroidX for this. If you’ve created a Flutter application after version 1.7, this comes by default, if not, follow this guide: AndroidX Migration.
注意:您需要确保您的Android项目为此使用AndroidX。 如果您是在1.7版之后创建的Flutter应用程序,则默认情况下会出现此应用程序;否则,请遵循以下指南: AndroidX Migration 。
We’ll then need to add permissions to both Android and iOS by editing ios/Runner/Info.plist
and android/app/src/main/AndroidManifest.xml
.
然后,我们需要通过编辑ios/Runner/Info.plist
和android/app/src/main/AndroidManifest.xml
向Android和iOS添加权限。
iOS权限 (iOS Permissions)
Starting with iOS and the Info.plist
, add the following key/value pairs and customize them to your liking:
从iOS和Info.plist
,添加以下键/值对并根据自己的喜好自定义它们:
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location when open and in the background.</string>
If you don’t intend to support iOS applications older than iOS 10 and you don’t want to get user location when the application isn’t in use, you can forego the addition of NSLocationAlwaysUsageDescription
and NSLocationAlwaysAndWhenInUseUsageDescription
.
如果你不打算支持iOS应用程序的iOS比10 年长 ,你不希望得到用户的位置,当应用程序不在使用中,你可以加入NSLocationAlwaysUsageDescription
和NSLocationAlwaysAndWhenInUseUsageDescription
。
Android权限 (Android Permissions)
For android, head on over to your AndroidManifest.xml
and add either of these permissions:
对于android,请转到您的AndroidManifest.xml
并添加以下任一权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
What’s the difference between these two? ACCESS_FINE_LOCATION
is the most precise, whereas ACCESS_COARSE_LOCATION
gives results equal to about a city block.
两者有什么区别? ACCESS_FINE_LOCATION
最精确,而ACCESS_COARSE_LOCATION
给出的结果约等于一个城市街区。
We’re now ready to get started!
现在就可以开始了!
脚手架我们的项目 (Scaffolding our Project)
We’ll update our main.dart
file to contain our new HomePage
widget found within home_page.dart
:
我们将更新main.dart
文件,以包含在home_page.dart
找到的新HomePage
小部件:
import 'package:flutter/material.dart';
import 'home_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
Our HomePage
widget will look something like this:
我们的HomePage
小部件将如下所示:
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Location"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FlatButton(
child: Text("Get location"),
onPressed: () {
// Get location here
},
),
],
),
),
);
}
}
获取当前位置 (Getting the Current Location)
Now that we’ve established the basics for our project, let’s go ahead and update our HomePage
widget to get the current location of a user.
现在,我们已经为项目建立了基础,让我们继续更新HomePage
小部件,以获取用户的当前位置。
We can do that by creating an instance of Geolocator
and calling getCurrentPosition
. This should ask the user whether they’re interested in using the Location feature, and if so, get the current location as a Position
.
我们可以通过创建Geolocator
实例并调用getCurrentPosition
。 这应该询问用户他们是否对使用“位置”功能感兴趣,如果是,则将当前位置作为Position
。
Here’s how it looks:
外观如下:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:geolocator/geolocator.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
Position _currentPosition;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Location"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (_currentPosition != null)
Text(
"LAT: ${_currentPosition.latitude}, LNG: ${_currentPosition.longitude}"),
FlatButton(
child: Text("Get location"),
onPressed: () {
_getCurrentLocation();
},
),
],
),
),
);
}
_getCurrentLocation() {
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
}
We should now be able to see the latitude
and longitude
on screen:
现在,我们应该可以在屏幕上看到latitude
和longitude
:
将此转换为地址 (Converting this Into an Address)
We don’t have to stop there though! We can get a Placemark
which is essentially an approximation of the user’s current location from the latitude
and longitude
. Let’s see this in action:
我们不必在那里停下来! 我们可以得到一个地Placemark
,它实际上是从latitude
和longitude
得出的用户当前位置的近似值。 让我们来看看实际情况:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:geolocator/geolocator.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final Geolocator geolocator = Geolocator()..forceAndroidLocationManager;
Position _currentPosition;
String _currentAddress;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Location"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (_currentPosition != null) Text(_currentAddress),
FlatButton(
child: Text("Get location"),
onPressed: () {
_getCurrentLocation();
},
),
],
),
),
);
}
_getCurrentLocation() {
geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best)
.then((Position position) {
setState(() {
_currentPosition = position;
});
_getAddressFromLatLng();
}).catchError((e) {
print(e);
});
}
_getAddressFromLatLng() async {
try {
List<Placemark> p = await geolocator.placemarkFromCoordinates(
_currentPosition.latitude, _currentPosition.longitude);
Placemark place = p[0];
setState(() {
_currentAddress =
"${place.locality}, ${place.postalCode}, ${place.country}";
});
} catch (e) {
print(e);
}
}
}
After getting the latitude
and longitude
, we’re now using _getAddressFromLatLng()
to convert this into an address and display it on screen.
得到latitude
和longitude
,我们现在使用_getAddressFromLatLng()
将其转换为地址并在屏幕上显示。
Here’s how it looks:
外观如下:
翻译自: https://www.digitalocean.com/community/tutorials/flutter-geolocator-plugin
flutter获取地理位置