Геолокация Flutter: geolocator и geocoding

Геолокация – это процесс определения текущего физического местоположения пользователя при взаимодействии с вашим приложением.

Flutter предлагает пакеты geolocator и geocoding, которые можно использовать для геолокации.

В этом мануале мы создадим простое тестовое приложение Flutter, которое использует пакеты geolocator и geocoding для определения местоположения пользователя.

Требования

  • Установка Flutter.
  • Установка Android Studio или Visual Studio Code.
  • Рекомендуется также установить плагины для вашего редактора кода:
    • Плагины Flutter и Dart для Android Studio.
    • Расширение Flutter для 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

Tags:

Добавить комментарий