GpsStatus.java revision 9066cfe9886ac131c34d59ed0e2d287b0e3c0087
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.location;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Iterator;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.NoSuchElementException;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class represents the current state of the GPS engine.
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class is used in conjunction with the {@link Listener} interface.
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class GpsStatus {
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int NUM_SATELLITES = 32;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* These package private values are modified by the LocationManager class */
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mTimeToFirstFix;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private GpsSatellite mSatellites[] = new GpsSatellite[NUM_SATELLITES];
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final class SatelliteIterator implements Iterator<GpsSatellite> {
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private GpsSatellite[] mSatellites;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int mIndex = 0;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SatelliteIterator(GpsSatellite[] satellites) {
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSatellites = satellites;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public boolean hasNext() {
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i = mIndex; i < mSatellites.length; i++) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mSatellites[i].mValid) {
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return true;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public GpsSatellite next() {
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (mIndex < mSatellites.length) {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                GpsSatellite satellite = mSatellites[mIndex++];
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (satellite.mValid) {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return satellite;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new NoSuchElementException();
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void remove() {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new UnsupportedOperationException();
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public Iterator<GpsSatellite> iterator() {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new SatelliteIterator(mSatellites);
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Event sent when the GPS system has started.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int GPS_EVENT_STARTED = 1;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Event sent when the GPS system has stopped.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int GPS_EVENT_STOPPED = 2;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Event sent when the GPS system has received its first fix since starting.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call {@link #getTimeToFirstFix()} to find the time from start to first fix.
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int GPS_EVENT_FIRST_FIX = 3;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Event sent periodically to report GPS satellite status.
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Call {@link #getSatellites()} to retrieve the status for each satellite.
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final int GPS_EVENT_SATELLITE_STATUS = 4;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used for receiving notifications when GPS status has changed.
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface Listener {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Called to report changes in the GPS status.
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * The event number is one of:
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <ul>
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <li> {@link GpsStatus#GPS_EVENT_STARTED}
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <li> {@link GpsStatus#GPS_EVENT_STOPPED}
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX}
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS}
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * </ul>
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * When this method is called, the client should call
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link LocationManager#getGpsStatus} to get additional
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * status information.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         *
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * @param event event number for this notification
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        void onGpsStatusChanged(int event);
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    GpsStatus() {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < mSatellites.length; i++) {
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSatellites[i] = new GpsSatellite(i + 1);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used internally within {@link LocationManager} to copy GPS status
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * data from the Location Manager Service to its cached GpsStatus instance.
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Is synchronized to ensure that GPS status updates are atomic.
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    synchronized void setStatus(int svCount, int[] prns, float[] snrs,
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            float[] elevations, float[] azimuths, int ephemerisMask,
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int almanacMask, int usedInFixMask) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int i;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < mSatellites.length; i++) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSatellites[i].mValid = false;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < svCount; i++) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int prn = prns[i] - 1;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int prnShift = (1 << prn);
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            GpsSatellite satellite = mSatellites[prn];
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mValid = true;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mSnr = snrs[i];
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mElevation = elevations[i];
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mAzimuth = azimuths[i];
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mHasAlmanac = ((almanacMask & prnShift) != 0);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Used by {@link LocationManager#getGpsStatus} to copy LocationManager's
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cached GpsStatus instance to the client's copy.
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Since this method is only used within {@link LocationManager#getGpsStatus},
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it does not need to be synchronized.
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setStatus(GpsStatus status) {
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTimeToFirstFix = status.getTimeToFirstFix();
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < mSatellites.length; i++) {
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSatellites[i].setStatus(status.mSatellites[i]);
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setTimeToFirstFix(int ttff) {
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mTimeToFirstFix = ttff;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the time required to receive the first fix since the most recent
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * restart of the GPS engine.
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return time to first fix in milliseconds
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getTimeToFirstFix() {
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTimeToFirstFix;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns an array of {@link GpsSatellite} objects, which represent the
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current state of the GPS engine.
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the list of satellites
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Iterable<GpsSatellite> getSatellites() {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mSatelliteList;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the maximum number of satellites that can be in the satellite
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * list that can be returned by {@link #getSatellites()}.
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the maximum number of satellites
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxSatellites() {
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NUM_SATELLITES;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
201