Flutter GPS历史记录插件gps_history的使用
Flutter GPS历史记录插件gps_history的使用
GPS History for Dart
模块旨在表示以 >= 1 秒频率记录的GPS点的历史。特性包括:
-
三种类型的GPS点:一种仅包含最基本信息的简洁类型,一种包含更多元数据(如方向、速度等)的类型,这种类型对生成GPX文件非常有用。此外,还有一种表示在某地点停留时间较长的点,这可以用于减少数据库中的重复条目。
-
不同的内存存储系统来存储GPS点:要么简单地基于列表,要么采用高效的二进制表示,每个点大约占用 14 到 22 字节(代价是精度略有损失,但该损失在GPS传感器的精度范围之内)。
-
对Google位置历史JSON导出的极低内存且快速解析器。作为参考,使用Dart JSON库直接解析一个约500MB的历史文件大约需要2GB的内存,在Intel Core i7-8565U处理器上每秒可产生约140k个点,而自定义解析器几乎不增加额外内存开销,并且输出速度比前者快2.5到3.5倍。在移动设备上解析Google位置历史时无需担心内存不足的问题。
-
模块化和可扩展架构:添加自己的点定义、容器或持久性机制。
-
包含大量单元测试、示例、基准测试和文档。
-
时间和距离处理的实用函数。
-
支持空安全。
-
第三方库依赖仅限于浅层功能,并且这些库都是主流且得到良好支持的。
示例
读取Google JSON文件
import 'dart:io';
import 'package:gps_history/gps_history.dart';
import 'package:gps_history/gps_history_convert.dart';
void main() async {
final filename = 'data/g_history_sample.json';
final file = File(filename);
final gpsStays = GpcCompactGpsStay();
final fileStream = file.openRead();
final points = fileStream.transform(GoogleJsonHistoryDecoder(
minSecondsBetweenDatapoints: 1, accuracyThreshold: 500));
final stays = points.transform(
PointsToStaysDecoder(maxTimeGapSeconds: 10, maxDistanceGapMeters: 10));
await for (final s in stays) {
gpsStays.add(s);
}
print('Read ${gpsStays.length} points');
// 计算点的记录频率
final intervals = <int>[];
final durations = <int>[];
final distances = <double>[];
GpsStay? prevPoint;
for (final s in gpsStays) {
durations.add(s.endTime.difference(s.startTime).inSeconds);
if (prevPoint != null) {
final diff = s.time.difference(prevPoint.endTime).inSeconds;
intervals.add(diff);
final dist = distance(prevPoint, s);
distances.add(dist);
}
prevPoint = s;
}
intervals.sort();
durations.sort();
distances.sort();
if (intervals.isNotEmpty) {
print('Intervals:');
print(' min = ${intervals[0]} s');
print(' median = ${intervals[intervals.length ~/ 2]} s');
print(' max = ${intervals[intervals.length - 1]} s');
}
if (durations.isNotEmpty) {
print('Durations:');
print(' min = ${durations[0]} s');
print(' median = ${durations[durations.length ~/ 2]} s');
print(' max = ${durations[durations.length - 1]} s');
}
if (distances.isNotEmpty) {
print('Distances:');
print(' min = ${distances[0].toStringAsFixed(2)} m');
print(' median = ${distances[distances.length ~/ 2].toStringAsFixed(2)} m');
print(' max = ${distances[distances.length - 1].toStringAsFixed(2)} m');
}
}
保存/重新加载数据
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:gps_history/gps_history.dart';
import 'package:gps_history/gps_history_convert.dart';
void main() async {
final databasePath = await getApplicationDocumentsDirectory();
final db = await openDatabase(databasePath.path + '/gps_history.db', version: 1, onCreate: (db, version) async {
await db.execute('CREATE TABLE gps_stay (id INTEGER PRIMARY KEY, latitude REAL, longitude REAL, startTime TEXT, endTime TEXT)');
});
final gpsStays = GpcCompactGpsStay();
// 假设你已经从某个地方获取到了gpsStays对象
await db.transaction((txn) async {
final batch = txn.batch();
for (var stay in gpsStays) {
batch.insert('gps_stay', {
'latitude': stay.latitude,
'longitude': stay.longitude,
'startTime': stay.startTime.toIso8601String(),
'endTime': stay.endTime.toIso8601String()
});
}
await batch.commit(noResult: true);
});
print('Data saved successfully.');
// 重新加载数据
final loadedStays = GpcCompactGpsStay();
final loadedStaysList = await db.query('gps_stay');
for (var stay in loadedStaysList) {
final gpsStay = GpsStay(
latitude: stay['latitude'],
longitude: stay['longitude'],
startTime: DateTime.parse(stay['startTime']),
endTime: DateTime.parse(stay['endTime'])
);
loadedStays.add(gpsStay);
}
print('Data reloaded successfully.');
}
将Google JSON文件转换为SQLite数据库
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:gps_history/gps_history.dart';
import 'package:gps_history/gps_history_convert.dart';
void main() async {
final databasePath = await getApplicationDocumentsDirectory();
final db = await openDatabase(databasePath.path + '/gps_history.db', version: 1, onCreate: (db, version) async {
await db.execute('CREATE TABLE gps_stay (id INTEGER PRIMARY KEY, latitude REAL, longitude REAL, startTime TEXT, endTime TEXT)');
});
final filename = 'data/g_history_sample.json';
final file = File(filename);
final gpsStays = GpcCompactGpsStay();
final fileStream = file.openRead();
final points = fileStream.transform(GoogleJsonHistoryDecoder(
minSecondsBetweenDatapoints: 1, accuracyThreshold: 500));
final stays = points.transform(
PointsToStaysDecoder(maxTimeGapSeconds: 10, maxDistanceGapMeters: 10));
await for (final s in stays) {
gpsStays.add(s);
}
print('Read ${gpsStays.length} points');
await db.transaction((txn) async {
final batch = txn.batch();
for (var stay in gpsStays) {
batch.insert('gps_stay', {
'latitude': stay.latitude,
'longitude': stay.longitude,
'startTime': stay.startTime.toIso8601String(),
'endTime': stay.endTime.toIso8601String()
});
}
await batch.commit(noResult: true);
});
print('Data saved successfully.');
}
更多关于Flutter GPS历史记录插件gps_history的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter GPS历史记录插件gps_history的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用gps_history
插件来获取GPS历史记录的示例代码。请注意,gps_history
插件可能不是Flutter官方插件,因此你可能需要在pubspec.yaml
文件中添加相应的依赖项(假设该插件存在于pub.dev上)。
首先,确保在pubspec.yaml
文件中添加gps_history
插件的依赖项(假设插件名为gps_history
,并且已经在pub.dev上发布):
dependencies:
flutter:
sdk: flutter
gps_history: ^x.y.z # 替换为实际版本号
然后,运行flutter pub get
来安装该插件。
接下来,在你的Flutter项目中,你可以按照以下步骤使用gps_history
插件来获取GPS历史记录。
1. 导入插件
在你的Dart文件中导入gps_history
插件:
import 'package:gps_history/gps_history.dart';
2. 请求权限
由于访问GPS历史记录需要权限,你需要在Android和iOS上请求相应的权限。以下是一个简单的权限请求示例(你可能需要根据实际情况调整):
Android
在AndroidManifest.xml
文件中添加权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
iOS
在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>
3. 使用插件获取GPS历史记录
以下是一个使用gps_history
插件获取GPS历史记录的示例代码:
import 'package:flutter/material.dart';
import 'package:gps_history/gps_history.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('GPS History Example'),
),
body: GPSHistoryScreen(),
),
);
}
}
class GPSHistoryScreen extends StatefulWidget {
@override
_GPSHistoryScreenState createState() => _GPSHistoryScreenState();
}
class _GPSHistoryScreenState extends State<GPSHistoryScreen> {
List<GPSHistoryPoint> _historyPoints = [];
@override
void initState() {
super.initState();
_getGPSHistory();
}
Future<void> _getGPSHistory() async {
try {
bool permissionGranted = await GPSHistory.requestLocationPermission();
if (permissionGranted) {
List<GPSHistoryPoint> historyPoints = await GPSHistory.getHistory();
setState(() {
_historyPoints = historyPoints;
});
} else {
print('Location permission denied');
}
} catch (e) {
print('Error fetching GPS history: $e');
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: _historyPoints.length,
itemBuilder: (context, index) {
GPSHistoryPoint point = _historyPoints[index];
return ListTile(
title: Text('Latitude: ${point.latitude}, Longitude: ${point.longitude}'),
subtitle: Text('Timestamp: ${point.timestamp}'),
);
},
);
}
}
class GPSHistoryPoint {
final double latitude;
final double longitude;
final DateTime timestamp;
GPSHistoryPoint({required this.latitude, required this.longitude, required this.timestamp});
}
注意:上述代码中的GPSHistoryPoint
类是一个假设的类,用于存储GPS历史记录点。实际的gps_history
插件可能会有自己的数据结构,你需要根据插件的文档进行调整。此外,GPSHistory.getHistory()
方法也是一个假设的方法,你需要根据插件的实际API进行替换。
由于gps_history
插件的具体API和实现细节可能有所不同,建议查阅该插件的官方文档或源代码以获取准确的信息。如果插件不支持直接获取GPS历史记录,你可能需要寻找其他方法或插件来实现该功能。