Геолокация – это процесс определения текущего физического местоположения пользователя при взаимодействии с вашим приложением.
Flutter предлагает пакеты geolocator и geocoding, которые можно использовать для геолокации.
В этом мануале мы создадим простое тестовое приложение Flutter, которое использует пакеты geolocator и geocoding для определения местоположения пользователя.
Требования
- Установка Flutter.
- Установка Android Studio или Visual Studio Code.
- Рекомендуется также установить плагины для вашего редактора кода:
Это руководство было протестировано на версиях Flutter v1.22.2, Android SDK v30.0.2 и Android Studio v4.1. Код поддерживает версии geolocator 6+ и geocoding 1+.
1: Создание тестового приложения
Подготовив среду для работы Flutter, вы можете запустить следующую команду, чтобы создать новое приложение:
flutter create flutter_geolocator_example
Перейдите в каталог нового проекта:
cd flutter_geolocator_example
Команда flutter create создала простое демо-приложение, которое будет отображать количество нажатий кнопки.
Откройте файл pubspec.yaml в редакторе кода и добавьте в него следующие плагины:
dependencies: flutter: sdk: flutter geocoding: ^1.0.5 geolocator: ^6.1.1
Примечание: Убедитесь, что ваш проект использует AndroidX. Если вы создали приложение с помощью Flutter 1.7+, AndroidX будет применяться по умолчанию. В противном случае следуйте этому руководству.
Затем нам нужно настроить привилегии как для Android, так и для iOS, отредактировав файлы android/app/src/main/AndroidManifest.xml и ios/Runner/Info.plist.
Привилегии iOS
Откройте файл Info.plist в редакторе кода и добавьте директивы NSLocationWhenInUseUsageDescription, NSLocationAlwaysUsageDescription и NSLocationAlwaysAndWhenInUseUsageDescription.
Вы можете отредактировать их значения на свое усмотрение:
<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>
Если вы не собираетесь поддерживать приложения iOS старше iOS 10 и не хотите получать геолокацию пользователя, когда приложение не используется, вы можете пропустить директивы NSLocationAlwaysUsageDescription и NSLocationAlwaysAndWhenInUseUsageDescription.
Привилегии Android
Откройте AndroidManifest.xml в редакторе кода и добавьте одно из следующих значений.
ACCESS_FINE_LOCATION: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Или ACCESS_COARSE_LOCATION:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
ACCESS_FINE_LOCATION отслеживает наиболее точную геолокацию, а ACCESS_COARSE_LOCATION – с точностью примерно до квартала.
После этого мы можем создать виджет, который будет запускать и отображать текущее местоположение пользователя.
2: Создание кнопки
Теперь нам нужно обновить файл main.dart и создать новый файл home_page.dart.
Откройте main.dart в редакторе кода, импортируйте home_page.dart и измените значение home с MyHomePage на 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,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomePage(),
);
}
}
После этого создайте файл home_page.dart и поместите в него такой код:
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
},
),
],
),
),
);
}
}
Это создаст кнопку с надписью «Get location».
3: Получение широты и долготы
Следующим нашим шагом будет добавление функции геолокации.
Вы можете сделать это, создав экземпляр Geolocator и вызвав getCurrentPosition. В результате приложение спросит пользователей, хотят ли они использовать функцию Location, и если да, оно извлечет текущее местоположение в качестве значения Position.
Снова зайдите в home_page.dart и добавьте _getCurrentLocation():
import 'package:flutter/material.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() {
Geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true)
.then((Position position) {
setState(() {
_currentPosition = position;
});
}).catchError((e) {
print(e);
});
}
}
Скомпилируйте код и запустите его в эмуляторе.
Когда вы начнете взаимодействовать с кнопкой Get location, вы можете сначала увидеть запрос на доступ. Как только вы разрешите доступ к своему местоположению, на экране появятся широта и долгота вашего текущего местоположения.
4: Преобразование широты и долготы в удобочитаемый адрес
Следующим нашим шагом будет преобразование координат в адрес, который будет показывать наше приложение.
Передача координат latitude и longitude в placemarkFromCoordinates вернет метку, Placemark. Эта метка содержит различнуюинформацию: населенный пункт, почтовый индекс и страну (locality, postalCode, country).
Снова откройте home_page.dart и добавьте в него _getAddressFromLatLng_():
import 'package:flutter/material.dart';
import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
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 (_currentAddress != null) Text(
_currentAddress
),
FlatButton(
child: Text("Get location"),
onPressed: () {
_getCurrentLocation();
},
),
],
),
),
);
}
_getCurrentLocation() {
Geolocator
.getCurrentPosition(desiredAccuracy: LocationAccuracy.best, forceAndroidLocationManager: true)
.then((Position position) {
setState(() {
_currentPosition = position;
_getAddressFromLatLng();
});
}).catchError((e) {
print(e);
});
}
_getAddressFromLatLng() async {
try {
List<Placemark> placemarks = await placemarkFromCoordinates(
_currentPosition.latitude,
_currentPosition.longitude
);
Placemark place = placemarks[0];
setState(() {
_currentAddress = "${place.locality}, ${place.postalCode}, ${place.country}";
});
} catch (e) {
print(e);
}
}
}
Скомпилируйте свой код и запустите его в эмуляторе.
Попробуйте взаимодействовать с кнопкой Get location. Сначала вы можете увидеть запрос на доступ. Когда вы разрешите доступ к своему местоположению, на экране отобразится название населенного пункта, почтовый индекс и страна, в которой вы находитесь в данный момент.
Заключение
В этом руководстве вы узнали, как использовать пакеты geolocator и geocoding в приложении Flutter.
Читайте также: Настройка Firebase для приложений iOS и Android через Flutter
