首先高德本身就支持后台持续定位:实例文档.对于Flutter项目高德也提供了框架支持:文档
pubspec.yaml如下:
dependencies:
flutter:
sdk: flutter
# 权限相关
permission_handler: ^5.1.0+2
# 定位功能
amap_location_fluttify: ^0.20.0
实现逻辑我们以iOS项目为例:
iOS项目工程(ios/Runner)配置:
添加定位权限申请配置
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>申请Always权限以便应用在前台和后台(suspend 或 terminated)都可以获取到更新的位置数据</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>需要您的同意才能始终访问位置</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要您的同意,才能在使用期间访问位置</string>
以上权限会根据iOS 系统版本的不同有所不同
后台任务(Background Modes)模式配置
<key>UIBackgroundModes</key>
<array>
<string>location</string>
<string>remote-notification</string>
</array>
选择Location updates
选项
Flutter项目实例
对于Flutter中的使用方法,具体实例如下:
- 首先要在main函数中进行高德地图组件的注册
- 视图中在调用定位之前必须进行权限申请
- 开启后台任务功能
- 执行持续定位
代码 main.dart
:
import 'package:amap_location_fluttify/amap_location_fluttify.dart';
void main() {
runApp(const MyApp());
# 注册高德地图组件
AmapLocation.instance.init(iosKey: 'xxxxxx');
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LocationPage(),
);
}
}
location_page.dart
:
import 'package:amap_location_fluttify/amap_location_fluttify.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:permission_handler/permission_handler.dart';
class LocationPage extends StatefulWidget {
LocationPage({Key? key}) : super(key: key);
_LocationPageState createState() => _LocationPageState();
}
class _LocationPageState extends State<LocationPage> {
//获取数据
// Map<String, Object> _locationResult;
String _latitude = ""; //纬度
String _longitude = ""; //经度
@override
void initState() {
super.initState();
/// 动态申请定位权限
requestPermission();
}
@override
void dispose() {
super.dispose();
}
/// 动态申请定位权限
void requestPermission() async {
// 申请权限
bool hasLocationPermission = await requestLocationPermission();
if (hasLocationPermission) {
print("定位权限申请通过");
} else {
print("定位权限申请不通过");
}
}
/// 申请定位权限 授予定位权限返回true, 否则返回false
Future<bool> requestLocationPermission() async {
//获取当前的权限
var status = await Permission.locationAlways.status;
if (status == PermissionStatus.granted) {
//已经授权
return true;
} else {
//未授权则发起一次申请
status = await Permission.location.request();
if (status == PermissionStatus.granted) {
return true;
} else {
return false;
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("地理定位演示"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// latitude: 36.570091461155336, longitude: 109.5080830206976
//
Text("纬度:${this._latitude}"),
Text("经度:${this._longitude}"),
SizedBox(height: 20),
ElevatedButton(
child: Text('开始定位'),
onPressed: () {
this._startTheLocation();
},
),
],
),
),
);
}
Future _startTheLocation() async {
if (await Permission.location.request().isGranted) {
# 开启后台持续定位功能
await AmapLocation.instance.enableBackgroundLocation(
10,
BackgroundNotification(
contentTitle: 'contentTitle',
channelId: 'channelId',
contentText: 'contentText',
channelName: 'channelName',
),
);
# 监听持续定位
AmapLocation.instance.listenLocation().listen((location) {
setState(() {
_latitude = location.latLng.latitude.toString();
_longitude = location.latLng.longitude.toString();
print("监听定位: {$_latitude, $_longitude}");
});
});
} else {
openAppSettings();
}
}
}
总结
关于后台持续定位对于高德来说核心函数只有2个:
开启后台任务
AmapLocation.instance.enableBackgroundLocation(id, notification)
执行持续定位:
AmapLocation.instance.listenLocation().listen((location) {
// do someting
});