GpsStatus.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
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 17package android.location; 18 19import java.util.Iterator; 20import 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 */ 27public final class GpsStatus { 28 private static final int NUM_SATELLITES = 32; 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 39 SatelliteIterator(GpsSatellite[] satellites) { 40 mSatellites = satellites; 41 } 42 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 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 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 */ 115 void onGpsStatusChanged(int event); 116 } 117 118 GpsStatus() { 119 for (int i = 0; i < mSatellites.length; i++) { 120 mSatellites[i] = new GpsSatellite(i + 1); 121 } 122 } 123 124 /** 125 * Used internally within {@link LocationManager} to copy GPS status 126 * data from the Location Manager Service to its cached GpsStatus instance. 127 * Is synchronized to ensure that GPS status updates are atomic. 128 */ 129 synchronized void setStatus(int svCount, int[] prns, float[] snrs, 130 float[] elevations, float[] azimuths, int ephemerisMask, 131 int almanacMask, int usedInFixMask) { 132 int i; 133 134 for (i = 0; i < mSatellites.length; i++) { 135 mSatellites[i].mValid = false; 136 } 137 138 for (i = 0; i < svCount; i++) { 139 int prn = prns[i] - 1; 140 int prnShift = (1 << prn); 141 GpsSatellite satellite = mSatellites[prn]; 142 143 satellite.mValid = true; 144 satellite.mSnr = snrs[i]; 145 satellite.mElevation = elevations[i]; 146 satellite.mAzimuth = azimuths[i]; 147 satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0); 148 satellite.mHasAlmanac = ((almanacMask & prnShift) != 0); 149 satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0); 150 } 151 } 152 153 /** 154 * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's 155 * cached GpsStatus instance to the client's copy. 156 * Since this method is only used within {@link LocationManager#getGpsStatus}, 157 * it does not need to be synchronized. 158 */ 159 void setStatus(GpsStatus status) { 160 mTimeToFirstFix = status.getTimeToFirstFix(); 161 162 for (int i = 0; i < mSatellites.length; i++) { 163 mSatellites[i].setStatus(status.mSatellites[i]); 164 } 165 } 166 167 void setTimeToFirstFix(int ttff) { 168 mTimeToFirstFix = ttff; 169 } 170 171 /** 172 * Returns the time required to receive the first fix since the most recent 173 * restart of the GPS engine. 174 * 175 * @return time to first fix in milliseconds 176 */ 177 public int getTimeToFirstFix() { 178 return mTimeToFirstFix; 179 } 180 181 /** 182 * Returns an array of {@link GpsSatellite} objects, which represent the 183 * current state of the GPS engine. 184 * 185 * @return the list of satellites 186 */ 187 public Iterable<GpsSatellite> getSatellites() { 188 return mSatelliteList; 189 } 190 191 /** 192 * Returns the maximum number of satellites that can be in the satellite 193 * list that can be returned by {@link #getSatellites()}. 194 * 195 * @return the maximum number of satellites 196 */ 197 public int getMaxSatellites() { 198 return NUM_SATELLITES; 199 } 200} 201