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:
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.