deven98 / raw_gnss

BSD 2-Clause "Simplified" License
13 stars 8 forks source link

Is this package functional? #2

Open GSORF opened 2 years ago

GSORF commented 2 years ago

Hello and thank you for providing this very useful package.

May I ask what the current status of this package is? I am trying to get the basic example running and it continuously shows the circularProgressIndicator in the UI. I tried to move my phone outside the house for a few minutes, but this didnt help. Before I put more time into getting this to run, I want to ask here first.

Kind regards, Adam

GSORF commented 2 years ago

Ok, today I gave it another shot. And the good news is, that in out of approx. 40 tests, I got the example working twice. I cannot really put my finger on the reason why it worked, though. I assume that there might be an issue with my GNSS receiver, because printing the snapshot to the console it says "ConnectionStatus.waiting". I understand that I need to wait for a GNSS fix, but this shouldn't be as random as in my tests. Although I was able to see the list of detected satellites in the UI at least twice during my extensive tests, I still want to do more tests to better identify the problems on my side. The goal is to improve the documentation for others who may face similar problems.

For example, the "Usage" description did not work at all on my side: https://github.com/deven98/raw_gnss#usage

Will report back once I will make another step towards getting the package working on my side.

deven98 commented 2 years ago

Hey @GSORF,

The latest update has GNSS Status as the default example. Can you let me know if GNSS Measurement events described in the README work on GitHub work for you?

Thanks.

GSORF commented 2 years ago

Hi @deven98 and thanks for your reply,

I am sitting outside again at the moment and will try to describe what I am testing as detailed as possible.

The code I have composed from every source related to the raw_gnss is the following:

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("Demo"),
        ),
        body: SingleChildScrollView(child: 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;
          print(value);
          RawGnss().gnssMeasurementEvents.listen((e) {
            print(e);
          });
          RawGnss().gnssNavigationMessageEvents.listen((e) {
            print(e);
          });
          RawGnss().gnssStatusEvents.listen((e) {
            print(e);
          });
        }));
  }

  @override
  Widget build(BuildContext context) => _hasPermissions
      ? Column(
          children: [
            StreamBuilder<GnssMeasurementModel>(
              builder: (context, snapshot) {
                print(snapshot);
                if (snapshot.data == null) {
                  return const CircularProgressIndicator();
                }

                return ListView.builder(
                  itemBuilder: (context, position) {
                    return ListTile(
                      title: Text(
                          "Satellite: ${snapshot.data!.measurements![position].toString()}"),
                    );
                  },
                  itemCount: snapshot.data!.measurements?.length ?? 0,
                );
              },
              stream: RawGnss().gnssMeasurementEvents,
            ),
            StreamBuilder<dynamic>(
              builder: (context, snapshot) {
                print(snapshot);
                if (snapshot.data == null) {
                  return const CircularProgressIndicator();
                }

                return ListView.builder(
                  itemBuilder: (context, position) {
                    return ListTile(
                      title: Text("Satellite: ${snapshot.data!}"),
                    );
                  },
                  itemCount: snapshot.data ?? 0,
                );
              },
              stream: RawGnss().gnssNavigationMessageEvents,
            ),
            StreamBuilder<GnssStatusModel>(
              builder: (context, snapshot) {
                if (snapshot.data == null) {
                  return const CircularProgressIndicator();
                }
                print(snapshot.data);
                return ListView.builder(
                  itemBuilder: (context, position) {
                    return ListTile(
                      title: Text("Satellite: ${snapshot.data!.toString()}"),
                    );
                  },
                  itemCount: snapshot.data!.satelliteCount ?? 0,
                );
              },
              stream: RawGnss().gnssStatusEvents,
            )
          ],
        )

      /*  
      StreamBuilder<GnssStatusModel>(
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return _loadingSpinner();
            } else {
              return ListView.builder(
                itemBuilder: (context, position) {
                  return ListTile(
                    title: Text(
                        "Satellite: ${snapshot.data!.status![position].azimuthDegrees}"),
                  );
                },
                itemCount: snapshot.data!.satelliteCount ?? 0,
              );
            }
          },
          stream: _gnss.gnssStatusEvents,
        ) */
      : _loadingSpinner();

  Widget _loadingSpinner() => const Center(child: CircularProgressIndicator());
}

I have some additional code in my project but I have removed any references and merely left the above code in my main.dart

