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.annotation.NonNull; 20 import android.util.SparseArray; 21 22 import java.util.Iterator; 23 import java.util.NoSuchElementException; 24 25 26 /** 27 * This class represents the current state of the GPS engine and is used in conjunction with {@link 28 * GpsStatus.Listener}. 29 * 30 * @deprecated Use {@link GnssStatus} instead. 31 */ 32 @Deprecated 33 public final class GpsStatus { 34 private static final int MAX_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 private int mTimeToFirstFix; 40 private final SparseArray<GpsSatellite> mSatellites = new SparseArray<>(); 41 42 private final class SatelliteIterator implements Iterator<GpsSatellite> { 43 private final int mSatellitesCount; 44 45 private int mIndex = 0; 46 SatelliteIterator()47 SatelliteIterator() { 48 mSatellitesCount = mSatellites.size(); 49 } 50 51 @Override hasNext()52 public boolean hasNext() { 53 for (; mIndex < mSatellitesCount; ++mIndex) { 54 GpsSatellite satellite = mSatellites.valueAt(mIndex); 55 if (satellite.mValid) { 56 return true; 57 } 58 } 59 return false; 60 } 61 62 @Override next()63 public GpsSatellite next() { 64 while (mIndex < mSatellitesCount) { 65 GpsSatellite satellite = mSatellites.valueAt(mIndex); 66 ++mIndex; 67 if (satellite.mValid) { 68 return satellite; 69 } 70 } 71 throw new NoSuchElementException(); 72 } 73 74 @Override remove()75 public void remove() { 76 throw new UnsupportedOperationException(); 77 } 78 } 79 80 private Iterable<GpsSatellite> mSatelliteList = SatelliteIterator::new; 81 82 /** 83 * Event sent when the GPS system has started. 84 */ 85 public static final int GPS_EVENT_STARTED = 1; 86 87 /** 88 * Event sent when the GPS system has stopped. 89 */ 90 public static final int GPS_EVENT_STOPPED = 2; 91 92 /** 93 * Event sent when the GPS system has received its first fix since starting. 94 * Call {@link #getTimeToFirstFix()} to find the time from start to first fix. 95 */ 96 public static final int GPS_EVENT_FIRST_FIX = 3; 97 98 /** 99 * Event sent periodically to report GPS satellite status. 100 * Call {@link #getSatellites()} to retrieve the status for each satellite. 101 */ 102 public static final int GPS_EVENT_SATELLITE_STATUS = 4; 103 104 /** 105 * Used for receiving notifications when GPS status has changed. 106 * 107 * @deprecated Use {@link GnssStatus.Callback} instead. 108 */ 109 @Deprecated 110 public interface Listener { 111 /** 112 * Called to report changes in the GPS status. 113 * The event number is one of: 114 * <ul> 115 * <li> {@link GpsStatus#GPS_EVENT_STARTED} 116 * <li> {@link GpsStatus#GPS_EVENT_STOPPED} 117 * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX} 118 * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS} 119 * </ul> 120 * 121 * When this method is called, the client should call 122 * {@link LocationManager#getGpsStatus} to get additional 123 * status information. 124 * 125 * @param event event number for this notification 126 */ onGpsStatusChanged(int event)127 void onGpsStatusChanged(int event); 128 } 129 130 /** 131 * Used for receiving NMEA sentences from the GPS. 132 * NMEA 0183 is a standard for communicating with marine electronic devices 133 * and is a common method for receiving data from a GPS, typically over a serial port. 134 * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details. 135 * You can implement this interface and call {@link LocationManager#addNmeaListener} 136 * to receive NMEA data from the GPS engine. 137 * @deprecated use {@link OnNmeaMessageListener} instead. 138 */ 139 @Deprecated 140 public interface NmeaListener { onNmeaReceived(long timestamp, String nmea)141 void onNmeaReceived(long timestamp, String nmea); 142 } 143 144 /** 145 * Builds a GpsStatus from the given GnssStatus. 146 */ 147 @NonNull create(@onNull GnssStatus gnssStatus, int timeToFirstFix)148 public static GpsStatus create(@NonNull GnssStatus gnssStatus, int timeToFirstFix) { 149 GpsStatus status = new GpsStatus(); 150 status.setStatus(gnssStatus, timeToFirstFix); 151 return status; 152 } 153 154 /** 155 * Builds an empty GpsStatus. Should only be used for legacy reasons. 156 * 157 * @hide 158 */ 159 @NonNull createEmpty()160 static GpsStatus createEmpty() { 161 return new GpsStatus(); 162 } 163 GpsStatus()164 private GpsStatus() { 165 } 166 167 /** 168 * @hide 169 */ setStatus(GnssStatus status, int timeToFirstFix)170 void setStatus(GnssStatus status, int timeToFirstFix) { 171 for (int i = 0; i < mSatellites.size(); i++) { 172 mSatellites.valueAt(i).mValid = false; 173 } 174 175 mTimeToFirstFix = timeToFirstFix; 176 for (int i = 0; i < status.getSatelliteCount(); i++) { 177 int constellationType = status.getConstellationType(i); 178 int prn = status.getSvid(i); 179 // Other satellites passed through these APIs before GnssSvStatus was availble. 180 // GPS, SBAS & QZSS can pass through at their nominally 181 // assigned prn number (as long as it fits in the valid 0-255 range below.) 182 // Glonass, and Beidou are passed through with the defacto standard offsets 183 // Other future constellation reporting (e.g. Galileo) needs to use 184 // GnssSvStatus on (N level) HAL & Java layers. 185 if (constellationType == GnssStatus.CONSTELLATION_GLONASS) { 186 prn += GLONASS_SVID_OFFSET; 187 } else if (constellationType == GnssStatus.CONSTELLATION_BEIDOU) { 188 prn += BEIDOU_SVID_OFFSET; 189 } else if (constellationType == GnssStatus.CONSTELLATION_SBAS) { 190 prn += SBAS_SVID_OFFSET; 191 } else if ((constellationType != GnssStatus.CONSTELLATION_GPS) && 192 (constellationType != GnssStatus.CONSTELLATION_QZSS)) { 193 continue; 194 } 195 if (prn <= 0 || prn > MAX_SATELLITES) { 196 continue; 197 } 198 199 GpsSatellite satellite = mSatellites.get(prn); 200 if (satellite == null) { 201 satellite = new GpsSatellite(prn); 202 mSatellites.put(prn, satellite); 203 } 204 205 satellite.mValid = true; 206 satellite.mSnr = status.getCn0DbHz(i); 207 satellite.mElevation = status.getElevationDegrees(i); 208 satellite.mAzimuth = status.getAzimuthDegrees(i); 209 satellite.mHasEphemeris = status.hasEphemerisData(i); 210 satellite.mHasAlmanac = status.hasAlmanacData(i); 211 satellite.mUsedInFix = status.usedInFix(i); 212 } 213 } 214 215 /** 216 * Returns the time required to receive the first fix since the most recent 217 * restart of the GPS engine. 218 * 219 * @return time to first fix in milliseconds 220 */ getTimeToFirstFix()221 public int getTimeToFirstFix() { 222 return mTimeToFirstFix; 223 } 224 225 /** 226 * Returns an array of {@link GpsSatellite} objects, which represent the 227 * current state of the GPS engine. 228 * 229 * @return the list of satellites 230 */ getSatellites()231 public Iterable<GpsSatellite> getSatellites() { 232 return mSatelliteList; 233 } 234 235 /** 236 * Returns the maximum number of satellites that can be in the satellite 237 * list that can be returned by {@link #getSatellites()}. 238 * 239 * @return the maximum number of satellites 240 */ getMaxSatellites()241 public int getMaxSatellites() { 242 return mSatellites.size(); 243 } 244 245 } 246