OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / location / java / android / location / GpsStatus.java
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
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     /**
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 {
127         void onNmeaReceived(long timestamp, String nmea);
128     }
129
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      */
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      */
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
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      */
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      */
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      */
211     public int getMaxSatellites() {
212         return NUM_SATELLITES;
213     }
214 }