package com.nutiteq.location.providers; import javax.microedition.location.Criteria; import javax.microedition.location.Location; import javax.microedition.location.LocationException; import javax.microedition.location.LocationProvider; import com.nutiteq.components.WgsPoint; import com.nutiteq.location.LocationListener; import com.nutiteq.location.LocationMarker; import com.nutiteq.location.LocationSource; import com.nutiteq.log.Log; /** * This is a wrapper class around JSR179 */ public class LocationAPIProvider implements Runnable, LocationSource, javax.microedition.location.LocationListener { private Criteria criteria; private LocationProvider locationProvider; private int status; private LocationMarker marker; private final int updateInterval; private LocationListener[] listeners = new LocationListener[0]; private WgsPoint wgsLocation; private final int accuracy; /** * Create location provider with given update interval (in milliseconds) and * without any accuracy requirements. * * @param updateInterval * location update time in milliseconds */ public LocationAPIProvider(final long updateInterval) { this(updateInterval, Criteria.NO_REQUIREMENT); } /** * <p> * Create location provider with given update interval (in milliseconds) and * without an accuracy requirement. * </p> * <p> * On <strong>Nokia</strong> phones this could trigger assisted positioning * for faster location finding. * </p> * * @param updateInterval * location update time in milliseconds * @param accuracy * accuracy for positioning (suggested value would be starting from * 500) */ public LocationAPIProvider(final long updateInterval, final int accuracy) { this.accuracy = accuracy; this.updateInterval = (int) (updateInterval / 1000); status = STATUS_CONNECTING; } public void start() { final Thread t = new Thread(this); t.start(); } public void run() { criteria = new Criteria(); criteria.setHorizontalAccuracy(accuracy); try { locationProvider = LocationProvider.getInstance(criteria); locationProvider .setLocationListener(this, updateInterval, updateInterval, updateInterval / 2); } catch (final LocationException e) { Log.printStackTrace(e); Log.error("LocationAPIProvider initialization failed: " + e.getMessage()); } } public WgsPoint getLocation() { return wgsLocation; } public int getStatus() { return status; } public LocationMarker getLocationMarker() { return marker; } public void quit() { final Thread t = new Thread() { public void run() { locationProvider.setLocationListener(null, 0, 0, 0); } }; t.start(); marker.quit(); } public void setLocationMarker(final LocationMarker marker) { this.marker = marker; addLocationListener(marker); this.marker.setLocationSource(this); } public void addLocationListener(final LocationListener listener) { final LocationListener[] newListeners = new LocationListener[listeners.length + 1]; System.arraycopy(listeners, 0, newListeners, 0, listeners.length); newListeners[listeners.length] = listener; listeners = newListeners; } public void locationUpdated(final LocationProvider provider, final Location location) { if (provider.getState() != LocationProvider.AVAILABLE) { status = STATUS_CONNECTION_LOST; } else { try { status = STATUS_CONNECTED; wgsLocation = new WgsPoint(location.getQualifiedCoordinates().getLongitude(), location .getQualifiedCoordinates().getLatitude()); for (int i = 0; i < listeners.length; i++) { listeners[i].setLocation(wgsLocation); } } catch (final Exception e) { status = STATUS_CANT_LOCATE; } } } public void providerStateChanged(final LocationProvider provider, final int newState) { if (provider.getState() != LocationProvider.AVAILABLE) { status = STATUS_CONNECTION_LOST; } else { status = STATUS_CONNECTED; } } }