1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.location; 18 19 import android.util.SparseArray; 20 21 import java.util.Iterator; 22 import java.util.NoSuchElementException; 23 24 25 /** 26 * This class represents the current state of the GPS engine. 27 * 28 * <p>This class is used in conjunction with the {@link Listener} interface. 29 * 30 * @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}. 31 */ 32 @Deprecated 33 public final class GpsStatus { 34 private static final int NUM_SATELLITES = 255; 35 private static final int GLONASS_SVID_OFFSET = 64; 36 private static final int BEIDOU_SVID_OFFSET = 200; 37 private static final int SBAS_SVID_OFFSET = -87; 38 39 /* These package private values are modified by the LocationManager class */ 40 private int mTimeToFirstFix; 41 private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>(); 42 43 private final class SatelliteIterator implements Iterator<GpsSatellite> { 44 private final int mSatellitesCount; 45 46 private int mIndex = 0; 47 SatelliteIterator()48 SatelliteIterator() { 49 mSatellitesCount = mSatellites.size(); 50 } 51 52 @Override hasNext()53 public boolean hasNext() { 54 for (; mIndex < mSatellitesCount; ++mIndex) { 55 GpsSatellite satellite = mSatellites.valueAt(mIndex); 56 if (satellite.mValid) { 57 return true; 58 } 59 } 60 return false; 61 } 62 63 @Override next()64 public GpsSatellite next() { 65 while (mIndex < mSatellitesCount) { 66 GpsSatellite satellite = mSatellites.valueAt(mIndex); 67 ++mIndex; 68 if (satellite.mValid) { 69 return satellite; 70 } 71 } 72 throw new NoSuchElementException(); 73 } 74 75 @Override remove()76 public void remove() { 77 throw new UnsupportedOperationException(); 78 } 79 } 80 81 private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() { 82 @Override 83 public Iterator<GpsSatellite> iterator() { 84 return new SatelliteIterator(); 85 } 86 }; 87 88 /** 89 * Event sent when the GPS system has started. 90 */ 91 public static final int GPS_EVENT_STARTED = 1; 92 93 /** 94 * Event sent when the GPS system has stopped. 95 */ 96 public static final int GPS_EVENT_STOPPED = 2; 97 98 /** 99 * Event sent when the GPS system has received its first fix since starting. 100 * Call {@link #getTimeToFirstFix()} to find the time from start to first fix. 101 */ 102 public static final int GPS_EVENT_FIRST_FIX = 3; 103 104 /** 105 * Event sent periodically to report GPS satellite status. 106 * Call {@link #getSatellites()} to retrieve the status for each satellite. 107 */ 108 public static final int GPS_EVENT_SATELLITE_STATUS = 4; 109 110 /** 111 * Used for receiving notifications when GPS status has changed. 112 * @deprecated use {@link GnssStatus.Callback} instead. 113 */ 114 @Deprecated 115 public interface Listener { 116 /** 117 * Called to report changes in the GPS status. 118 * The event number is one of: 119 * <ul> 120 * <li> {@link GpsStatus#GPS_EVENT_STARTED} 121 * <li> {@link GpsStatus#GPS_EVENT_STOPPED} 122 * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX} 123 * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS} 124 * </ul> 125 * 126 * When this method is called, the client should call 127 * {@link LocationManager#getGpsStatus} to get additional 128 * status information. 129 * 130 * @param event event number for this notification 131 */ onGpsStatusChanged(int event)132 void onGpsStatusChanged(int event); 133 } 134 135 /** 136 * Used for receiving NMEA sentences from the GPS. 137 * NMEA 0183 is a standard for communicating with marine electronic devices 138 * and is a common method for receiving data from a GPS, typically over a serial port. 139 * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details. 140 * You can implement this interface and call {@link LocationManager#addNmeaListener} 141 * to receive NMEA data from the GPS engine. 142 * @deprecated use {@link OnNmeaMessageListener} instead. 143 */ 144 @Deprecated 145 public interface NmeaListener { onNmeaReceived(long timestamp, String nmea)146 void onNmeaReceived(long timestamp, String nmea); 147 } 148 149 // For API-compat a public ctor() is not available GpsStatus()150 GpsStatus() {} 151 setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, float[] azimuths)152 private void setStatus(int svCount, int[] svidWithFlags, float[] cn0s, float[] elevations, 153 float[] azimuths) { 154 clearSatellites(); 155 for (int i = 0; i < svCount; i++) { 156 final int constellationType = 157 (svidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH) 158 & GnssStatus.CONSTELLATION_TYPE_MASK; 159 int prn = svidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH; 160 // Other satellites passed through these APIs before GnssSvStatus was availble. 161 // GPS, SBAS & QZSS can pass through at their nominally 162 // assigned prn number (as long as it fits in the valid 0-255 range below.) 163 // Glonass, and Beidou are passed through with the defacto standard offsets 164 // Other future constellation reporting (e.g. Galileo) needs to use 165 // GnssSvStatus on (N level) HAL & Java layers. 166 if (constellationType == GnssStatus.CONSTELLATION_GLONASS) { 167 prn += GLONASS_SVID_OFFSET; 168 } else if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) { 169 prn += BEIDOU_SVID_OFFSET; 170 } else if (constellationType == GnssStatus.CONSTELLATION_SBAS) { 171 prn += SBAS_SVID_OFFSET; 172 } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) && 173 (constellationType != GnssStatus.CONSTELLATION_QZSS)) { 174 continue; 175 } 176 if (prn > 0 && prn <= NUM_SATELLITES) { 177 GpsSatellite satellite = mSatellites.get(prn); 178 if (satellite == null) { 179 satellite = new GpsSatellite(prn); 180 mSatellites.put(prn, satellite); 181 } 182 183 satellite.mValid = true; 184 satellite.mSnr = cn0s[i]; 185 satellite.mElevation = elevations[i]; 186 satellite.mAzimuth = azimuths[i]; 187 satellite.mHasEphemeris = 188 (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) != 0; 189 satellite.mHasAlmanac = 190 (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) != 0; 191 satellite.mUsedInFix = 192 (svidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0; 193 } 194 } 195 } 196 197 /** 198 * Copies GPS satellites information from GnssStatus object. 199 * Since this method is only used within {@link LocationManager#getGpsStatus}, 200 * it does not need to be synchronized. 201 * @hide 202 */ setStatus(GnssStatus status, int timeToFirstFix)203 void setStatus(GnssStatus status, int timeToFirstFix) { 204 mTimeToFirstFix = timeToFirstFix; 205 setStatus(status.mSvCount, status.mSvidWithFlags, status.mCn0DbHz, status.mElevations, 206 status.mAzimuths); 207 } 208 setTimeToFirstFix(int ttff)209 void setTimeToFirstFix(int ttff) { 210 mTimeToFirstFix = ttff; 211 } 212 213 /** 214 * Returns the time required to receive the first fix since the most recent 215 * restart of the GPS engine. 216 * 217 * @return time to first fix in milliseconds 218 */ getTimeToFirstFix()219 public int getTimeToFirstFix() { 220 return mTimeToFirstFix; 221 } 222 223 /** 224 * Returns an array of {@link GpsSatellite} objects, which represent the 225 * current state of the GPS engine. 226 * 227 * @return the list of satellites 228 */ getSatellites()229 public Iterable<GpsSatellite> getSatellites() { 230 return mSatelliteList; 231 } 232 233 /** 234 * Returns the maximum number of satellites that can be in the satellite 235 * list that can be returned by {@link #getSatellites()}. 236 * 237 * @return the maximum number of satellites 238 */ getMaxSatellites()239 public int getMaxSatellites() { 240 return NUM_SATELLITES; 241 } 242 clearSatellites()243 private void clearSatellites() { 244 int satellitesCount = mSatellites.size(); 245 for (int i = 0; i < satellitesCount; i++) { 246 GpsSatellite satellite = mSatellites.valueAt(i); 247 satellite.mValid = false; 248 } 249 } 250 } 251