com.google.gwt.geolocation.client.Geolocation Maven / Gradle / Ivy
/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.geolocation.client;
import com.google.gwt.core.client.Callback;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.PartialSupport;
/**
* Implements the HTML5 Geolocation interface.
*
*
* You can obtain a user's position by first calling
* Geolocation.getIfSupported()
*
*
*
* Once you have a Geolocation
, you can request the user's current
* position by calling {@link #getCurrentPosition(Callback)} or
* {@link #watchPosition(Callback)}.
*
*
*
* The first time an application requests the user's position, the browser will
* prompt the user for permission. If the user grants permission, the browser
* will locate the user and report it back to your application. If the user
* declines permission, the callback's {@link Callback#onFailure(Object)} method
* will be called with a {@link PositionError} with its code set to
* {@link PositionError#PERMISSION_DENIED}.
*
*
*
* Experimental API: This API is still under
* development and is subject to change.
*
*
* This may not be supported on all browsers.
*
*
* @see W3C Geolocation API
* @see Dive Into HTML5 -
* Geolocation
*/
@PartialSupport
public class Geolocation {
private static GeolocationSupportDetector detector;
private static Geolocation impl;
/**
* Detector for browser support for Geolocation.
*/
private static class GeolocationSupportDetector {
private static native boolean detectSupport() /*-{
return !!$wnd.navigator.geolocation;
}-*/;
private boolean supported = detectSupport();
public boolean isSupported() {
return supported;
}
}
/**
* Detector for browsers that do not support Geolocation.
*/
@SuppressWarnings("unused")
private static class GeolocationSupportDetectorNo extends GeolocationSupportDetector {
@Override
public boolean isSupported() {
return false;
}
}
/**
* Additional options for receiving the user's location.
*/
public static class PositionOptions {
private boolean enableHighAccuracy = false;
private int timeout = -1;
private int maximumAge = 0;
/**
* Sets whether or not the application will request a more accurate position
* from the browser.
*
*
* If the browser supports this option, the user will be prompted to grant
* permission to this application, even if permission to get the user's
* (less accurate) position has already been granted.
*
*
* Requesting high accuracy may be slower, or not supported at all,
* depending on the browser.
*
*
*
* By default this is false
*
*/
public PositionOptions setHighAccuracyEnabled(boolean enabled) {
this.enableHighAccuracy = enabled;
return this;
}
/**
* Allows the browser to return a position immediately with a cached
* position. The maximum age is then the oldest acceptable cached
* position. If no acceptable cached position is found, the browser will
* locate the user and cache and return the position.
*
*
* By default this is 0, which means that the position cache will not be
* used.
*
*/
public PositionOptions setMaximumAge(int maximumAge) {
this.maximumAge = maximumAge;
return this;
}
/**
* Sets the amount of time (in milliseconds) that the application is willing
* to wait before getting the user's position. If a request for position
* takes more than this amount of time, an error will result.
*
*
* By default this is -1, which means there is no application-specified
* timeout.
*
*/
public PositionOptions setTimeout(int timeout) {
this.timeout = timeout;
return this;
}
}
/**
* Returns a {@link Geolocation} if the browser supports this feature, and
* null
otherwise.
*/
public static Geolocation getIfSupported() {
if (!isSupported()) {
return null;
} else {
if (impl == null) {
impl = new Geolocation();
}
return impl;
}
}
/**
* Returns true
if the browser supports geolocation.
*/
public static boolean isSupported() {
if (detector == null) {
detector = GWT.create(GeolocationSupportDetector.class);
}
return detector.isSupported();
}
private static void handleFailure(Callback callback, int code,
String msg) {
callback.onFailure(new PositionError(code, msg));
}
private static void handleSuccess(Callback callback, PositionImpl pos) {
callback.onSuccess(pos);
}
private static native JavaScriptObject toJso(PositionOptions options) /*-{
var opt = {};
if (options) {
opt.enableHighAccuracy = options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::enableHighAccuracy;
opt.maximumAge = options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::maximumAge;
if (options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::timeout > 0) {
opt.timeout = options.@com.google.gwt.geolocation.client.Geolocation.PositionOptions::timeout;
}
}
return opt;
}-*/;
/**
* Should be instantiated by {@link #getIfSupported()}.
*/
protected Geolocation() {
}
/**
* Stops watching the user's position.
*
* @param watchId the ID of a position watch as returned by a previous call to
* {@link #watchPosition(Callback)}.
*/
public native void clearWatch(int watchId) /*-{
$wnd.navigator.geolocation.clearWatch(watchId);
}-*/;
/**
* Calls the callback with the user's current position.
*/
public void getCurrentPosition(Callback callback) {
getCurrentPosition(callback, null);
}
/**
* Calls the callback with the user's current position, with additional
* options.
*/
public native void getCurrentPosition(Callback callback,
PositionOptions options) /*-{
var opt = @com.google.gwt.geolocation.client.Geolocation::toJso(*)(options);
var success = $entry(function(pos) {
@com.google.gwt.geolocation.client.Geolocation::handleSuccess(*)(callback, pos);
});
var failure = $entry(function(err) {
@com.google.gwt.geolocation.client.Geolocation::handleFailure(*)
(callback, err.code, err.message);
});
if (@com.google.gwt.geolocation.client.Geolocation::isSupported()) {
$wnd.navigator.geolocation.getCurrentPosition(success, failure, opt);
}
}-*/;
/**
* Repeatedly calls the given callback with the user's position, as it
* changes.
*
*
* The frequency of these updates is entirely up to the browser. There is no
* guarantee that updates will be received at any set interval, but are
* instead designed to be sent when the user's position changes. This method
* should be used instead of polling the user's current position.
*
*
* @return the ID of this watch, which can be passed to
* {@link #clearWatch(int)} to stop watching the user's position.
*/
public int watchPosition(Callback callback) {
return watchPosition(callback, null);
}
/**
* Repeatedly calls the given callback with the user's position, as it
* changes, with additional options.
*
*
* The frequency of these updates is entirely up to the browser. There is no
* guarantee that updates will be received at any set interval, but are
* instead designed to be sent when the user's position changes. This method
* should be used instead of polling the user's current position.
*
*
*
* If the browser does not support geolocation, this method will do nothing,
* and will return -1.
*
*
* @return the ID of this watch, which can be passed to
* {@link #clearWatch(int)} to stop watching the user's position.
*/
public native int watchPosition(Callback callback,
PositionOptions options) /*-{
var opt = @com.google.gwt.geolocation.client.Geolocation::toJso(*)(options);
var success = $entry(function(pos) {
@com.google.gwt.geolocation.client.Geolocation::handleSuccess(*)(callback, pos);
});
var failure = $entry(function(err) {
@com.google.gwt.geolocation.client.Geolocation::handleFailure(*)
(callback, err.code, err.message);
});
if (@com.google.gwt.geolocation.client.Geolocation::isSupported()) {
$wnd.navigator.geolocation.watchPosition(success, failure, opt);
}
}-*/;
}