对于我的一个项目,我正在尝试使用 Pixel 5 中的 Flutter 应用程序访问 GNSS NMEA 消息。我现在使用的库是 raw_gnss (https://github.com/deven98/raw_gnss)。我可以使用该包访问测量数据,但不知道如何提取 NMEA 消息。
任何人都可以帮助我访问 NMEA 消息吗?
谢谢你。
我使用 gnssStatusModel、gnssMeasurementModel 和 raw_gnss 函数尝试了不同的操作,但现在只有 gnssMeasurement 模型可以工作。我需要使用时间戳、constellationType、svid、az、el 和 CN_0 解析原始 NMEA 消息。
gnssMeasurementModel 的 main.dart 文件(工作):
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:raw_gnss/gnss_measurement_model.dart';
import 'package:raw_gnss/gnss_status_model.dart';
import 'package:raw_gnss/raw_gnss.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(
title: Text("Eddy's GNSS logs"),
),
body: HomeScreen(),
),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
var _hasPermissions = false;
late RawGnss _gnss;
@override
void initState() {
super.initState();
_gnss = RawGnss();
Permission.location
.request()
.then((value) => setState(() => _hasPermissions = value.isGranted));
}
// Measurment Model
@override
Widget build(BuildContext context) => _hasPermissions
? StreamBuilder<GnssMeasurementModel>(
builder: (context, snapshot) {
return ListView.builder(
itemBuilder: (context, position) {
if (snapshot.data != null){
int count =0;
while(count< snapshot.data!.measurements!.length) {
return ListTile(
title: Text(
//"${snapshot.data!.status![count].svid} ${snapshot.data!.status![count].azimuthDegrees} ${snapshot.data!.status![count].elevationDegrees}"),
"Time: ${snapshot.data!.measurements![count].receivedSvTimeNanos} PRN: ${snapshot.data!.measurements![count].svid}, C_N0: ${snapshot.data!.measurements![count].cn0DbHz}, Constellation type: ${snapshot.data!.measurements![count].constellationType} "),
);
}
}
},
//itemCount: snapshot.data!.satelliteCount ?? 0,
);
},
stream: _gnss.gnssMeasurementEvents,
)
: _loadingSpinner();
Widget _loadingSpinner() => const Center(child: CircularProgressIndicator());
}
gnssStatusModel 的 main.dart(不工作):
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:raw_gnss/gnss_measurement_model.dart';
import 'package:raw_gnss/gnss_status_model.dart';
import 'package:raw_gnss/raw_gnss.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: Scaffold(
appBar: AppBar(
title: Text("Eddy's GNSS logs"),
),
body: HomeScreen(),
),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
var _hasPermissions = false;
late RawGnss _gnss;
@override
void initState() {
super.initState();
_gnss = RawGnss();
Permission.location
.request()
.then((value) => setState(() => _hasPermissions = value.isGranted));
}
//GNSS STATUS
@override
Widget build(BuildContext context) => _hasPermissions
? StreamBuilder<GnssStatusModel>(//StreamBuilder<GnssMeasurementModel>(
builder: (context, snapshot) {
return ListView.builder(
itemBuilder: (context, position) {
if (snapshot.data != null){
int count =0;
while(count<snapshot.data!.status!.length){//while(count< snapshot.data!.measurements!.length) {
return ListTile(
title: Text(
"${snapshot.data!.status![count].svid} ${snapshot.data!.status![count].azimuthDegrees} ${snapshot.data!.status![count].elevationDegrees}"),
//"Time: ${snapshot.data!.measurements![count].receivedSvTimeNanos} PRN: ${snapshot.data!.measurements![count].svid}, C_N0: ${snapshot.data!.measurements![count].cn0DbHz}, Constellation type: ${snapshot.data!.measurements![count].constellationType} "),
);
}
}
},
//itemCount: snapshot.data!.satelliteCount ?? 0,
);
},
stream: _gnss.gnssStatusEvents,
)
: _loadingSpinner();
Widget _loadingSpinner() => const Center(child: CircularProgressIndicator());
}
我不是这方面的专家,但我遇到了和你一样的问题。我发现当页面不跟踪 gnssMeasurement 时,gnssStatus 永远不会更新。只要在页面上跟踪 gnssMeasurement 值,gnssStatus 就与 gnssMeasurement 一样能够更改。
您可以尝试以下代码,默认情况下gnssMeasurement不被跟踪,gnssStatus将始终意识到它正在加载,并且一旦单击Toggle GnssMeasurement按钮以显示与gnssMeasurement相关的内容,gnssStatus将相应更新。
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:raw_gnss/raw_gnss.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.lightGreen),
useMaterial3: true,
),
home: const TestPage(),
);
}
}
class TestPage extends StatefulWidget {
const TestPage({super.key});
@override
State<TestPage> createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
var _hasPermissions = false;
var _showGnssMeasurement = false;
late RawGnss _gnss;
@override
void initState() {
super.initState();
_gnss = RawGnss();
Permission.location
.request()
.then((value) => setState(() => _hasPermissions = value.isGranted));
}
void _toggleGnssMeasurement() {
setState(() {
_showGnssMeasurement = !_showGnssMeasurement;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text("GnssStatus Demo"),
),
body: Center(
child: !_hasPermissions
? const Text('No permissions!')
: Column(
children: [
StreamBuilder(
stream: _gnss.gnssStatusEvents,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Text("Loading gnssStatus...");
}
var gnssStatus = snapshot.data!;
return Column(
children: [
Text('Update at : ${DateTime.now()}'),
Text(
"All satellites: ${gnssStatus.satelliteCount}"),
],
);
},
),
// 分隔线
const Divider(),
ElevatedButton(
onPressed: _toggleGnssMeasurement,
child: const Text("Toggle GnssMeasurement")),
!_showGnssMeasurement
? Container()
: StreamBuilder(
stream: _gnss.gnssMeasurementEvents,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Text(
"Loading gnssMeasurement...");
}
var measurements = snapshot.data!.measurements!;
var lens = measurements.length;
return Text("Measurements lens: $lens");
})
],
)));
}
}