Flutter后台定位插件background_location的使用

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

Flutter后台定位插件background_location的使用

background_location 是一个用于在后台获取位置更新的Flutter插件,支持Android和iOS(要求iOS 10.0+)。它在iOS上使用CoreLocation,在Android上使用FusedLocationProvider

Getting Started

1. 添加依赖到 pubspec.yaml

dependencies:
  background_location: ^0.13.0

2. 安装包

从命令行安装:

$ flutter packages get

或者使用编辑器自带的支持flutter packages get功能。

如何使用

导入包

import 'package:background_location/background_location.dart';

请求权限

你可以使用 permission_handler 来请求用户权限。

设置通知标题、消息和图标 (仅限Android)

BackgroundLocation.setAndroidNotification(
  title: "Notification title",
  message: "Notification message",
  icon: "@mipmap/ic_launcher",
);

设置定位间隔 (仅限Android)

BackgroundLocation.setAndroidConfiguration(1000);

启动定位服务

BackgroundLocation.stopLocationService(); // 确保之前启动的服务已停止
BackgroundLocation.startLocationService();

使用 distanceFilter

BackgroundLocation.startLocationService(distanceFilter: 10);

强制使用 LocationManager

BackgroundLocation.startLocationService(forceAndroidLocationManager: true);

获取位置更新

BackgroundLocation.getLocationUpdates((location) {
  print(location);
});

位置数据类属性:

double latitude;
double longitude;
double altitude;
double bearing;
double accuracy;
double speed;
double time;
bool isMock;

停止监听位置变化

BackgroundLocation.stopLocationService();

确保在 Android 和 iOS 应用中声明所有必要的权限。

info.plist (iOS)

<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>This app needs access to location.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location.</string>
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>location</string>
</array>

AndroidManifest.xml (Android)

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

示例代码

以下是一个完整的示例应用程序:

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String latitude = 'waiting...';
  String longitude = 'waiting...';
  String altitude = 'waiting...';
  String accuracy = 'waiting...';
  String bearing = 'waiting...';
  String speed = 'waiting...';
  String time = 'waiting...';
  bool? serviceRunning = null;

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Background Location Service'),
        ),
        body: Center(
          child: ListView(
            children: <Widget>[
              locationData('Latitude: ' + latitude),
              locationData('Longitude: ' + longitude),
              locationData('Altitude: ' + altitude),
              locationData('Accuracy: ' + accuracy),
              locationData('Bearing: ' + bearing),
              locationData('Speed: ' + speed),
              locationData('Time: ' + time),
              locationData('IsServiceRunning: ' + serviceRunning.toString()),
              ElevatedButton(
                  onPressed: () async {
                    await BackgroundLocation.setAndroidNotification(
                      title: 'Background service is running',
                      message: 'Background location in progress',
                      icon: '@mipmap/ic_launcher',
                    );
                    await BackgroundLocation.startLocationService(
                        distanceFilter: 20);
                    BackgroundLocation.getLocationUpdates((location) {
                      setState(() {
                        latitude = location.latitude.toString();
                        longitude = location.longitude.toString();
                        accuracy = location.accuracy.toString();
                        altitude = location.altitude.toString();
                        bearing = location.bearing.toString();
                        speed = location.speed.toString();
                        time = DateTime.fromMillisecondsSinceEpoch(
                                location.time!.toInt())
                            .toString();
                      });
                      print('''\n
                        Latitude:  $latitude
                        Longitude: $longitude
                        Altitude: $altitude
                        Accuracy: $accuracy
                        Bearing:  $bearing
                        Speed: $speed
                        Time: $time
                        IsServiceRunning: $serviceRunning
                      ''');
                    });
                  },
                  child: Text('Start Location Service')),
              ElevatedButton(
                  onPressed: () {
                    BackgroundLocation.stopLocationService();
                  },
                  child: Text('Stop Location Service')),
              ElevatedButton(
                  onPressed: () {
                    BackgroundLocation.isServiceRunning().then((value) {
                      setState(() {
                        serviceRunning = value;
                      });
                      print("Is Running: $value");
                    });
                  },
                  child: Text('Check service')),
              ElevatedButton(
                  onPressed: () {
                    getCurrentLocation();
                  },
                  child: Text('Get Current Location')),
            ],
          ),
        ),
      ),
    );
  }

  Widget locationData(String data) {
    return Text(
      data,
      style: TextStyle(
        fontWeight: FontWeight.bold,
        fontSize: 18,
      ),
      textAlign: TextAlign.center,
    );
  }

  void getCurrentLocation() {
    BackgroundLocation().getCurrentLocation().then((location) {
      print('This is current Location ' + location.toMap().toString());
    });
  }

  @override
  void dispose() {
    BackgroundLocation.stopLocationService();
    super.dispose();
  }
}

这个示例展示了如何使用 background_location 插件来获取后台位置更新,并在界面上显示这些位置信息。


更多关于Flutter后台定位插件background_location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter后台定位插件background_location的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于在Flutter中使用background_location插件来实现后台定位功能,以下是一个简单的代码示例,展示了如何配置和使用该插件。

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

dependencies:
  flutter:
    sdk: flutter
  background_location: ^x.y.z  # 替换为最新版本号

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

接下来,在你的Flutter项目中,你需要按照以下步骤进行配置和使用:

  1. 配置Android权限

android/app/src/main/AndroidManifest.xml中添加必要的权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <!-- 其他必要的权限 -->

    <application
        ... >
        <!-- 其他配置 -->
        <service
            android:name="com.lyokone.location.FlutterLocationService"
            android:foregroundServiceType="location" />
    </application>
</manifest>
  1. 配置iOS权限

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

<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs access to location when in the background.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to location when open.</string>
<key>UIBackgroundModes</key>
<array>
    <string>location</string>
</array>
  1. 在Dart代码中使用background_location插件
import 'package:flutter/material.dart';
import 'package:background_location/background_location.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  BackgroundLocation _backgroundLocation = BackgroundLocation();
  LocationData? _locationData;

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

  Future<void> initLocationService() async {
    // 检查并请求权限
    bool hasPermission = await _backgroundLocation.serviceEnabled();
    if (!hasPermission) {
      hasPermission = await _backgroundLocation.requestService();
      if (!hasPermission) {
        return;
      }
    }

    bool permissionGranted = await _backgroundLocation.permissionGranted();
    if (!permissionGranted) {
      permissionGranted = await _backgroundLocation.requestPermission();
      if (!permissionGranted) {
        return;
      }
    }

    // 开始后台定位
    await _backgroundLocation.setLocationUpdatesEnabled(true);

    // 监听位置变化
    _backgroundLocation.onLocationChanged().listen((LocationData location) {
      setState(() {
        _locationData = location;
      });
      print('Latitude: ${location.latitude}, Longitude: ${location.longitude}');
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Background Location Demo'),
        ),
        body: Center(
          child: _locationData != null
              ? Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Text('Latitude: ${_locationData!.latitude}'),
                    Text('Longitude: ${_locationData!.longitude}'),
                  ],
                )
              : CircularProgressIndicator(),
        ),
      ),
    );
  }
}

上述代码示例展示了如何在Flutter应用中初始化并使用background_location插件来获取后台位置信息。请注意,实际项目中你可能需要处理更多的边缘情况和错误处理逻辑,例如权限被拒绝时的用户提示、位置服务不可用时的处理、以及应用进入后台时的特殊处理等。

此外,由于操作系统的更新和插件的迭代,确保你查阅最新的background_location插件文档以获取最新的使用指南和最佳实践。

回到顶部