Additionally, I have added all possible permission to my AndroidManifest.xml file in the folder {MY_PROJECT_DIRECTORY}/android/app/src/main/AndroidManifest.xml as can be seen below:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
<uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCOUNT_MANAGER"/>
<uses-permission android:name="android.permission.ADD_VOICEMAIL"/>
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS"/>
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"/>
<uses-permission android:name="android.permission.BATTERY_STATS"/>
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE"/>
<uses-permission android:name="android.permission.BIND_APPWIDGET"/>
<uses-permission android:name="android.permission.BIND_AUTOFILL_SERVICE"/>
<uses-permission android:name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
<uses-permission android:name="android.permission.BIND_CARRIER_SERVICES"/>
<uses-permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"/>
<uses-permission android:name="android.permission.BIND_CONDITION_PROVIDER_SERVICE."/>
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN"/>
<uses-permission android:name="android.permission.BIND_DREAM_SERVICE"/>
<uses-permission android:name="android.permission.BIND_INCALL_SERVICE"/>
<uses-permission android:name="android.permission.BIND_INPUT_METHOD"/>
<uses-permission android:name="android.permission.BIND_NFC_SERVICE"/>
<uses-permission android:name="android.permission.BIND_MIDI_DEVICE_SERVICE"/>
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
<uses-permission android:name="android.permission.BIND_PRINT_SERVICE"/>
<uses-permission android:name="android.permission.BIND_QUICK_SETTINGS_TILE"/>
<uses-permission android:name="android.permission.BIND_REMOTEVIEWS"/>
<uses-permission android:name="android.permission.BIND_SCREENING_SERVICE"/>
<uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"/>
<uses-permission android:name="android.permission.BIND_TEXT_SERVICE"/>
<uses-permission android:name="android.permission.BIND_TV_INPUT"/>
<uses-permission android:name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
<uses-permission android:name="android.permission.BIND_VOICE_INTERACTION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BIND_WALLPAPER"/>
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.BIND_VR_LISTENER_SERVICE"/>
<uses-permission android:name="android.permission.BIND_VPN_SERVICE"/>
<uses-permission android:name="android.permission.BODY_SENSORS"/>
<uses-permission android:name="android.permission.BRICK"/>
<uses-permission android:name="android.permission.BROADCAST_PACKAGE_REMOVED"/>
<uses-permission android:name="android.permission.BROADCAST_SMS"/>
<uses-permission android:name="android.permission.BROADCAST_STICKY"/>
<uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CALL_PRIVILEGED"/>
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"/>
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT"/>
<uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA"/>
<uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES"/>
<uses-permission android:name="android.permission.DELETE_CACHE_FILES"/>
<uses-permission android:name="android.permission.DELETE_PACKAGES"/>
<uses-permission android:name="android.permission.DEVICE_POWER"/>
<uses-permission android:name="android.permission.DIAGNOSTIC"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.DUMP"/>
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>
<uses-permission android:name="android.permission.FACTORY_TEST"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.FORCE_BACK"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"/>
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"/>
<uses-permission android:name="android.permission.GLOBAL_SEARCH"/>
<uses-permission android:name="android.permission.HARDWARE_TEST"/>
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
<uses-permission android:name="android.permission.INSTALL_LOCATION_PROVIDER"/>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS"/>
<uses-permission android:name="android.permission.MANAGE_APP_TOKENS"/>
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
<uses-permission android:name="android.permission.MASTER_CLEAR"/>
<uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.NFC"/>
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
<uses-permission android:name="android.permission.PERSISTENT_ACTIVITY"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>
<uses-permission android:name="android.permission.READ_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.READ_INPUT_STATE"/>
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_SOCIAL_STREAM"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.READ_USER_DICTIONARY"/>
<uses-permission android:name="android.permission.READ_VOICEMAIL"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.REBOOT"/>
<uses-permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.SET_ACTIVITY_WATCHER"/>
<uses-permission android:name="android.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.SET_ALWAYS_FINISH"/>
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>
<uses-permission android:name="android.permission.SET_DEBUG_APP"/>
<uses-permission android:name="android.permission.SET_ORIENTATION"/>
<uses-permission android:name="android.permission.SET_POINTER_SPEED"/>
<uses-permission android:name="android.permission.SET_PREFERRED_APPLICATIONS"/>
<uses-permission android:name="android.permission.SET_PROCESS_LIMIT"/>
<uses-permission android:name="android.permission.SET_TIME"/>
<uses-permission android:name="android.permission.SET_TIME_ZONE"/>
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
<uses-permission android:name="android.permission.SET_WALLPAPER_HINTS"/>
<uses-permission android:name="android.permission.TRANSMIT_IR"/>
<uses-permission android:name="android.permission.UNINSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:name="android.permission.USE_SIP"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_GSERVICES"/>
<uses-permission android:name="android.permission.WRITE_HISTORY_BOOKMARKS"/>
<uses-permission android:name="android.permission.WRITE_PROFILE"/>
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.WRITE_SOCIAL_STREAM"/>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_USER_DICTIONARY"/>
<uses-permission android:name="android.permission.WRITE_VOICEMAIL"/>

