Class Geolocation
- All Implemented Interfaces:
Serializable
UI.getGeolocation().
Every entry point on this class is asynchronous: calling it enqueues a request to the browser and returns immediately. The browser answers later (after the user responds to a permission prompt, after the operating system reports a position, or after a timeout), and Flow invokes the callback or updates the signal on the UI thread.
Two usage modes:
get(SerializableConsumer)— one-shot position request. Use this when the application only needs to know the user's location at a single moment (e.g. on a button click). The callback receives a singleGeolocationResult; match on it to separateGeolocationPositionfromGeolocationError.track(Component)— continuous tracking that keeps the server updated as the user moves. Returns aGeolocationTrackerwhosevalue()is a reactive signal ofGeolocationResult. The browser watch is automatically cancelled when the owning component detaches; useGeolocationTracker.stop()to cancel it sooner andGeolocationTracker.resume()to resume.
getAvailability()— synchronous snapshot of whether the feature is usable and what permission state the origin has. Kept in sync automatically for the lifetime of the UI.
Permission prompts. The first time the application asks for a
location, the browser shows its own permission dialog. The dialog is
controlled by the browser, not by Flow — Flow cannot style it, suppress it,
or detect when it is shown. If the user denies the prompt the callback
receives a GeolocationError whose errorCode is GeolocationErrorCode.PERMISSION_DENIED.
One-shot example:
Button locate = new Button("Use my location");
locate.addClickListener(e -> UI.getCurrent().getGeolocation().get(result -> {
switch (result) {
case GeolocationPosition pos ->
showNearest(pos.coords().latitude(), pos.coords().longitude());
case GeolocationError err -> showManualEntry();
}
}));
Tracking example:
GeolocationTracker tracker = UI.getCurrent().getGeolocation().track(this);
Signal.effect(this, () -> {
switch (tracker.value().get()) {
case GeolocationPending p -> {
// waiting for first reading
}
case GeolocationPosition pos ->
map.setCenter(pos.coords().latitude(), pos.coords().longitude());
case GeolocationError err -> showError(err.message());
}
});
- See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidget(@Nullable GeolocationOptions options, SerializableConsumer<GeolocationResult> callback) Requests the user's current position once with tuning options.voidget(SerializableConsumer<GeolocationResult> callback) Requests the user's current position once.@Nullable GeolocationAvailabilityReturns the current geolocation availability — whether the Geolocation API is usable in this context and, if so, what permission state the origin has.Starts continuously watching the user's position, tied to the owner component's lifecycle.track(Component owner, @Nullable GeolocationOptions options) Starts continuously watching the user's position with tuning options, tied to the owner component's lifecycle.
-
Constructor Details
-
Geolocation
Creates a new Geolocation facade bound to the given UI.Framework-only. Application code obtains the instance via
UI.getGeolocation()and should not instantiate this class directly — attempting to create a second instance for a UI that already has one throws.- Parameters:
ui- the UI this facade belongs to- Throws:
IllegalStateException- if the UI already has a Geolocation facade
-
-
Method Details
-
get
Requests the user's current position once. The callback receives aGeolocationResultthat is either aGeolocationPositionor aGeolocationError.The call returns immediately. The browser may show a permission dialog on the first call; after the user responds, the callback is invoked on the UI thread.
- Parameters:
callback- invoked with the outcome once the browser reports it
-
get
public void get(@Nullable GeolocationOptions options, SerializableConsumer<GeolocationResult> callback) Requests the user's current position once with tuning options. Use this to trade accuracy for battery/speed or to accept a recent cached reading. SeeGeolocationOptionsfor the available settings.The call returns immediately. The browser may show a permission dialog on the first call; after the user responds, the callback is invoked on the UI thread.
- Parameters:
options- accuracy / timeout / cache-age tuning, ornullto use the browser defaultscallback- invoked with the outcome once the browser reports it
-
track
Starts continuously watching the user's position, tied to the owner component's lifecycle.The browser reports new positions whenever it detects movement. Each report is delivered to the returned tracker's
value()signal on the UI thread. The initial value isGeolocationPendinguntil the first reading arrives, then transitions toGeolocationPosition(updated on every subsequent reading) orGeolocationError.The underlying browser watch is automatically cancelled when
ownerdetaches, so the application does not need to write cleanup code for navigation. For cancelling while the view is still attached (e.g. a "Stop tracking" button), callGeolocationTracker.stop()on the returned tracker.- Parameters:
owner- the component that owns this tracking session; detaching the component automatically stops the watch- Returns:
- a tracker whose
GeolocationTracker.value()reports progress and whoseGeolocationTracker.stop()cancels the watch
-
track
Starts continuously watching the user's position with tuning options, tied to the owner component's lifecycle. Behaves liketrack(Component)but lets the caller request high accuracy, set a failure timeout, or accept cached readings. SeeGeolocationOptionsfor the available settings.- Parameters:
owner- the component that owns this tracking session; detaching the component automatically stops the watchoptions- accuracy / timeout / cache-age tuning, ornullto use the browser defaults- Returns:
- a tracker whose
GeolocationTracker.value()reports progress and whoseGeolocationTracker.stop()cancels the watch
-
getAvailability
Returns the current geolocation availability — whether the Geolocation API is usable in this context and, if so, what permission state the origin has.Synchronous; can be read from
onAttachor an attach listener without an async callback. The value is fetched once during the initial client handshake and kept current after that.Reliability caveats. The value is best-effort, not authoritative — it reflects what the browser last reported, and can be briefly stale in these cases:
- Between server attach and the completion of the first client
handshake — returns
nullduring this short window. Using an attach listener (which fires after the handshake) is a safe place to read a non-null value. - On Safari, the permission state is never observable;
GRANTED,DENIEDandPROMPTall surface asUNKNOWN.UNSUPPORTEDis still reported correctly. - On Firefox, permission changes the user makes in browser settings are
not reliably propagated back — the cached value can remain stale until
the next
get(com.vaadin.flow.function.SerializableConsumer<com.vaadin.flow.component.geolocation.GeolocationResult>)ortrack(com.vaadin.flow.component.Component)call. - On Chromium, the value updates promptly when the user flips the site permission, but there is still a small propagation delay between the browser event and the cache update.
get(com.vaadin.flow.function.SerializableConsumer<com.vaadin.flow.component.geolocation.GeolocationResult>)and handle the authoritative result in the callback.- Returns:
- the current availability, or
nullif the browser has not yet reported one
- Between server attach and the completion of the first client
handshake — returns
-