79622565

Date: 2025-05-15 03:29:34
Score: 1
Natty:
Report link

I know it has been three years from this, but here it is how I was able to solve this using Flutter and some JavaScript:

  1. In my index.html file inside a <script> tag I added the following function that will override the behavior of navigator.geolocation.watchPosition:
(function() {
    // I am validating if the user is on Windows because I use a different package
    const isWindows = navigator.platform.indexOf("Win") > -1;

    if (isWindows) {
        console.log("Skipping geolocation override on Windows");
        return;
    }

    let watchSuccessCallback = null;

    navigator.geolocation.watchPosition = function(success, error, options) {
        watchSuccessCallback = success;

        window.flutter_inappwebview.callHandler('watchPosition')
            .catch(err => {
                error && error({ code: 1, message: err.toString() });
            });
    };

    // Listen for updates from Flutter and forward them
    window.addEventListener('flutter-position-update', function(event) {
        if (watchSuccessCallback) {
            watchSuccessCallback(event.detail);
        }
    });
})();

On the Dart side from the WebView widget:

StreamSubscription? activeWatcher;

        ...

void dispose(){
    activeWatcher?.dispose();
    super.dispose();
}

        ...

return  InAppWebView(
      onWebViewCreated: (controller) {
        void sendPosition(final Position? position){
        controller.evaluateJavascript(source: """
        window.dispatchEvent(new CustomEvent('flutter-position-update', {
          detail: {
            coords: {
              latitude: ${position?.latitude ?? 0},
              longitude: ${position?.longitude ?? 0},
              accuracy: ${position?.accuracy ?? 100}
            },
            timestamp: ${DateTime.now().millisecondsSinceEpoch}
          }
        }));
      """);
      }
      controller.addJavaScriptHandler(handlerName: 'watchPosition', callback: (final _) async{
        // Cancel existing watcher if any
        if(activeWatcher != null){
          await activeWatcher?.cancel();
        }
        // Start listening for continuous position updates
        activeWatcher = Geolocator.getPositionStream().listen(sendPosition);

        // Return current position immediately, for some reason, if I don't do this, the map doesn't load
        final position = await Geolocator.getCurrentPosition();
        sendPosition(position);
        return {
          'coords': {
            'latitude': position.latitude,
            'longitude': position.longitude,
            'accuracy': position.accuracy
          },
          'timestamp': DateTime.now().millisecondsSinceEpoch
        };
      });
      },
    );

It works for me, if there is something not working as expected, please let me know.

Reasons:
  • Whitelisted phrase (-1): works for me
  • RegEx Blacklisted phrase (2.5): please let me know
  • Long answer (-1):
  • Has code block (-0.5):
  • Low reputation (1):
Posted by: Arturo Espinosa