Flutter后台定位插件flutter_location_bg的使用
Flutter后台定位插件flutter_location_bg的使用
Android设置
在您的AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
之后,在<application>
标签内包含以下条目:
<application
...
<!-- 配置background_locator_2 -->
<receiver android:name="yukams.app.background_locator_2.BootBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<service android:name="yukams.app.background_locator_2.IsolateHolderService"
android:permission="android.permission.FOREGROUND_SERVICE"
android:exported="true"
android:foregroundServiceType = "location"/>
</application>
注意:在Android 11及更高版本上,应用程序无法通过清单文件自动设置位置权限。Google在其页面上提到:
在Android 11(API级别30)及以上版本上,系统对话框不包括始终允许选项。用户必须在设置页面上手动启用后台位置。
因此,为了使此插件(及其示例应用)正常工作,您需要进入此设置屏幕并手动将权限设置为“始终允许”。
iOS设置
在您的Info.plist
文件中添加以下条目:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>此应用需要在打开和后台时访问位置。</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>此应用需要在后台时访问位置。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>此应用需要在打开时访问位置。</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
接下来,用以下内容覆盖您的AppDelegate.swift
文件:
import UIKit
import Flutter
import background_locator_2
func registerPlugins(registry: FlutterPluginRegistry) -> () {
if (!registry.hasPlugin("BackgroundLocatorPlugin")) {
GeneratedPluginRegistrant.register(with: registry)
}
}
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
BackgroundLocatorPlugin.setPluginRegistrantCallback(registerPlugins)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
功能
请在此处提交功能请求和错误报告。
开始使用
请参阅示例应用以获取完整的使用示例。
使用示例
// 配置定位管理器
LocationManager().interval = 1;
LocationManager().distanceFilter = 0;
LocationManager().notificationTitle = 'CARP Location Example';
LocationManager().notificationMsg = 'CARP正在跟踪您的位置';
// 获取当前定位
await LocationManager().getCurrentLocation();
// 开始监听定位更新
StreamSubscription<LocationDto> locationSubscription = LocationManager()
.locationStream
.listen((LocationDto loc) => print(loc));
// 取消监听并停止定位管理器
locationSubscription?.cancel();
LocationManager().stop();
请参阅示例应用以获取完整的使用示例。
示例代码
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_location_bg/flutter_location_bg.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
enum LocationStatus { UNKNOWN, INITIALIZED, RUNNING, STOPPED }
class _MyAppState extends State<MyApp> {
String logStr = '';
LocationDto? _lastLocation;
StreamSubscription<LocationDto>? locationSubscription;
LocationStatus _status = LocationStatus.UNKNOWN;
[@override](/user/override)
void initState() {
super.initState();
LocationManager().interval = 1;
LocationManager().distanceFilter = 0;
LocationManager().notificationTitle = 'CARP Location Example';
LocationManager().notificationMsg = 'CARP正在跟踪您的位置';
_status = LocationStatus.INITIALIZED;
}
void getCurrentLocation() async => onData(await LocationManager().getCurrentLocation());
void onData(LocationDto location) {
print('>> $location');
setState(() {
_lastLocation = location;
});
}
/// 是否已授予“始终允许”位置权限?
Future<bool> isLocationAlwaysGranted() async => await Permission.locationAlways.isGranted;
/// 尝试从用户那里请求“始终允许”位置权限。
/// 如果成功返回`true`,否则返回`false`。
Future<bool> askForLocationAlwaysPermission() async {
bool granted = await Permission.locationAlways.isGranted;
if (!granted) {
granted = await Permission.locationAlways.request() == PermissionStatus.granted;
}
return granted;
}
/// 开始监听定位事件。
void start() async {
// 如果未授予位置权限,则请求位置权限
if (!await isLocationAlwaysGranted()) await askForLocationAlwaysPermission();
locationSubscription?.cancel();
locationSubscription = LocationManager().locationStream.listen(onData);
await LocationManager().start();
setState(() {
_status = LocationStatus.RUNNING;
});
}
void stop() {
locationSubscription?.cancel();
LocationManager().stop();
setState(() {
_status = LocationStatus.STOPPED;
});
}
Widget stopButton() => SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: const Text('STOP'),
onPressed: stop,
),
);
Widget startButton() => SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: const Text('START'),
onPressed: start,
),
);
Widget statusText() => Text("Status: ${_status.toString().split('.').last}");
Widget currentLocationButton() => SizedBox(
width: double.maxFinite,
child: ElevatedButton(
child: const Text('CURRENT LOCATION'),
onPressed: getCurrentLocation,
),
);
Widget locationWidget() {
if (_lastLocation == null) return Text("无位置数据");
else return Column(
children: <Widget>[
Text(
'${_lastLocation!.latitude}, ${_lastLocation!.longitude}',
),
Text(
'@',
),
Text('${DateTime.fromMillisecondsSinceEpoch(_lastLocation!.time ~/ 1)}')
],
);
}
[@override](/user/override)
void dispose() => super.dispose();
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('CARP后台定位'),
),
body: Container(
width: double.maxFinite,
padding: const EdgeInsets.all(22),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
startButton(),
stopButton(),
currentLocationButton(),
Divider(),
statusText(),
Divider(),
locationWidget(),
],
),
),
),
),
);
}
}
更多关于Flutter后台定位插件flutter_location_bg的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter后台定位插件flutter_location_bg的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_location_bg
是一个用于在 Flutter 应用中实现后台定位的插件。它允许应用在后台持续获取设备的位置信息,即使应用不在前台运行。这对于需要持续跟踪用户位置的应用(如健身应用、打车应用等)非常有用。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 flutter_location_bg
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_location_bg: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 配置 Android
为了在 Android 上使用后台定位,你需要进行以下配置:
2.1. 添加权限
在 AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2.2. 配置后台服务
在 AndroidManifest.xml
中添加以下服务声明:
<service
android:name="com.example.flutter_location_bg.LocationBackgroundService"
android:enabled="true"
android:exported="false" />
3. 配置 iOS
在 iOS 上,你需要在 Info.plist
文件中添加以下键值对以请求定位权限:
<key>NSLocationAlwaysUsageDescription</key>
<string>我们需要您的位置信息来提供更好的服务。</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>我们需要您的位置信息来提供更好的服务。</string>
4. 使用插件
以下是如何在 Flutter 应用中使用 flutter_location_bg
插件的基本示例:
import 'package:flutter/material.dart';
import 'package:flutter_location_bg/flutter_location_bg.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> {
LocationData? _locationData;
@override
void initState() {
super.initState();
_startLocationService();
}
void _startLocationService() async {
await FlutterLocationBg.startLocationService(
interval: Duration(seconds: 10), // 定位间隔时间
distanceFilter: 10, // 距离过滤,单位:米
notificationTitle: "后台定位服务",
notificationText: "正在获取位置信息",
callback: (LocationData locationData) {
setState(() {
_locationData = locationData;
});
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('后台定位示例'),
),
body: Center(
child: _locationData == null
? Text('正在获取位置信息...')
: Text('位置信息: ${_locationData!.latitude}, ${_locationData!.longitude}'),
),
);
}
}
5. 停止后台定位服务
当你不再需要后台定位时,可以调用 FlutterLocationBg.stopLocationService()
来停止服务:
void _stopLocationService() async {
await FlutterLocationBg.stopLocationService();
}