diff options
Diffstat (limited to 'location/java/android')
-rw-r--r-- | location/java/android/location/Geocoder.java | 2 | ||||
-rw-r--r-- | location/java/android/location/GpsSatellite.java | 117 | ||||
-rw-r--r-- | location/java/android/location/GpsStatus.java | 200 | ||||
-rw-r--r-- | location/java/android/location/GpsStatusListener.java | 58 | ||||
-rw-r--r-- | location/java/android/location/ILocationManager.aidl | 3 | ||||
-rw-r--r-- | location/java/android/location/LocationManager.java | 265 |
6 files changed, 498 insertions, 147 deletions
diff --git a/location/java/android/location/Geocoder.java b/location/java/android/location/Geocoder.java index 92a19e4..709ad23 100644 --- a/location/java/android/location/Geocoder.java +++ b/location/java/android/location/Geocoder.java @@ -228,7 +228,7 @@ public final class Geocoder { ArrayList<Address> result = new ArrayList<Address>(); String ex = mService.getFromLocationName(locationName, lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude, - maxResults, mLanguage, mCountry, mVariant, mAppName, new ArrayList<Address>()); + maxResults, mLanguage, mCountry, mVariant, mAppName, result); if (ex != null) { throw new IOException(ex); } else { diff --git a/location/java/android/location/GpsSatellite.java b/location/java/android/location/GpsSatellite.java new file mode 100644 index 0000000..17af4a6 --- /dev/null +++ b/location/java/android/location/GpsSatellite.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * 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 android.location; + +/** + * This class represents the current state of a GPS satellite. + * This class is used in conjunction with the {@link GpsStatus} class. + */ +public final class GpsSatellite { + /* These package private values are modified by the GpsStatus class */ + boolean mValid; + boolean mHasEphemeris; + boolean mHasAlmanac; + boolean mUsedInFix; + int mPrn; + float mSnr; + float mElevation; + float mAzimuth; + + GpsSatellite(int prn) { + mPrn = prn; + } + + /** + * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's + * cached GpsStatus instance to the client's copy. + */ + void setStatus(GpsSatellite satellite) { + mValid = satellite.mValid; + mHasEphemeris = satellite.mHasEphemeris; + mHasAlmanac = satellite.mHasAlmanac; + mUsedInFix = satellite.mUsedInFix; + mSnr = satellite.mSnr; + mElevation = satellite.mElevation; + mAzimuth = satellite.mAzimuth; + } + + /** + * Returns the PRN (pseudo-random number) for the satellite. + * + * @return PRN number + */ + public int getPrn() { + return mPrn; + } + + /** + * Returns the signal to noise ratio for the satellite. + * + * @return the signal to noise ratio + */ + public float getSnr() { + return mSnr; + } + + /** + * Returns the elevation of the satellite in degrees. + * The elevation can vary between 0 and 90. + * + * @return the elevation in degrees + */ + public float getElevation() { + return mElevation; + } + + /** + * Returns the azimuth of the satellite in degrees. + * The azimuth can vary between 0 and 360. + * + * @return the azimuth in degrees + */ + public float getAzimuth() { + return mAzimuth; + } + + /** + * Returns true if the GPS engine has ephemeris data for the satellite. + * + * @return true if the satellite has ephemeris data + */ + public boolean hasEphemeris() { + return mHasEphemeris; + } + + /** + * Returns true if the GPS engine has almanac data for the satellite. + * + * @return true if the satellite has almanac data + */ + public boolean hasAlmanac() { + return mHasAlmanac; + } + + /** + * Returns true if the satellite was used by the GPS engine when + * calculating the most recent GPS fix. + * + * @return true if the satellite was used to compute the most recent fix. + */ + public boolean usedInFix() { + return mUsedInFix; + } +} diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java new file mode 100644 index 0000000..a40b1fb --- /dev/null +++ b/location/java/android/location/GpsStatus.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * 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 android.location; + +import java.util.Iterator; +import java.util.NoSuchElementException; + + +/** + * This class represents the current state of the GPS engine. + * This class is used in conjunction with the {@link Listener} interface. + */ +public final class GpsStatus { + private static final int NUM_SATELLITES = 32; + + /* These package private values are modified by the LocationManager class */ + private int mTimeToFirstFix; + private GpsSatellite mSatellites[] = new GpsSatellite[NUM_SATELLITES]; + + private final class SatelliteIterator implements Iterator<GpsSatellite> { + + private GpsSatellite[] mSatellites; + int mIndex = 0; + + SatelliteIterator(GpsSatellite[] satellites) { + mSatellites = satellites; + } + + public boolean hasNext() { + for (int i = mIndex; i < mSatellites.length; i++) { + if (mSatellites[i].mValid) { + return true; + } + } + return false; + } + + public GpsSatellite next() { + while (mIndex < mSatellites.length) { + GpsSatellite satellite = mSatellites[mIndex++]; + if (satellite.mValid) { + return satellite; + } + } + throw new NoSuchElementException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() { + public Iterator<GpsSatellite> iterator() { + return new SatelliteIterator(mSatellites); + } + }; + + /** + * Event sent when the GPS system has started. + */ + public static final int GPS_EVENT_STARTED = 1; + + /** + * Event sent when the GPS system has stopped. + */ + public static final int GPS_EVENT_STOPPED = 2; + + /** + * Event sent when the GPS system has received its first fix since starting. + * Call {@link #getTimeToFirstFix()} to find the time from start to first fix. + */ + public static final int GPS_EVENT_FIRST_FIX = 3; + + /** + * Event sent periodically to report GPS satellite status. + * Call {@link #getSatellites()} to retrieve the status for each satellite. + */ + public static final int GPS_EVENT_SATELLITE_STATUS = 4; + + /** + * Used for receiving notifications when GPS status has changed. + */ + public interface Listener { + /** + * Called to report changes in the GPS status. + * The event number is one of: + * <ul> + * <li> {@link GpsStatus#GPS_EVENT_STARTED} + * <li> {@link GpsStatus#GPS_EVENT_STOPPED} + * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX} + * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS} + * </ul> + * + * When this method is called, the client should call + * {@link LocationManager#getGpsStatus} to get additional + * status information. + * + * @param event event number for this notification + */ + void onGpsStatusChanged(int event); + } + + GpsStatus() { + for (int i = 0; i < mSatellites.length; i++) { + mSatellites[i] = new GpsSatellite(i + 1); + } + } + + /** + * Used internally within {@link LocationManager} to copy GPS status + * data from the Location Manager Service to its cached GpsStatus instance. + * Is synchronized to ensure that GPS status updates are atomic. + */ + synchronized void setStatus(int svCount, int[] prns, float[] snrs, + float[] elevations, float[] azimuths, int ephemerisMask, + int almanacMask, int usedInFixMask) { + int i; + + for (i = 0; i < mSatellites.length; i++) { + mSatellites[i].mValid = false; + } + + for (i = 0; i < svCount; i++) { + int prn = prns[i] - 1; + int prnShift = (1 << prn); + GpsSatellite satellite = mSatellites[prn]; + + satellite.mValid = true; + satellite.mSnr = snrs[i]; + satellite.mElevation = elevations[i]; + satellite.mAzimuth = azimuths[i]; + satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0); + satellite.mHasAlmanac = ((almanacMask & prnShift) != 0); + satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0); + } + } + + /** + * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's + * cached GpsStatus instance to the client's copy. + * Since this method is only used within {@link LocationManager#getGpsStatus}, + * it does not need to be synchronized. + */ + void setStatus(GpsStatus status) { + mTimeToFirstFix = status.getTimeToFirstFix(); + + for (int i = 0; i < mSatellites.length; i++) { + mSatellites[i].setStatus(status.mSatellites[i]); + } + } + + void setTimeToFirstFix(int ttff) { + mTimeToFirstFix = ttff; + } + + /** + * Returns the time required to receive the first fix since the most recent + * restart of the GPS engine. + * + * @return time to first fix in milliseconds + */ + public int getTimeToFirstFix() { + return mTimeToFirstFix; + } + + /** + * Returns an array of {@link GpsSatellite} objects, which represent the + * current state of the GPS engine. + * + * @return the list of satellites + */ + public Iterable<GpsSatellite> getSatellites() { + return mSatelliteList; + } + + /** + * Returns the maximum number of satellites that can be in the satellite + * list that can be returned by {@link #getSatellites()}. + * + * @return the maximum number of satellites + */ + public int getMaxSatellites() { + return NUM_SATELLITES; + } +} diff --git a/location/java/android/location/GpsStatusListener.java b/location/java/android/location/GpsStatusListener.java deleted file mode 100644 index e494887..0000000 --- a/location/java/android/location/GpsStatusListener.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * 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 android.location; - -/** - * Used for receiving notifications from the SensorManager when - * sensor values have changed. - * - * @hide - */ -public interface GpsStatusListener { - - /** - * Called when the GPS has started. - */ - void onGpsStarted(); - - /** - * Called when the GPS has stopped. - */ - void onGpsStopped(); - - /** - * Called when the GPS status has received its first fix since starting. - * - * @param ttff Time to first fix in milliseconds. - */ - void onFirstFix(int ttff); - - /** - * Called when the GPS SV status has changed. - * - * @param svCount The number of visible SVs - * @param prns Array of SV prns. Length of array is svCount. - * @param snrs Array of signal to noise ratios for SVs, in 1/10 dB units. Length of array is svCount. - * @param elevations Array of SV elevations in degrees. Length of array is svCount. - * @param azimuths Array of SV azimuths in degrees. Length of array is svCount. - * @param ephemerisMask Bit mask indicating which SVs the GPS has ephemeris data for. - * @param almanacMask Bit mask indicating which SVs the GPS has almanac data for. - * @param usedInFixMask Bit mask indicating which SVs were used in the most recent GPS fix. - */ - public void onSvStatusChanged(int svCount, int[] prns, float[] snrs, float[] elevations, - float[] azimuths, int ephemerisMask, int almanacMask, int usedInFixMask); -} diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl index d3eefeb..69c404a 100644 --- a/location/java/android/location/ILocationManager.aidl +++ b/location/java/android/location/ILocationManager.aidl @@ -37,7 +37,10 @@ interface ILocationManager void requestLocationUpdates(String provider, long minTime, float minDistance, in ILocationListener listener); + void requestLocationUpdatesPI(String provider, long minTime, float minDistance, + in PendingIntent intent); void removeUpdates(in ILocationListener listener); + void removeUpdatesPI(in PendingIntent intent); boolean addGpsStatusListener(IGpsStatusListener listener); void removeGpsStatusListener(IGpsStatusListener listener); diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java index b5adb33..022ee25 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -47,8 +47,9 @@ import java.util.List; public class LocationManager { private static final String TAG = "LocationManager"; private ILocationManager mService; - private HashMap<GpsStatusListener, GpsStatusListenerTransport> mGpsStatusListeners = - new HashMap<GpsStatusListener, GpsStatusListenerTransport>(); + private final HashMap<GpsStatus.Listener, GpsStatusListenerTransport> mGpsStatusListeners = + new HashMap<GpsStatus.Listener, GpsStatusListenerTransport>(); + private final GpsStatus mGpsStatus = new GpsStatus(); /** * Name of the network location provider. This provider determines location based on @@ -82,6 +83,24 @@ public class LocationManager { */ public static final String KEY_PROXIMITY_ENTERING = "entering"; + /** + * Key used for a Bundle extra holding an Integer status value + * when a status change is broadcast using a PendingIntent. + */ + public static final String KEY_STATUS_CHANGED = "status"; + + /** + * Key used for a Bundle extra holding an Boolean status value + * when a provider enabled/disabled event is broadcast using a PendingIntent. + */ + public static final String KEY_PROVIDER_ENABLED = "providerEnabled"; + + /** + * Key used for a Bundle extra holding a Location value + * when a location change is broadcast using a PendingIntent. + */ + public static final String KEY_LOCATION_CHANGED = "location"; + /** @hide -- does this belong here? */ public static final String PROVIDER_DIR = "/data/location"; @@ -180,7 +199,7 @@ public class LocationManager { /** * @hide - hide this constructor because it has a parameter * of type ILocationManager, which is a system private class. The - * right way to create an instance of this class is using the + * right way to create an instance of this class is using the * factory Context.getSystemService. */ public LocationManager(ILocationManager service) { @@ -686,11 +705,9 @@ public class LocationManager { ListenerTransport transport = mListeners.get(listener); if (transport == null) { transport = new ListenerTransport(listener, looper); - mListeners.put(listener, transport); } mListeners.put(listener, transport); - mService.requestLocationUpdates(provider, minTime, minDistance, - transport); + mService.requestLocationUpdates(provider, minTime, minDistance, transport); } } catch (RemoteException ex) { Log.e(TAG, "requestLocationUpdates: DeadObjectException", ex); @@ -698,6 +715,78 @@ public class LocationManager { } /** + * Registers the current activity to be notified periodically by + * the named provider. Periodically, the supplied PendingIntent will + * be broadcast with the current Location or with status updates. + * + * <p> Location updates are sent with a key of KEY_LOCATION_CHANGED and a Location value. + * + * <p> It may take a while to receive the most recent location. If + * an immediate location is required, applications may use the + * {@link #getLastKnownLocation(String)} method. + * + * <p> The frequency of notification or new locations may be controlled using the + * minTime and minDistance parameters. If minTime is greater than 0, + * the LocationManager could potentially rest for minTime milliseconds + * between location updates to conserve power. If minDistance is greater than 0, + * a location will only be broadcast if the device moves by minDistance meters. + * To obtain notifications as frequently as possible, set both parameters to 0. + * + * <p> Background services should be careful about setting a sufficiently high + * minTime so that the device doesn't consume too much power by keeping the + * GPS or wireless radios on all the time. In particular, values under 60000ms + * are not recommended. + * + * <p> In case the provider is disabled by the user, updates will stop, + * and an intent will be sent with an extra with key KEY_PROVIDER_ENABLED and a boolean value + * of false. If the provider is re-enabled, an intent will be sent with an + * extra with key KEY_PROVIDER_ENABLED and a boolean value of true and location updates will + * start again. + * + * <p> If the provider's status changes, an intent will be sent with an extra with key + * KEY_STATUS_CHANGED and an integer value indicating the new status. Any extras associated + * with the status update will be sent as well. + * + * @param provider the name of the provider with which to register + * @param minTime the minimum time interval for notifications, in + * milliseconds. This field is only used as a hint to conserve power, and actual + * time between location updates may be greater or lesser than this value. + * @param minDistance the minimum distance interval for notifications, + * in meters + * @param intent a {#link PendingIntet} to be sent for each location update + * + * @throws IllegalArgumentException if provider is null or doesn't exist + * @throws IllegalArgumentException if intent is null + * @throws SecurityException if no suitable permission is present for the provider. + */ + public void requestLocationUpdates(String provider, + long minTime, float minDistance, PendingIntent intent) { + if (provider == null) { + throw new IllegalArgumentException("provider==null"); + } + if (intent == null) { + throw new IllegalArgumentException("intent==null"); + } + _requestLocationUpdates(provider, minTime, minDistance, intent); + } + + private void _requestLocationUpdates(String provider, + long minTime, float minDistance, PendingIntent intent) { + if (minTime < 0L) { + minTime = 0L; + } + if (minDistance < 0.0f) { + minDistance = 0.0f; + } + + try { + mService.requestLocationUpdatesPI(provider, minTime, minDistance, intent); + } catch (RemoteException ex) { + Log.e(TAG, "requestLocationUpdates: RemoteException", ex); + } + } + + /** * Removes any current registration for location updates of the current activity * with the given LocationListener. Following this call, updates will no longer * occur for this listener. @@ -723,6 +812,28 @@ public class LocationManager { } /** + * Removes any current registration for location updates of the current activity + * with the given PendingIntent. Following this call, updates will no longer + * occur for this intent. + * + * @param intent {#link PendingIntent} object that no longer needs location updates + * @throws IllegalArgumentException if intent is null + */ + public void removeUpdates(PendingIntent intent) { + if (intent == null) { + throw new IllegalArgumentException("intent==null"); + } + if (Config.LOGD) { + Log.d(TAG, "removeUpdates: intent = " + intent); + } + try { + mService.removeUpdatesPI(intent); + } catch (RemoteException ex) { + Log.e(TAG, "removeUpdates: RemoteException", ex); + } + } + + /** * Sets a proximity alert for the location given by the position * (latitude, longitude) and the given radius. When the device * detects that it has entered or exited the area surrounding the @@ -865,9 +976,9 @@ public class LocationManager { * @param accuracy * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION} system setting is not enabled * @throws IllegalArgumentException if a provider with the given name already exists - * - * {@hide} */ public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, @@ -887,9 +998,9 @@ public class LocationManager { * @param provider the provider name * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void removeTestProvider(String provider) { try { @@ -907,9 +1018,9 @@ public class LocationManager { * @param loc the mock location * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void setTestProviderLocation(String provider, Location loc) { try { @@ -925,9 +1036,9 @@ public class LocationManager { * @param provider the provider name * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void clearTestProviderLocation(String provider) { try { @@ -945,9 +1056,9 @@ public class LocationManager { * @param enabled the mock enabled value * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void setTestProviderEnabled(String provider, boolean enabled) { try { @@ -963,9 +1074,9 @@ public class LocationManager { * @param provider the provider name * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void clearTestProviderEnabled(String provider) { try { @@ -986,9 +1097,9 @@ public class LocationManager { * @param updateTime the mock update time * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { try { @@ -1004,9 +1115,9 @@ public class LocationManager { * @param provider the provider name * * @throws SecurityException if the ACCESS_MOCK_LOCATION permission is not present + * or the {@link android.provider.Settings.Secure#ALLOW_MOCK_LOCATION + * Settings.Secure.ALLOW_MOCK_LOCATION}} system setting is not enabled * @throws IllegalArgumentException if no provider with the given name exists - * - * {@hide} */ public void clearTestProviderStatus(String provider) { try { @@ -1021,102 +1132,65 @@ public class LocationManager { // This class is used to send GPS status events to the client's main thread. private class GpsStatusListenerTransport extends IGpsStatusListener.Stub { - private GpsStatusListener mListener; - private int mTTFF; - private int mSvCount; - private int[] mPrns; - private float[] mSnrs; - private float[] mElevations; - private float[] mAzimuths; - private int mEphemerisMask; - private int mAlmanacMask; - private int mUsedInFixMask; - - private static final int GPS_STARTED = 0; - private static final int GPS_STOPPED = 1; - private static final int GPS_FIRST_FIX = 2; - private static final int GPS_SV_STATUS = 3; - - GpsStatusListenerTransport(GpsStatusListener listener) { + private final GpsStatus.Listener mListener; + + GpsStatusListenerTransport(GpsStatus.Listener listener) { mListener = listener; } public void onGpsStarted() { Message msg = Message.obtain(); - msg.what = GPS_STARTED; + msg.what = GpsStatus.GPS_EVENT_STARTED; mGpsHandler.sendMessage(msg); } public void onGpsStopped() { Message msg = Message.obtain(); - msg.what = GPS_STOPPED; + msg.what = GpsStatus.GPS_EVENT_STOPPED; mGpsHandler.sendMessage(msg); } public void onFirstFix(int ttff) { - mTTFF = ttff; + mGpsStatus.setTimeToFirstFix(ttff); Message msg = Message.obtain(); - msg.what = GPS_FIRST_FIX; + msg.what = GpsStatus.GPS_EVENT_FIRST_FIX; mGpsHandler.sendMessage(msg); } public void onSvStatusChanged(int svCount, int[] prns, float[] snrs, float[] elevations, float[] azimuths, int ephemerisMask, int almanacMask, int usedInFixMask) { - // synchronize here to ensure SV count matches data in the arrays - synchronized(this) { - mSvCount = svCount; - mPrns = prns; - mSnrs = snrs; - mElevations = elevations; - mAzimuths = azimuths; - mEphemerisMask = ephemerisMask; - mAlmanacMask = almanacMask; - mUsedInFixMask = usedInFixMask; - } + mGpsStatus.setStatus(svCount, prns, snrs, elevations, azimuths, + ephemerisMask, almanacMask, usedInFixMask); Message msg = Message.obtain(); - msg.what = GPS_SV_STATUS; + msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS; // remove any SV status messages already in the queue - mGpsHandler.removeMessages(GPS_SV_STATUS); + mGpsHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS); mGpsHandler.sendMessage(msg); } private final Handler mGpsHandler = new Handler() { @Override public void handleMessage(Message msg) { - switch (msg.what) { - case GPS_STARTED: - mListener.onGpsStarted(); - break; - case GPS_STOPPED: - mListener.onGpsStopped(); - break; - case GPS_FIRST_FIX: - mListener.onFirstFix(mTTFF); - break; - case GPS_SV_STATUS: - // synchronize here to ensure SV count matches data in the arrays - synchronized(this) { - mListener.onSvStatusChanged(mSvCount, mPrns, mSnrs, mElevations, - mAzimuths, mEphemerisMask, mAlmanacMask, mUsedInFixMask); - break; - } + // synchronize on mGpsStatus to ensure the data is copied atomically. + synchronized(mGpsStatus) { + mListener.onGpsStatusChanged(msg.what); } } }; } /** - * Registers a GPS status listener. + * Adds a GPS status listener. * - * @param listener GPS status listener object to register. + * @param listener GPS status listener object to register * - * @return true if the listener was successfully registered. - * - * {@hide} + * @return true if the listener was successfully added + * + * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present */ - public boolean registerGpsStatusListener(GpsStatusListener listener) { + public boolean addGpsStatusListener(GpsStatus.Listener listener) { boolean result; if (mGpsStatusListeners.get(listener) != null) { @@ -1138,13 +1212,11 @@ public class LocationManager { } /** - * Unegisters a GPS status listener. - * - * @param listener GPS status listener object to unregister. + * Removes a GPS status listener. * - * {@hide} + * @param listener GPS status listener object to remove */ - public void unregisterGpsStatusListener(GpsStatusListener listener) { + public void removeGpsStatusListener(GpsStatus.Listener listener) { try { GpsStatusListenerTransport transport = mGpsStatusListeners.remove(listener); if (transport != null) { @@ -1154,7 +1226,26 @@ public class LocationManager { Log.e(TAG, "RemoteException in unregisterGpsStatusListener: ", e); } } - + + /** + * Retrieves information about the current status of the GPS engine. + * This should only be called from the {@link GpsStatus.Listener#onGpsStatusChanged} + * callback to ensure that the data is copied atomically. + * + * The caller may either pass in a {@link GpsStatus} object to set with the latest + * status information, or pass null to create a new {@link GpsStatus} object. + * + * @param status object containing GPS status details, or null. + * @return status object containing updated GPS status. + */ + public GpsStatus getGpsStatus(GpsStatus status) { + if (status == null) { + status = new GpsStatus(); + } + status.setStatus(mGpsStatus); + return status; + } + /** * Sends additional commands to a location provider. * Can be used to support provider specific extensions to the Location Manager API @@ -1164,9 +1255,7 @@ public class LocationManager { * @param extras optional arguments for the command (or null). * The provider may optionally fill the extras Bundle with results from the command. * - * @return true if the command succeeds. - * - * {@hide} + * @return true if the command succeeds. */ public boolean sendExtraCommand(String provider, String command, Bundle extras) { try { |