Flutter地理位置获取插件location的使用

发布于 1周前 作者 sinazl 来自 Flutter

Flutter地理位置获取插件location的使用

简介

location插件用于在Flutter应用中获取设备的地理位置信息。它支持Android和iOS平台,并提供了当位置变化时的回调功能。此外,该插件还支持后台模式下的位置获取。

开始使用

添加依赖

首先,在pubspec.yaml文件中添加location依赖:

dependencies:
  location: ^5.0.0

平台配置

Android

为了在Android上使用后台模式的位置服务,需要在AndroidManifest.xml中添加以下权限:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>

同时提醒用户在设置中将位置权限设置为“始终允许”。

iOS

Info.plist中添加必要的权限描述:

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to provide better service.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need your location even when you're not using the app.</string>

如果需要接收后台位置更新,还需添加:

<key>UIBackgroundModes</key>
<array>
  <string>location</string>
</array>

Web 和 macOS

  • Web: 插件开箱即用,无需额外配置。
  • macOS: 需要在Xcode中启用沙盒并选择“Location”选项,同时在Info.plist中添加相应的权限描述。

使用方法

导入包:

import 'package:location/location.dart';

获取单次位置

Location location = Location();

bool _serviceEnabled;
PermissionStatus _permissionGranted;
LocationData _locationData;

_serviceEnabled = await location.serviceEnabled();
if (!_serviceEnabled) {
  _serviceEnabled = await location.requestService();
  if (!_serviceEnabled) {
    return;
  }
}

_permissionGranted = await location.hasPermission();
if (_permissionGranted == PermissionStatus.denied) {
  _permissionGranted = await location.requestPermission();
  if (_permissionGranted != PermissionStatus.granted) {
    return;
  }
}

_locationData = await location.getLocation();
print('纬度: ${_locationData.latitude}, 经度: ${_locationData.longitude}');

监听位置变化

location.onLocationChanged.listen((LocationData currentLocation) {
  print('当前位置更新 - 纬度: ${currentLocation.latitude}, 经度: ${currentLocation.longitude}');
});

启用后台模式

await location.enableBackgroundMode(enable: true);

示例代码

下面是一个完整的示例应用程序,展示了如何集成和使用location插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Location Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Location Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final Location location = Location();
  bool _serviceEnabled = false;
  PermissionStatus? _permissionGranted;
  LocationData? _locationData;

  Future<void> _getLocation() async {
    _serviceEnabled = await location.serviceEnabled();
    if (!_serviceEnabled) {
      _serviceEnabled = await location.requestService();
      if (!_serviceEnabled) {
        return;
      }
    }

    _permissionGranted = await location.hasPermission();
    if (_permissionGranted == PermissionStatus.denied) {
      _permissionGranted = await location.requestPermission();
      if (_permissionGranted != PermissionStatus.granted) {
        return;
      }
    }

    _locationData = await location.getLocation();
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    _getLocation();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('位置信息:'),
            Text(
              _locationData == null
                  ? '正在获取...'
                  : '纬度: ${_locationData!.latitude}, 经度: ${_locationData!.longitude}',
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getLocation,
              child: Text('刷新位置'),
            ),
          ],
        ),
      ),
    );
  }
}

以上代码创建了一个简单的Flutter应用,展示了如何请求位置权限、检查服务状态以及获取当前位置。通过点击按钮可以刷新位置信息。


更多关于Flutter地理位置获取插件location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter地理位置获取插件location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter应用中使用location插件来获取地理位置的示例代码。这个示例将展示如何请求位置权限、获取当前位置以及处理可能的错误。

首先,确保你已经在pubspec.yaml文件中添加了location插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  location: ^4.3.0  # 请检查最新版本号

然后,运行flutter pub get来安装依赖。

接下来,是主要的Dart代码。这里是一个完整的示例,包括请求权限、获取位置以及显示位置信息。

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LocationScreen(),
    );
  }
}

class LocationScreen extends StatefulWidget {
  @override
  _LocationScreenState createState() => _LocationScreenState();
}

class _LocationScreenState extends State<LocationScreen> {
  Location _location = Location();
  bool _serviceEnabled;
  LocationPermission _permission;
  LocationData? _locationData;

  @override
  void initState() {
    super.initState();
    _getCurrentLocation();
  }

  Future<void> _updateLocation() async {
    bool serviceStatus = await _location.serviceEnabled();
    if (!serviceStatus) {
      return Future.error('Location services are disabled.');
    }

    _permission = await _location.requestPermission();
    if (_permission == LocationPermission.denied) {
      return Future.error('Location permissions are denied');
    }

    if (_permission == LocationPermission.deniedForever) {
      return Future.error(
          'Location permissions are permanently denied, we cannot request permissions.');
    }

    _serviceEnabled = serviceStatus;

    _locationData = await _location.getLocation();
  }

  Future<void> _getCurrentLocation() async {
    String errorMessage = 'Unknown error occurred!';

    try {
      await _updateLocation();
    } catch (e) {
      print(e);
      errorMessage = e.toString();
    }

    if (_locationData == null) {
      errorMessage = 'Failed to get location.';
    }

    setState(() {
      _locationData = _locationData ?? LocationData.fromMap({});
    });

    // Optionally, you can show a snackbar or dialog with the errorMessage
    // ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage)));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Location Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Location:',
              style: TextStyle(fontSize: 20),
            ),
            if (_locationData != null)
              Text(
                'Latitude: ${_locationData!.latitude}, Longitude: ${_locationData!.longitude}',
                style: TextStyle(fontSize: 18),
              ),
            else
              Text(
                'Loading...',
                style: TextStyle(fontSize: 18, color: Colors.grey),
              ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _getCurrentLocation,
        tooltip: 'Get Location',
        child: Icon(Icons.location_on),
      ),
    );
  }
}

代码解释

  1. 依赖导入

    • import 'package:flutter/material.dart'; 导入Flutter的核心Material组件。
    • import 'package:location/location.dart'; 导入location插件。
  2. 主应用

    • MyApp 类是一个简单的无状态组件,它只包含一个LocationScreen
  3. LocationScreen

    • LocationScreen 是一个有状态组件,它包含了位置服务、权限检查和位置数据。
    • initState方法中,调用_getCurrentLocation方法来初始化位置数据。
    • _updateLocation 方法检查位置服务是否启用,请求位置权限,然后尝试获取当前位置。
    • _getCurrentLocation 方法处理所有可能的错误,并更新状态以反映最新的位置数据。
  4. UI

    • 使用ScaffoldAppBarColumn等组件来构建用户界面。
    • 显示当前的纬度和经度,如果位置数据未加载,则显示“Loading…”。
    • 使用FloatingActionButton来手动刷新位置数据。

这个示例提供了一个基础框架,你可以在此基础上添加更多功能,比如处理精度和准确度、显示地图、记录位置历史等。

回到顶部