Running the code above will result in some useful terminal output like this:

I/flutter (15023): PermissionStatus.granted
D/GNSS_MEASURE(15023): onListen
D/GNSS_MESSAGE(15023): onListen
D/GNSS_STATUS(15023): onListen
I/flutter (15023): AsyncSnapshot<GnssMeasurementModel>(ConnectionState.waiting, null, null, null)
I/flutter (15023): AsyncSnapshot<dynamic>(ConnectionState.waiting, null, null, null)
D/GNSS_MEASURE(15023): onStatusChanged: 1
D/GNSS_MEASURE(15023): onStatusChanged: 0
D/GNSS_MESSAGE(15023): onStatusChanged: 0
D/GNSS_MEASURE(15023): onCancel
D/GNSS_MEASURE(15023): onListen
D/GNSS_MESSAGE(15023): onCancel
D/GNSS_MESSAGE(15023): onListen
D/GNSS_MEASURE(15023): onStatusChanged: 1
D/GNSS_MEASURE(15023): onStatusChanged: 0
D/GNSS_MESSAGE(15023): onStatusChanged: 0
D/GNSS_STATUS(15023): onCancel
D/GNSS_STATUS(15023): onListen
W/Gralloc3(15023): mapper 3.x is not supported
The Flutter DevTools debugger and profiler on MAR LX1A is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:58559/LHVQik90h4s=/
D/AwareBitmapCacher(15023): handleInit switch not opened pid=15023
E/        (15023): APS:IFLoad:importExternalFunctions, search function createNewHwApsUtils failed, dlsym err:undefined symbol: createNewHwApsUtils
D/        (15023): APS:importExternalFunctions OK
I/HwViewRootImpl(15023): removeInvalidNode jank list is null
W/IInputConnectionWrapper(15023): getExtractedText on inactive InputConnection
W/IInputConnectionWrapper(15023): getTextBeforeCursor on inactive InputConnection

The status changes coming from the power saving mode on my phone while I am typing this message. The error messages are unfortunately unclear to me at this point. I suppose they are not related to the GNSS issue but I still need to investigate that.

The visible result in the app is: Three Circular Progress Indicators which are not changing for at least 10 minutes (with interruptions due to energy saving mode). It is a (very) hot day with an open sky, I am near to individual trees and some buildings. Not ideal for a GNSS fix, but at least there should be something bad location data coming. I have free wifi here and yesterday I had a fix at least once, so I believe there are some other factors interfering. At the moment I am still investigating the issue and will now simplify the code until I got the version linked in the GitHub README. Once I have tested it, I will report back here.

GSORF commented 2 years ago

Oh, now there is some success again!

I have copied the code from the example folder in this repository.

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.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("Demo"),
        ),
        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));
  }

  @override
  Widget build(BuildContext context) => _hasPermissions
      ? StreamBuilder<GnssStatusModel>(
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return _loadingSpinner();
            } else {
              return ListView.builder(
                itemBuilder: (context, position) {
                  return ListTile(
                    title: Text(
                        "Satellite: ${snapshot.data!.status![position].azimuthDegrees}"),
                  );
                },
                itemCount: snapshot.data!.satelliteCount ?? 0,
              );
            }
          },
          stream: _gnss.gnssStatusEvents,
        )
      : _loadingSpinner();

  Widget _loadingSpinner() => const Center(child: CircularProgressIndicator());
}

I did not clone this repository, but am using the official method to include _rawgnss: ^1.1.0+1 in pubspec.yaml.

I have aborted the running app from above in the terminal and re-executed flutter run in the terminal. At first, the only change was that there was only one Circular Progress Indicator spinning but again: No gnss related output! After waiting 2 minutes, I have disabled and re-enabled the location service in my phone and et voila - magically I can now see the azimuthDegrees of quite a large number of satellites. So why is it now working but not before? Why do I need to toggle the location service of my phone to make it work?

This is part of the terminal output now:

D/GNSS_STATUS(19457): onGnssStatusReceived: android.location.GnssStatus@19d5968
D/GNSS_STATUS(19457): onGnssStatusReceived: android.location.GnssStatus@facf181

