Flutter后台定位插件background_location的使用
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
更多关于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项目中,你需要按照以下步骤进行配置和使用:
- 配置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>
- 配置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>
- 在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
插件文档以获取最新的使用指南和最佳实践。