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 java.util.Iterator; 20 import java.util.NoSuchElementException; 21 22 23 /** 24 * This class represents the current state of the GPS engine. 25 * This class is used in conjunction with the {@link Listener} interface. 26 */ 27 public final class GpsStatus { 28 private static final int NUM_SATELLITES = 255; 29 30 /* These package private values are modified by the LocationManager class */ 31 private int mTimeToFirstFix; 32 private GpsSatellite mSatellites[] = new GpsSatellite[NUM_SATELLITES]; 33 34 private final class SatelliteIterator implements Iterator<GpsSatellite> { 35 36 private GpsSatellite[] mSatellites; 37 int mIndex = 0; 38 SatelliteIterator(GpsSatellite[] satellites)39 SatelliteIterator(GpsSatellite[] satellites) { 40 mSatellites = satellites; 41 } 42 hasNext()43 public boolean hasNext() { 44 for (int i = mIndex; i < mSatellites.length; i++) { 45 if (mSatellites[i].mValid) { 46 return true; 47 } 48 } 49 return false; 50 } 51 next()52 public GpsSatellite next() { 53 while (mIndex < mSatellites.length) { 54 GpsSatellite satellite = mSatellites[mIndex++]; 55 if (satellite.mValid) { 56 return satellite; 57 } 58 } 59 throw new NoSuchElementException(); 60 } 61 remove()62 public void remove() { 63 throw new UnsupportedOperationException(); 64 } 65 } 66 67 private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() { 68 public Iterator<GpsSatellite> iterator() { 69 return new SatelliteIterator(mSatellites); 70 } 71 }; 72 73 /** 74 * Event sent when the GPS system has started. 75 */ 76 public static final int GPS_EVENT_STARTED = 1; 77 78 /** 79 * Event sent when the GPS system has stopped. 80 */ 81 public static final int GPS_EVENT_STOPPED = 2; 82 83 /** 84 * Event sent when the GPS system has received its first fix since starting. 85 * Call {@link #getTimeToFirstFix()} to find the time from start to first fix. 86 */ 87 public static final int GPS_EVENT_FIRST_FIX = 3; 88 89 /** 90 * Event sent periodically to report GPS satellite status. 91 * Call {@link #getSatellites()} to retrieve the status for each satellite. 92 */ 93 public static final int GPS_EVENT_SATELLITE_STATUS = 4; 94 95 /** 96 * Used for receiving notifications when GPS status has changed. 97 */ 98 public interface Listener { 99 /** 100 * Called to report changes in the GPS status. 101 * The event number is one of: 102 * <ul> 103 * <li> {@link GpsStatus#GPS_EVENT_STARTED} 104 * <li> {@link GpsStatus#GPS_EVENT_STOPPED} 105 * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX} 106 * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS} 107 * </ul> 108 * 109 * When this method is called, the client should call 110 * {@link LocationManager#getGpsStatus} to get additional 111 * status information. 112 * 113 * @param event event number for this notification 114 */ onGpsStatusChanged(int event)115 void onGpsStatusChanged(int event); 116 } 117 118 /** 119 * Used for receiving NMEA sentences from the GPS. 120 * NMEA 0183 is a standard for communicating with marine electronic devices 121 * and is a common method for receiving data from a GPS, typically over a serial port. 122 * See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details. 123 * You can implement this interface and call {@link LocationManager#addNmeaListener} 124 * to receive NMEA data from the GPS engine. 125 */ 126 public interface NmeaListener { onNmeaReceived(long timestamp, String nmea)127 void onNmeaReceived(long timestamp, String nmea); 128 } 129 GpsStatus()130 GpsStatus() { 131 for (int i = 0; i < mSatellites.length; i++) { 132 mSatellites[i] = new GpsSatellite(i + 1); 133 } 134 } 135 136 /** 137 * Used internally within {@link LocationManager} to copy GPS status 138 * data from the Location Manager Service to its cached GpsStatus instance. 139 * Is synchronized to ensure that GPS status updates are atomic. 140 */ setStatus(int svCount, int[] prns, float[] snrs, float[] elevations, float[] azimuths, int ephemerisMask, int almanacMask, int usedInFixMask)141 synchronized void setStatus(int svCount, int[] prns, float[] snrs, 142 float[] elevations, float[] azimuths, int ephemerisMask, 143 int almanacMask, int usedInFixMask) { 144 int i; 145 146 for (i = 0; i < mSatellites.length; i++) { 147 mSatellites[i].mValid = false; 148 } 149 150 for (i = 0; i < svCount; i++) { 151 int prn = prns[i] - 1; 152 int prnShift = (1 << prn); 153 if (prn >= 0 && prn < mSatellites.length) { 154 GpsSatellite satellite = mSatellites[prn]; 155 156 satellite.mValid = true; 157 satellite.mSnr = snrs[i]; 158 satellite.mElevation = elevations[i]; 159 satellite.mAzimuth = azimuths[i]; 160 satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0); 161 satellite.mHasAlmanac = ((almanacMask & prnShift) != 0); 162 satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0); 163 } 164 } 165 } 166 167 /** 168 * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's 169 * cached GpsStatus instance to the client's copy. 170 * Since this method is only used within {@link LocationManager#getGpsStatus}, 171 * it does not need to be synchronized. 172 */ setStatus(GpsStatus status)173 void setStatus(GpsStatus status) { 174 mTimeToFirstFix = status.getTimeToFirstFix(); 175 176 for (int i = 0; i < mSatellites.length; i++) { 177 mSatellites[i].setStatus(status.mSatellites[i]); 178 } 179 } 180 setTimeToFirstFix(int ttff)181 void setTimeToFirstFix(int ttff) { 182 mTimeToFirstFix = ttff; 183 } 184 185 /** 186 * Returns the time required to receive the first fix since the most recent 187 * restart of the GPS engine. 188 * 189 * @return time to first fix in milliseconds 190 */ getTimeToFirstFix()191 public int getTimeToFirstFix() { 192 return mTimeToFirstFix; 193 } 194 195 /** 196 * Returns an array of {@link GpsSatellite} objects, which represent the 197 * current state of the GPS engine. 198 * 199 * @return the list of satellites 200 */ getSatellites()201 public Iterable<GpsSatellite> getSatellites() { 202 return mSatelliteList; 203 } 204 205 /** 206 * Returns the maximum number of satellites that can be in the satellite 207 * list that can be returned by {@link #getSatellites()}. 208 * 209 * @return the maximum number of satellites 210 */ getMaxSatellites()211 public int getMaxSatellites() { 212 return NUM_SATELLITES; 213 } 214 } 215