What I have also changed in my project is to comment out all the unused flutter packages for my GNSS test. Specifically I am talking about these:

So maybe one of these packages is interfering with raw_gnss? Quite a lot to test still. Will report back again after modifying the example to output some more verbose data (such as constellation type and svid). I am happy, but still very worried that this case is a lucky one. We will see.

GSORF commented 2 years ago

Ok, of course it did not work (i.e. I was presented with an infinite Circular Progress indicator) after modifying the example. I tried re-enabling the location service in my phone, restarting the app and rebuilding. No success.

Then I rebooted my phone... ...at first it didn't work again but this could have been due to my disabled internet SIM card (I accidentally skipped the PIN dialogue). It was weird that the app didn't ask me to enable my location services until I got my internet SIM card enabled (but who knows if this was the reason - it would make sense as phone GNSS receivers tend to get location data over the internet as well). And then once again, it worked like magic! And my modifications to the example are visible in the UI - yay! Still, I cannot put my finger on the exact reason why it only works sporadically like that. Hmm, testing continues...

For reference this is the code which is currently running successfully on my phone - I would love to contribute it (and any other modifications) to this repository:

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.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("Demo"),
        ),
        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));
  }

  @override
  Widget build(BuildContext context) => _hasPermissions
      ? StreamBuilder<GnssStatusModel>(
          builder: (context, snapshot) {
            if (snapshot.data == null) {
              return _loadingSpinner();
            } else {
              return ListView.builder(
                itemBuilder: (context, position) {
                  return ListTile(
                    title: Text(
                        "${position}. Satellite (${snapshot.data!.status![position].svid}): azimuth: ${snapshot.data!.status![position].azimuthDegrees}°, elevation: ${snapshot.data!.status![position].elevationDegrees}°, constellation: ${snapshot.data!.status![position].constellationType}"),
                  );
                },
                itemCount: snapshot.data!.satelliteCount ?? 0,
              );
            }
          },
          stream: _gnss.gnssStatusEvents,
        )
      : _loadingSpinner();

  Widget _loadingSpinner() => const Center(child: CircularProgressIndicator());
}
GSORF commented 2 years ago

Ok, rebooting the phone will let me test the code just once! This is so freaking annoying, I need to get another phone to try if it works better there. -.-

Enough for today.

GSORF commented 2 years ago

A short update from my side:

It seems that my phone somehow does not allow the Geolocation Service to establish a connection to the GNSS satellites unless I reboot it. My current workaround is that I am using this raw_gnss package here together with the flutter geolocator package (https://pub.dev/packages/geolocator/example). I managed to get my app working now, so that I do not need to reboot my phone every time before testing raw_gnss, so that's the good news. Somehow the constant pulling of geolocator streams also fixes the communication for raw_gnss (I am using the stream listeners as described in the README at the moment). Currently, my code is not suitable for a minimal working example which I can contribute and furthermore the additional dependency on another package is not how it should be working of course. I am continuing to investigate, but at least I can use the raw_gnss package now and I am also pretty happy with the results!

However, besides the above issue, I am still facing two problems:

  1. I cannot get raw_gnss and geolocator running simultaneously at the moment to get the raw gnss data with the calculated user position (latitude / longitude), but I am still investigating the issue. Not sure at the moment, but raw_gnss should also provide the estimated user position somewhere (I think in the StatusModel)
  2. Listening to the StatusModel-stream will crash my app with two alternating errors. Code to reproduce:

    late RawGnss _gnss;
    
    void initState() {
    super.initState();
    _gnss.gnssStatusEvents.listen((e) {
      print(e);
    });
    }

Will throw these exceptions forever (results in a red error screen in UI):

Another exception was thrown: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 6207 pos 12: 'child == _child': is not true.

Another exception was thrown: Duplicate GlobalKey detected in widget tree.

{REPEATS INFINITELY...}

To sum up, I can now basically use the raw_gnss package for my app and I like it how it was implemented (especially (1) the simple stream listeners and (2) the descriptive model fields). However, there are still many issues I want to have resolved. So I will keep this issue open for now hoping that someone will have an idea or - eventually - I will be able to post the solution here myself.

At this point I want to express my gratitude for providing this flutter package again - thank you for the great work!

Kind regards, Adam

GSORF commented 1 year ago

Ok, I think I have found the issue with the StatusModel.

I have proposed a pull request, see #5 and hope I can contribute to make this flutter package even more awesome than it is!

Thank you for creating and maintaining it. Keep it up!

This issue can be closed now.

Kind regards, Adam