我可以在 Flutter 上使用 raw_gnss 包访问 NMEA 消息吗?

问题描述 投票:0回答:1

对于我的一个项目,我正在尝试使用 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());
}
flutter dart mobile-application android-sensors android-gnss
1个回答
0
投票

我不是这方面的专家,但我遇到了和你一样的问题。我发现当页面不跟踪 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");
                              })
                    ],
                  )));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.