Home | History | Annotate | Download | only in location
      1 /*
      2  * Copyright (C) 2014 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.SystemApi;
     20 import android.os.Parcel;
     21 import android.os.Parcelable;
     22 
     23 /**
     24  * A class representing a GPS satellite measurement, containing raw and computed information.
     25  *
     26  * @hide
     27  */
     28 @SystemApi
     29 public class GpsMeasurement implements Parcelable {
     30     private int mFlags;
     31     private byte mPrn;
     32     private double mTimeOffsetInNs;
     33     private short mState;
     34     private long mReceivedGpsTowInNs;
     35     private long mReceivedGpsTowUncertaintyInNs;
     36     private double mCn0InDbHz;
     37     private double mPseudorangeRateInMetersPerSec;
     38     private double mPseudorangeRateUncertaintyInMetersPerSec;
     39     private short mAccumulatedDeltaRangeState;
     40     private double mAccumulatedDeltaRangeInMeters;
     41     private double mAccumulatedDeltaRangeUncertaintyInMeters;
     42     private double mPseudorangeInMeters;
     43     private double mPseudorangeUncertaintyInMeters;
     44     private double mCodePhaseInChips;
     45     private double mCodePhaseUncertaintyInChips;
     46     private float mCarrierFrequencyInHz;
     47     private long mCarrierCycles;
     48     private double mCarrierPhase;
     49     private double mCarrierPhaseUncertainty;
     50     private byte mLossOfLock;
     51     private int mBitNumber;
     52     private short mTimeFromLastBitInMs;
     53     private double mDopplerShiftInHz;
     54     private double mDopplerShiftUncertaintyInHz;
     55     private byte mMultipathIndicator;
     56     private double mSnrInDb;
     57     private double mElevationInDeg;
     58     private double mElevationUncertaintyInDeg;
     59     private double mAzimuthInDeg;
     60     private double mAzimuthUncertaintyInDeg;
     61     private boolean mUsedInFix;
     62 
     63     // The following enumerations must be in sync with the values declared in gps.h
     64 
     65     private static final int HAS_NO_FLAGS = 0;
     66     private static final int HAS_SNR = (1<<0);
     67     private static final int HAS_ELEVATION = (1<<1);
     68     private static final int HAS_ELEVATION_UNCERTAINTY = (1<<2);
     69     private static final int HAS_AZIMUTH = (1<<3);
     70     private static final int HAS_AZIMUTH_UNCERTAINTY = (1<<4);
     71     private static final int HAS_PSEUDORANGE = (1<<5);
     72     private static final int HAS_PSEUDORANGE_UNCERTAINTY = (1<<6);
     73     private static final int HAS_CODE_PHASE = (1<<7);
     74     private static final int HAS_CODE_PHASE_UNCERTAINTY = (1<<8);
     75     private static final int HAS_CARRIER_FREQUENCY = (1<<9);
     76     private static final int HAS_CARRIER_CYCLES = (1<<10);
     77     private static final int HAS_CARRIER_PHASE = (1<<11);
     78     private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12);
     79     private static final int HAS_BIT_NUMBER = (1<<13);
     80     private static final int HAS_TIME_FROM_LAST_BIT = (1<<14);
     81     private static final int HAS_DOPPLER_SHIFT = (1<<15);
     82     private static final int HAS_DOPPLER_SHIFT_UNCERTAINTY = (1<<16);
     83     private static final int HAS_USED_IN_FIX = (1<<17);
     84     private static final int GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18);
     85 
     86     /**
     87      * The indicator is not available or it is unknown.
     88      */
     89     public static final byte LOSS_OF_LOCK_UNKNOWN = 0;
     90 
     91     /**
     92      * The measurement does not present any indication of 'loss of lock'.
     93      */
     94     public static final byte LOSS_OF_LOCK_OK = 1;
     95 
     96     /**
     97      * 'Loss of lock' detected between the previous and current observation: cycle slip possible.
     98      */
     99     public static final byte LOSS_OF_LOCK_CYCLE_SLIP = 2;
    100 
    101     /**
    102      * The indicator is not available or it is unknown.
    103      */
    104     public static final byte MULTIPATH_INDICATOR_UNKNOWN = 0;
    105 
    106     /**
    107      * The measurement has been indicated to use multi-path.
    108      */
    109     public static final byte MULTIPATH_INDICATOR_DETECTED = 1;
    110 
    111     /**
    112      * The measurement has been indicated not tu use multi-path.
    113      */
    114     public static final byte MULTIPATH_INDICATOR_NOT_USED = 2;
    115 
    116     /**
    117      * The state of GPS receiver the measurement is invalid or unknown.
    118      */
    119     public static final short STATE_UNKNOWN = 0;
    120 
    121     /**
    122      * The state of the GPS receiver is ranging code lock.
    123      */
    124     public static final short STATE_CODE_LOCK = (1<<0);
    125 
    126     /**
    127      * The state of the GPS receiver is in bit sync.
    128      */
    129     public static final short STATE_BIT_SYNC = (1<<1);
    130 
    131     /**
    132      *The state of the GPS receiver is in sub-frame sync.
    133      */
    134     public static final short STATE_SUBFRAME_SYNC = (1<<2);
    135 
    136     /**
    137      * The state of the GPS receiver has TOW decoded.
    138      */
    139     public static final short STATE_TOW_DECODED = (1<<3);
    140 
    141     /**
    142      * The state of the GPS receiver contains millisecond ambiguity.
    143      */
    144     public static final short STATE_MSEC_AMBIGUOUS = (1<<4);
    145 
    146     /**
    147      * All the GPS receiver state flags.
    148      */
    149     private static final short STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
    150             | STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
    151 
    152     /**
    153      * The state of the 'Accumulated Delta Range' is invalid or unknown.
    154      */
    155     public static final short ADR_STATE_UNKNOWN = 0;
    156 
    157     /**
    158      * The state of the 'Accumulated Delta Range' is valid.
    159      */
    160     public static final short ADR_STATE_VALID = (1<<0);
    161 
    162     /**
    163      * The state of the 'Accumulated Delta Range' has detected a reset.
    164      */
    165     public static final short ADR_STATE_RESET = (1<<1);
    166 
    167     /**
    168      * The state of the 'Accumulated Delta Range' has a cycle slip detected.
    169      */
    170     public static final short ADR_STATE_CYCLE_SLIP = (1<<2);
    171 
    172     /**
    173      * All the 'Accumulated Delta Range' flags.
    174      */
    175     private static final short ADR_ALL = ADR_STATE_VALID | ADR_STATE_RESET | ADR_STATE_CYCLE_SLIP;
    176 
    177     // End enumerations in sync with gps.h
    178 
    179     GpsMeasurement() {
    180         initialize();
    181     }
    182 
    183     /**
    184      * Sets all contents to the values stored in the provided object.
    185      */
    186     public void set(GpsMeasurement measurement) {
    187         mFlags = measurement.mFlags;
    188         mPrn = measurement.mPrn;
    189         mTimeOffsetInNs = measurement.mTimeOffsetInNs;
    190         mState = measurement.mState;
    191         mReceivedGpsTowInNs = measurement.mReceivedGpsTowInNs;
    192         mReceivedGpsTowUncertaintyInNs = measurement.mReceivedGpsTowUncertaintyInNs;
    193         mCn0InDbHz = measurement.mCn0InDbHz;
    194         mPseudorangeRateInMetersPerSec = measurement.mPseudorangeRateInMetersPerSec;
    195         mPseudorangeRateUncertaintyInMetersPerSec =
    196                 measurement.mPseudorangeRateUncertaintyInMetersPerSec;
    197         mAccumulatedDeltaRangeState = measurement.mAccumulatedDeltaRangeState;
    198         mAccumulatedDeltaRangeInMeters = measurement.mAccumulatedDeltaRangeInMeters;
    199         mAccumulatedDeltaRangeUncertaintyInMeters =
    200                 measurement.mAccumulatedDeltaRangeUncertaintyInMeters;
    201         mPseudorangeInMeters = measurement.mPseudorangeInMeters;
    202         mPseudorangeUncertaintyInMeters = measurement.mPseudorangeUncertaintyInMeters;
    203         mCodePhaseInChips = measurement.mCodePhaseInChips;
    204         mCodePhaseUncertaintyInChips = measurement.mCodePhaseUncertaintyInChips;
    205         mCarrierFrequencyInHz = measurement.mCarrierFrequencyInHz;
    206         mCarrierCycles = measurement.mCarrierCycles;
    207         mCarrierPhase = measurement.mCarrierPhase;
    208         mCarrierPhaseUncertainty = measurement.mCarrierPhaseUncertainty;
    209         mLossOfLock = measurement.mLossOfLock;
    210         mBitNumber = measurement.mBitNumber;
    211         mTimeFromLastBitInMs = measurement.mTimeFromLastBitInMs;
    212         mDopplerShiftInHz = measurement.mDopplerShiftInHz;
    213         mDopplerShiftUncertaintyInHz = measurement.mDopplerShiftUncertaintyInHz;
    214         mMultipathIndicator = measurement.mMultipathIndicator;
    215         mSnrInDb = measurement.mSnrInDb;
    216         mElevationInDeg = measurement.mElevationInDeg;
    217         mElevationUncertaintyInDeg = measurement.mElevationUncertaintyInDeg;
    218         mAzimuthInDeg = measurement.mAzimuthInDeg;
    219         mAzimuthUncertaintyInDeg = measurement.mAzimuthUncertaintyInDeg;
    220         mUsedInFix = measurement.mUsedInFix;
    221     }
    222 
    223     /**
    224      * Resets all the contents to its original state.
    225      */
    226     public void reset() {
    227         initialize();
    228     }
    229 
    230     /**
    231      * Gets the Pseudo-random number (PRN).
    232      * Range: [1, 32]
    233      */
    234     public byte getPrn() {
    235         return mPrn;
    236     }
    237 
    238     /**
    239      * Sets the Pseud-random number (PRN).
    240      */
    241     public void setPrn(byte value) {
    242         mPrn = value;
    243     }
    244 
    245     /**
    246      * Gets the time offset at which the measurement was taken in nanoseconds.
    247      * The reference receiver's time is specified by {@link GpsClock#getTimeInNs()} and should be
    248      * interpreted in the same way as indicated by {@link GpsClock#getType()}.
    249      *
    250      * The sign of this value is given by the following equation:
    251      *      measurement time = time_ns + time_offset_ns
    252      *
    253      * The value provides an individual time-stamp for the measurement, and allows sub-nanosecond
    254      * accuracy.
    255      */
    256     public double getTimeOffsetInNs() {
    257         return mTimeOffsetInNs;
    258     }
    259 
    260     /**
    261      * Sets the time offset at which the measurement was taken in nanoseconds.
    262      */
    263     public void setTimeOffsetInNs(double value) {
    264         mTimeOffsetInNs = value;
    265     }
    266 
    267     /**
    268      * Gets per-satellite sync state.
    269      * It represents the current sync state for the associated satellite.
    270      *
    271      * This value helps interpret {@link #getReceivedGpsTowInNs()}.
    272      */
    273     public short getState() {
    274         return mState;
    275     }
    276 
    277     /**
    278      * Sets the sync state.
    279      */
    280     public void setState(short value) {
    281         mState = value;
    282     }
    283 
    284     /**
    285      * Gets a string representation of the 'sync state'.
    286      * For internal and logging use only.
    287      */
    288     private String getStateString() {
    289         if (mState == STATE_UNKNOWN) {
    290             return "Unknown";
    291         }
    292         StringBuilder builder = new StringBuilder();
    293         if ((mState & STATE_CODE_LOCK) == STATE_CODE_LOCK) {
    294             builder.append("CodeLock|");
    295         }
    296         if ((mState & STATE_BIT_SYNC) == STATE_BIT_SYNC) {
    297             builder.append("BitSync|");
    298         }
    299         if ((mState & STATE_SUBFRAME_SYNC) == STATE_SUBFRAME_SYNC) {
    300             builder.append("SubframeSync|");
    301         }
    302         if ((mState & STATE_TOW_DECODED) == STATE_TOW_DECODED) {
    303             builder.append("TowDecoded|");
    304         }
    305         if ((mState & STATE_MSEC_AMBIGUOUS) == STATE_MSEC_AMBIGUOUS) {
    306             builder.append("MsecAmbiguous");
    307         }
    308         int remainingStates = mState & ~STATE_ALL;
    309         if (remainingStates > 0) {
    310             builder.append("Other(");
    311             builder.append(Integer.toBinaryString(remainingStates));
    312             builder.append(")|");
    313         }
    314         builder.deleteCharAt(builder.length() - 1);
    315         return builder.toString();
    316     }
    317 
    318     /**
    319      * Gets the received GPS Time-of-Week at the measurement time, in nanoseconds.
    320      * The value is relative to the beginning of the current GPS week.
    321      *
    322      * Given {@link #getState()} of the GPS receiver, the range of this field can be:
    323      *      Searching           : [ 0           ]   : {@link #STATE_UNKNOWN} is set
    324      *      Ranging code lock   : [ 0    1 ms   ]   : {@link #STATE_CODE_LOCK} is set
    325      *      Bit sync            : [ 0   20 ms   ]   : {@link #STATE_BIT_SYNC} is set
    326      *      Subframe sync       : [ 0    6 ms   ]   : {@link #STATE_SUBFRAME_SYNC} is set
    327      *      TOW decoded         : [ 0    1 week ]   : {@link #STATE_TOW_DECODED} is set
    328      */
    329     public long getReceivedGpsTowInNs() {
    330         return mReceivedGpsTowInNs;
    331     }
    332 
    333     /**
    334      * Sets the received GPS time-of-week in nanoseconds.
    335      */
    336     public void setReceivedGpsTowInNs(long value) {
    337         mReceivedGpsTowInNs = value;
    338     }
    339 
    340     /**
    341      * Gets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
    342      */
    343     public long getReceivedGpsTowUncertaintyInNs() {
    344         return mReceivedGpsTowUncertaintyInNs;
    345     }
    346 
    347     /**
    348      * Sets the received GPS time-of-week's uncertainty (1-Sigma) in nanoseconds.
    349      */
    350     public void setReceivedGpsTowUncertaintyInNs(long value) {
    351         mReceivedGpsTowUncertaintyInNs = value;
    352     }
    353 
    354     /**
    355      * Gets the Carrier-to-noise density in dB-Hz.
    356      * Range: [0, 63].
    357      *
    358      * The value contains the measured C/N0 for the signal at the antenna input.
    359      */
    360     public double getCn0InDbHz() {
    361         return mCn0InDbHz;
    362     }
    363 
    364     /**
    365      * Sets the carrier-to-noise density in dB-Hz.
    366      */
    367     public void setCn0InDbHz(double value) {
    368         mCn0InDbHz = value;
    369     }
    370 
    371     /**
    372      * Gets the Pseudorange rate at the timestamp in m/s.
    373      * The reported value includes {@link #getPseudorangeRateUncertaintyInMetersPerSec()}.
    374      *
    375      * The correction of a given Pseudorange Rate value includes corrections from receiver and
    376      * satellite clock frequency errors.
    377      * {@link #isPseudorangeRateCorrected()} identifies the type of value reported.
    378      *
    379      * A positive 'uncorrected' value indicates that the SV is moving away from the receiver.
    380      * The sign of the 'uncorrected' Pseudorange Rate and its relation to the sign of
    381      * {@link #getDopplerShiftInHz()} is given by the equation:
    382      *      pseudorange rate = -k * doppler shift   (where k is a constant)
    383      */
    384     public double getPseudorangeRateInMetersPerSec() {
    385         return mPseudorangeRateInMetersPerSec;
    386     }
    387 
    388     /**
    389      * Sets the pseudorange rate at the timestamp in m/s.
    390      */
    391     public void setPseudorangeRateInMetersPerSec(double value) {
    392         mPseudorangeRateInMetersPerSec = value;
    393     }
    394 
    395     /**
    396      * See {@link #getPseudorangeRateInMetersPerSec()} for more details.
    397      *
    398      * @return {@code true} if {@link #getPseudorangeRateInMetersPerSec()} contains a corrected
    399      *         value, {@code false} if it contains an uncorrected value.
    400      */
    401     public boolean isPseudorangeRateCorrected() {
    402         return !isFlagSet(GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE);
    403     }
    404 
    405     /**
    406      * Gets the pseudorange's rate uncertainty (1-Sigma) in m/s.
    407      * The uncertainty is represented as an absolute (single sided) value.
    408      */
    409     public double getPseudorangeRateUncertaintyInMetersPerSec() {
    410         return mPseudorangeRateUncertaintyInMetersPerSec;
    411     }
    412 
    413     /**
    414      * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s.
    415      */
    416     public void setPseudorangeRateUncertaintyInMetersPerSec(double value) {
    417         mPseudorangeRateUncertaintyInMetersPerSec = value;
    418     }
    419 
    420     /**
    421      * Gets 'Accumulated Delta Range' state.
    422      * It indicates whether {@link #getAccumulatedDeltaRangeInMeters()} is reset or there is a
    423      * cycle slip (indicating 'loss of lock').
    424      */
    425     public short getAccumulatedDeltaRangeState() {
    426         return mAccumulatedDeltaRangeState;
    427     }
    428 
    429     /**
    430      * Sets the 'Accumulated Delta Range' state.
    431      */
    432     public void setAccumulatedDeltaRangeState(short value) {
    433         mAccumulatedDeltaRangeState = value;
    434     }
    435 
    436     /**
    437      * Gets a string representation of the 'Accumulated Delta Range state'.
    438      * For internal and logging use only.
    439      */
    440     private String getAccumulatedDeltaRangeStateString() {
    441         if (mAccumulatedDeltaRangeState == ADR_STATE_UNKNOWN) {
    442             return "Unknown";
    443         }
    444         StringBuilder builder = new StringBuilder();
    445         if ((mAccumulatedDeltaRangeState & ADR_STATE_VALID) == ADR_STATE_VALID) {
    446             builder.append("Valid|");
    447         }
    448         if ((mAccumulatedDeltaRangeState & ADR_STATE_RESET) == ADR_STATE_RESET) {
    449             builder.append("Reset|");
    450         }
    451         if ((mAccumulatedDeltaRangeState & ADR_STATE_CYCLE_SLIP) == ADR_STATE_CYCLE_SLIP) {
    452             builder.append("CycleSlip|");
    453         }
    454         int remainingStates = mAccumulatedDeltaRangeState & ~ADR_ALL;
    455         if (remainingStates > 0) {
    456             builder.append("Other(");
    457             builder.append(Integer.toBinaryString(remainingStates));
    458             builder.append(")|");
    459         }
    460         builder.deleteCharAt(builder.length() - 1);
    461         return builder.toString();
    462     }
    463 
    464     /**
    465      * Gets the accumulated delta range since the last channel reset, in meters.
    466      * The reported value includes {@link #getAccumulatedDeltaRangeUncertaintyInMeters()}.
    467      *
    468      * The availability of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
    469      *
    470      * A positive value indicates that the SV is moving away from the receiver.
    471      * The sign of {@link #getAccumulatedDeltaRangeInMeters()} and its relation to the sign of
    472      * {@link #getCarrierPhase()} is given by the equation:
    473      *          accumulated delta range = -k * carrier phase    (where k is a constant)
    474      */
    475     public double getAccumulatedDeltaRangeInMeters() {
    476         return mAccumulatedDeltaRangeInMeters;
    477     }
    478 
    479     /**
    480      * Sets the accumulated delta range in meters.
    481      */
    482     public void setAccumulatedDeltaRangeInMeters(double value) {
    483         mAccumulatedDeltaRangeInMeters = value;
    484     }
    485 
    486     /**
    487      * Gets the accumulated delta range's uncertainty (1-Sigma) in meters.
    488      * The uncertainty is represented as an absolute (single sided) value.
    489      *
    490      * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
    491      */
    492     public double getAccumulatedDeltaRangeUncertaintyInMeters() {
    493         return mAccumulatedDeltaRangeUncertaintyInMeters;
    494     }
    495 
    496     /**
    497      * Sets the accumulated delta range's uncertainty (1-sigma) in meters.
    498      *
    499      * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}.
    500      */
    501     public void setAccumulatedDeltaRangeUncertaintyInMeters(double value) {
    502         mAccumulatedDeltaRangeUncertaintyInMeters = value;
    503     }
    504 
    505     /**
    506      * Returns true if {@link #getPseudorangeInMeters()} is available, false otherwise.
    507      */
    508     public boolean hasPseudorangeInMeters() {
    509         return isFlagSet(HAS_PSEUDORANGE);
    510     }
    511 
    512     /**
    513      * Gets the best derived pseudorange by the chipset, in meters.
    514      * The reported pseudorange includes {@link #getPseudorangeUncertaintyInMeters()}.
    515      *
    516      * The value is only available if {@link #hasPseudorangeInMeters()} is true.
    517      */
    518     public double getPseudorangeInMeters() {
    519         return mPseudorangeInMeters;
    520     }
    521 
    522     /**
    523      * Sets the Pseudo-range in meters.
    524      */
    525     public void setPseudorangeInMeters(double value) {
    526         setFlag(HAS_PSEUDORANGE);
    527         mPseudorangeInMeters = value;
    528     }
    529 
    530     /**
    531      * Resets the Pseudo-range in meters.
    532      */
    533     public void resetPseudorangeInMeters() {
    534         resetFlag(HAS_PSEUDORANGE);
    535         mPseudorangeInMeters = Double.NaN;
    536     }
    537 
    538     /**
    539      * Returns true if {@link #getPseudorangeUncertaintyInMeters()} is available, false otherwise.
    540      */
    541     public boolean hasPseudorangeUncertaintyInMeters() {
    542         return isFlagSet(HAS_PSEUDORANGE_UNCERTAINTY);
    543     }
    544 
    545     /**
    546      * Gets the pseudorange's uncertainty (1-Sigma) in meters.
    547      * The value contains the 'pseudorange' and 'clock' uncertainty in it.
    548      * The uncertainty is represented as an absolute (single sided) value.
    549      *
    550      * The value is only available if {@link #hasPseudorangeUncertaintyInMeters()} is true.
    551      */
    552     public double getPseudorangeUncertaintyInMeters() {
    553         return mPseudorangeUncertaintyInMeters;
    554     }
    555 
    556     /**
    557      * Sets the pseudo-range's uncertainty (1-Sigma) in meters.
    558      */
    559     public void setPseudorangeUncertaintyInMeters(double value) {
    560         setFlag(HAS_PSEUDORANGE_UNCERTAINTY);
    561         mPseudorangeUncertaintyInMeters = value;
    562     }
    563 
    564     /**
    565      * Resets the pseudo-range's uncertainty (1-Sigma) in meters.
    566      */
    567     public void resetPseudorangeUncertaintyInMeters() {
    568         resetFlag(HAS_PSEUDORANGE_UNCERTAINTY);
    569         mPseudorangeUncertaintyInMeters = Double.NaN;
    570     }
    571 
    572     /**
    573      * Returns true if {@link #getCodePhaseInChips()} is available, false otherwise.
    574      */
    575     public boolean hasCodePhaseInChips() {
    576         return isFlagSet(HAS_CODE_PHASE);
    577     }
    578 
    579     /**
    580      * Gets the fraction of the current C/A code cycle.
    581      * Range: [0, 1023]
    582      * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
    583      * The reported code-phase includes {@link #getCodePhaseUncertaintyInChips()}.
    584      *
    585      * The value is only available if {@link #hasCodePhaseInChips()} is true.
    586      */
    587     public double getCodePhaseInChips() {
    588         return mCodePhaseInChips;
    589     }
    590 
    591     /**
    592      * Sets the Code-phase in chips.
    593      */
    594     public void setCodePhaseInChips(double value) {
    595         setFlag(HAS_CODE_PHASE);
    596         mCodePhaseInChips = value;
    597     }
    598 
    599     /**
    600      * Resets the Code-phase in chips.
    601      */
    602     public void resetCodePhaseInChips() {
    603         resetFlag(HAS_CODE_PHASE);
    604         mCodePhaseInChips = Double.NaN;
    605     }
    606 
    607     /**
    608      * Returns true if {@link #getCodePhaseUncertaintyInChips()} is available, false otherwise.
    609      */
    610     public boolean hasCodePhaseUncertaintyInChips() {
    611         return isFlagSet(HAS_CODE_PHASE_UNCERTAINTY);
    612     }
    613 
    614     /**
    615      * Gets the code-phase's uncertainty (1-Sigma) as a fraction of chips.
    616      * The uncertainty is represented as an absolute (single sided) value.
    617      *
    618      * The value is only available if {@link #hasCodePhaseUncertaintyInChips()} is true.
    619      */
    620     public double getCodePhaseUncertaintyInChips() {
    621         return mCodePhaseUncertaintyInChips;
    622     }
    623 
    624     /**
    625      * Sets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
    626      */
    627     public void setCodePhaseUncertaintyInChips(double value) {
    628         setFlag(HAS_CODE_PHASE_UNCERTAINTY);
    629         mCodePhaseUncertaintyInChips = value;
    630     }
    631 
    632     /**
    633      * Resets the Code-phase's uncertainty (1-Sigma) in fractions of chips.
    634      */
    635     public void resetCodePhaseUncertaintyInChips() {
    636         resetFlag(HAS_CODE_PHASE_UNCERTAINTY);
    637         mCodePhaseUncertaintyInChips = Double.NaN;
    638     }
    639 
    640     /**
    641      * Returns true if {@link #getCarrierFrequencyInHz()} is available, false otherwise.
    642      */
    643     public boolean hasCarrierFrequencyInHz() {
    644         return isFlagSet(HAS_CARRIER_FREQUENCY);
    645     }
    646 
    647     /**
    648      * Gets the carrier frequency at which codes and messages are modulated, it can be L1 or L2.
    649      * If the field is not set, the carrier frequency corresponds to L1.
    650      *
    651      * The value is only available if {@link #hasCarrierFrequencyInHz()} is true.
    652      */
    653     public float getCarrierFrequencyInHz() {
    654         return mCarrierFrequencyInHz;
    655     }
    656 
    657     /**
    658      * Sets the Carrier frequency (L1 or L2) in Hz.
    659      */
    660     public void setCarrierFrequencyInHz(float carrierFrequencyInHz) {
    661         setFlag(HAS_CARRIER_FREQUENCY);
    662         mCarrierFrequencyInHz = carrierFrequencyInHz;
    663     }
    664 
    665     /**
    666      * Resets the Carrier frequency (L1 or L2) in Hz.
    667      */
    668     public void resetCarrierFrequencyInHz() {
    669         resetFlag(HAS_CARRIER_FREQUENCY);
    670         mCarrierFrequencyInHz = Float.NaN;
    671     }
    672 
    673     /**
    674      * Returns true if {@link #getCarrierCycles()} is available, false otherwise.
    675      */
    676     public boolean hasCarrierCycles() {
    677         return isFlagSet(HAS_CARRIER_CYCLES);
    678     }
    679 
    680     /**
    681      * The number of full carrier cycles between the satellite and the receiver.
    682      * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
    683      *
    684      * The value is only available if {@link #hasCarrierCycles()} is true.
    685      */
    686     public long getCarrierCycles() {
    687         return mCarrierCycles;
    688     }
    689 
    690     /**
    691      * Sets the number of full carrier cycles between the satellite and the receiver.
    692      */
    693     public void setCarrierCycles(long value) {
    694         setFlag(HAS_CARRIER_CYCLES);
    695         mCarrierCycles = value;
    696     }
    697 
    698     /**
    699      * Resets the number of full carrier cycles between the satellite and the receiver.
    700      */
    701     public void resetCarrierCycles() {
    702         resetFlag(HAS_CARRIER_CYCLES);
    703         mCarrierCycles = Long.MIN_VALUE;
    704     }
    705 
    706     /**
    707      * Returns true if {@link #getCarrierPhase()} is available, false otherwise.
    708      */
    709     public boolean hasCarrierPhase() {
    710         return isFlagSet(HAS_CARRIER_PHASE);
    711     }
    712 
    713     /**
    714      * Gets the RF phase detected by the receiver.
    715      * Range: [0.0, 1.0].
    716      * This is usually the fractional part of the complete carrier phase measurement.
    717      *
    718      * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
    719      * The reported carrier-phase includes {@link #getCarrierPhaseUncertainty()}.
    720      *
    721      * The value is only available if {@link #hasCarrierPhase()} is true.
    722      */
    723     public double getCarrierPhase() {
    724         return mCarrierPhase;
    725     }
    726 
    727     /**
    728      * Sets the RF phase detected by the receiver.
    729      */
    730     public void setCarrierPhase(double value) {
    731         setFlag(HAS_CARRIER_PHASE);
    732         mCarrierPhase = value;
    733     }
    734 
    735     /**
    736      * Resets the RF phase detected by the receiver.
    737      */
    738     public void resetCarrierPhase() {
    739         resetFlag(HAS_CARRIER_PHASE);
    740         mCarrierPhase = Double.NaN;
    741     }
    742 
    743     /**
    744      * Returns true if {@link #getCarrierPhaseUncertainty()} is available, false otherwise.
    745      */
    746     public boolean hasCarrierPhaseUncertainty() {
    747         return isFlagSet(HAS_CARRIER_PHASE_UNCERTAINTY);
    748     }
    749 
    750     /**
    751      * Gets the carrier-phase's uncertainty (1-Sigma).
    752      * The uncertainty is represented as an absolute (single sided) value.
    753      *
    754      * The value is only available if {@link #hasCarrierPhaseUncertainty()} is true.
    755      */
    756     public double getCarrierPhaseUncertainty() {
    757         return mCarrierPhaseUncertainty;
    758     }
    759 
    760     /**
    761      * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles.
    762      */
    763     public void setCarrierPhaseUncertainty(double value) {
    764         setFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
    765         mCarrierPhaseUncertainty = value;
    766     }
    767 
    768     /**
    769      * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles.
    770      */
    771     public void resetCarrierPhaseUncertainty() {
    772         resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY);
    773         mCarrierPhaseUncertainty = Double.NaN;
    774     }
    775 
    776     /**
    777      * Gets a value indicating the 'loss of lock' state of the event.
    778      */
    779     public byte getLossOfLock() {
    780         return mLossOfLock;
    781     }
    782 
    783     /**
    784      * Sets the 'loss of lock' status.
    785      */
    786     public void setLossOfLock(byte value) {
    787         mLossOfLock = value;
    788     }
    789 
    790     /**
    791      * Gets a string representation of the 'loss of lock'.
    792      * For internal and logging use only.
    793      */
    794     private String getLossOfLockString() {
    795         switch (mLossOfLock) {
    796             case LOSS_OF_LOCK_UNKNOWN:
    797                 return "Unknown";
    798             case LOSS_OF_LOCK_OK:
    799                 return "Ok";
    800             case LOSS_OF_LOCK_CYCLE_SLIP:
    801                 return "CycleSlip";
    802             default:
    803                 return "<Invalid:" + mLossOfLock + ">";
    804         }
    805     }
    806 
    807     /**
    808      * Returns true if {@link #getBitNumber()} is available, false otherwise.
    809      */
    810     public boolean hasBitNumber() {
    811         return isFlagSet(HAS_BIT_NUMBER);
    812     }
    813 
    814     /**
    815      * Gets the number of GPS bits transmitted since Sat-Sun midnight (GPS week).
    816      *
    817      * The value is only available if {@link #hasBitNumber()} is true.
    818      */
    819     public int getBitNumber() {
    820         return mBitNumber;
    821     }
    822 
    823     /**
    824      * Sets the bit number within the broadcast frame.
    825      */
    826     public void setBitNumber(int bitNumber) {
    827         setFlag(HAS_BIT_NUMBER);
    828         mBitNumber = bitNumber;
    829     }
    830 
    831     /**
    832      * Resets the bit number within the broadcast frame.
    833      */
    834     public void resetBitNumber() {
    835         resetFlag(HAS_BIT_NUMBER);
    836         mBitNumber = Integer.MIN_VALUE;
    837     }
    838 
    839     /**
    840      * Returns true if {@link #getTimeFromLastBitInMs()} is available, false otherwise.
    841      */
    842     public boolean hasTimeFromLastBitInMs() {
    843         return isFlagSet(HAS_TIME_FROM_LAST_BIT);
    844     }
    845 
    846     /**
    847      * Gets the elapsed time since the last received bit in milliseconds.
    848      * Range: [0, 20].
    849      *
    850      * The value is only available if {@link #hasTimeFromLastBitInMs()} is true.
    851      */
    852     public short getTimeFromLastBitInMs() {
    853         return mTimeFromLastBitInMs;
    854     }
    855 
    856     /**
    857      * Sets the elapsed time since the last received bit in milliseconds.
    858      */
    859     public void setTimeFromLastBitInMs(short value) {
    860         setFlag(HAS_TIME_FROM_LAST_BIT);
    861         mTimeFromLastBitInMs = value;
    862     }
    863 
    864     /**
    865      * Resets the elapsed time since the last received bit in milliseconds.
    866      */
    867     public void resetTimeFromLastBitInMs() {
    868         resetFlag(HAS_TIME_FROM_LAST_BIT);
    869         mTimeFromLastBitInMs = Short.MIN_VALUE;
    870     }
    871 
    872     /**
    873      * Returns true if {@link #getDopplerShiftInHz()} is available, false otherwise.
    874      */
    875     public boolean hasDopplerShiftInHz() {
    876         return isFlagSet(HAS_DOPPLER_SHIFT);
    877     }
    878 
    879     /**
    880      * Gets the Doppler Shift in Hz.
    881      * A positive value indicates that the SV is moving toward the receiver.
    882      *
    883      * The reference frequency is given by the value of {@link #getCarrierFrequencyInHz()}.
    884      * The reported doppler shift includes {@link #getDopplerShiftUncertaintyInHz()}.
    885      *
    886      * The value is only available if {@link #hasDopplerShiftInHz()} is true.
    887      */
    888     public double getDopplerShiftInHz() {
    889         return mDopplerShiftInHz;
    890     }
    891 
    892     /**
    893      * Sets the Doppler shift in Hz.
    894      */
    895     public void setDopplerShiftInHz(double value) {
    896         setFlag(HAS_DOPPLER_SHIFT);
    897         mDopplerShiftInHz = value;
    898     }
    899 
    900     /**
    901      * Resets the Doppler shift in Hz.
    902      */
    903     public void resetDopplerShiftInHz() {
    904         resetFlag(HAS_DOPPLER_SHIFT);
    905         mDopplerShiftInHz = Double.NaN;
    906     }
    907 
    908     /**
    909      * Returns true if {@link #getDopplerShiftUncertaintyInHz()} is available, false otherwise.
    910      */
    911     public boolean hasDopplerShiftUncertaintyInHz() {
    912         return isFlagSet(HAS_DOPPLER_SHIFT_UNCERTAINTY);
    913     }
    914 
    915     /**
    916      * Gets the Doppler's Shift uncertainty (1-Sigma) in Hz.
    917      * The uncertainty is represented as an absolute (single sided) value.
    918      *
    919      * The value is only available if {@link #hasDopplerShiftUncertaintyInHz()} is true.
    920      */
    921     public double getDopplerShiftUncertaintyInHz() {
    922         return mDopplerShiftUncertaintyInHz;
    923     }
    924 
    925     /**
    926      * Sets the Doppler's shift uncertainty (1-Sigma) in Hz.
    927      */
    928     public void setDopplerShiftUncertaintyInHz(double value) {
    929         setFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
    930         mDopplerShiftUncertaintyInHz = value;
    931     }
    932 
    933     /**
    934      * Resets the Doppler's shift uncertainty (1-Sigma) in Hz.
    935      */
    936     public void resetDopplerShiftUncertaintyInHz() {
    937         resetFlag(HAS_DOPPLER_SHIFT_UNCERTAINTY);
    938         mDopplerShiftUncertaintyInHz = Double.NaN;
    939     }
    940 
    941     /**
    942      * Gets a value indicating the 'multipath' state of the event.
    943      */
    944     public byte getMultipathIndicator() {
    945         return mMultipathIndicator;
    946     }
    947 
    948     /**
    949      * Sets the 'multi-path' indicator.
    950      */
    951     public void setMultipathIndicator(byte value) {
    952         mMultipathIndicator = value;
    953     }
    954 
    955     /**
    956      * Gets a string representation of the 'multi-path indicator'.
    957      * For internal and logging use only.
    958      */
    959     private String getMultipathIndicatorString() {
    960         switch(mMultipathIndicator) {
    961             case MULTIPATH_INDICATOR_UNKNOWN:
    962                 return "Unknown";
    963             case MULTIPATH_INDICATOR_DETECTED:
    964                 return "Detected";
    965             case MULTIPATH_INDICATOR_NOT_USED:
    966                 return "NotUsed";
    967             default:
    968                 return "<Invalid:" + mMultipathIndicator + ">";
    969         }
    970     }
    971 
    972     /**
    973      * Returns true if {@link #getSnrInDb()} is available, false otherwise.
    974      */
    975     public boolean hasSnrInDb() {
    976         return isFlagSet(HAS_SNR);
    977     }
    978 
    979     /**
    980      * Gets the Signal-to-Noise ratio (SNR) in dB.
    981      *
    982      * The value is only available if {@link #hasSnrInDb()} is true.
    983      */
    984     public double getSnrInDb() {
    985         return mSnrInDb;
    986     }
    987 
    988     /**
    989      * Sets the Signal-to-noise ratio (SNR) in dB.
    990      */
    991     public void setSnrInDb(double snrInDb) {
    992         setFlag(HAS_SNR);
    993         mSnrInDb = snrInDb;
    994     }
    995 
    996     /**
    997      * Resets the Signal-to-noise ratio (SNR) in dB.
    998      */
    999     public void resetSnrInDb() {
   1000         resetFlag(HAS_SNR);
   1001         mSnrInDb = Double.NaN;
   1002     }
   1003 
   1004     /**
   1005      * Returns true if {@link #getElevationInDeg()} is available, false otherwise.
   1006      */
   1007     public boolean hasElevationInDeg() {
   1008         return isFlagSet(HAS_ELEVATION);
   1009     }
   1010 
   1011     /**
   1012      * Gets the Elevation in degrees.
   1013      * Range: [-90, 90]
   1014      * The reported elevation includes {@link #getElevationUncertaintyInDeg()}.
   1015      *
   1016      * The value is only available if {@link #hasElevationInDeg()} is true.
   1017      */
   1018     public double getElevationInDeg() {
   1019         return mElevationInDeg;
   1020     }
   1021 
   1022     /**
   1023      * Sets the Elevation in degrees.
   1024      */
   1025     public void setElevationInDeg(double elevationInDeg) {
   1026         setFlag(HAS_ELEVATION);
   1027         mElevationInDeg = elevationInDeg;
   1028     }
   1029 
   1030     /**
   1031      * Resets the Elevation in degrees.
   1032      */
   1033     public void resetElevationInDeg() {
   1034         resetFlag(HAS_ELEVATION);
   1035         mElevationInDeg = Double.NaN;
   1036     }
   1037 
   1038     /**
   1039      * Returns true if {@link #getElevationUncertaintyInDeg()} is available, false otherwise.
   1040      */
   1041     public boolean hasElevationUncertaintyInDeg() {
   1042         return isFlagSet(HAS_ELEVATION_UNCERTAINTY);
   1043     }
   1044 
   1045     /**
   1046      * Gets the elevation's uncertainty (1-Sigma) in degrees.
   1047      * Range: [0, 90]
   1048      *
   1049      * The uncertainty is represented as an absolute (single sided) value.
   1050      *
   1051      * The value is only available if {@link #hasElevationUncertaintyInDeg()} is true.
   1052      */
   1053     public double getElevationUncertaintyInDeg() {
   1054         return mElevationUncertaintyInDeg;
   1055     }
   1056 
   1057     /**
   1058      * Sets the elevation's uncertainty (1-Sigma) in degrees.
   1059      */
   1060     public void setElevationUncertaintyInDeg(double value) {
   1061         setFlag(HAS_ELEVATION_UNCERTAINTY);
   1062         mElevationUncertaintyInDeg = value;
   1063     }
   1064 
   1065     /**
   1066      * Resets the elevation's uncertainty (1-Sigma) in degrees.
   1067      */
   1068     public void resetElevationUncertaintyInDeg() {
   1069         resetFlag(HAS_ELEVATION_UNCERTAINTY);
   1070         mElevationUncertaintyInDeg = Double.NaN;
   1071     }
   1072 
   1073     /**
   1074      * Returns true if {@link #getAzimuthInDeg()} is available, false otherwise.
   1075      */
   1076     public boolean hasAzimuthInDeg() {
   1077         return isFlagSet(HAS_AZIMUTH);
   1078     }
   1079 
   1080     /**
   1081      * Gets the azimuth in degrees.
   1082      * Range: [0, 360).
   1083      *
   1084      * The reported azimuth includes {@link #getAzimuthUncertaintyInDeg()}.
   1085      *
   1086      * The value is only available if {@link #hasAzimuthInDeg()} is true.
   1087      */
   1088     public double getAzimuthInDeg() {
   1089         return mAzimuthInDeg;
   1090     }
   1091 
   1092     /**
   1093      * Sets the Azimuth in degrees.
   1094      */
   1095     public void setAzimuthInDeg(double value) {
   1096         setFlag(HAS_AZIMUTH);
   1097         mAzimuthInDeg = value;
   1098     }
   1099 
   1100     /**
   1101      * Resets the Azimuth in degrees.
   1102      */
   1103     public void resetAzimuthInDeg() {
   1104         resetFlag(HAS_AZIMUTH);
   1105         mAzimuthInDeg = Double.NaN;
   1106     }
   1107 
   1108     /**
   1109      * Returns true if {@link #getAzimuthUncertaintyInDeg()} is available, false otherwise.
   1110      */
   1111     public boolean hasAzimuthUncertaintyInDeg() {
   1112         return isFlagSet(HAS_AZIMUTH_UNCERTAINTY);
   1113     }
   1114 
   1115     /**
   1116      * Gets the azimuth's uncertainty (1-Sigma) in degrees.
   1117      * Range: [0, 180].
   1118      *
   1119      * The uncertainty is represented as an absolute (single sided) value.
   1120      *
   1121      * The value is only available if {@link #hasAzimuthUncertaintyInDeg()} is true.
   1122      */
   1123     public double getAzimuthUncertaintyInDeg() {
   1124         return mAzimuthUncertaintyInDeg;
   1125     }
   1126 
   1127     /**
   1128      * Sets the Azimuth's uncertainty (1-Sigma) in degrees.
   1129      */
   1130     public void setAzimuthUncertaintyInDeg(double value) {
   1131         setFlag(HAS_AZIMUTH_UNCERTAINTY);
   1132         mAzimuthUncertaintyInDeg = value;
   1133     }
   1134 
   1135     /**
   1136      * Resets the Azimuth's uncertainty (1-Sigma) in degrees.
   1137      */
   1138     public void resetAzimuthUncertaintyInDeg() {
   1139         resetFlag(HAS_AZIMUTH_UNCERTAINTY);
   1140         mAzimuthUncertaintyInDeg = Double.NaN;
   1141     }
   1142 
   1143     /**
   1144      * Gets a flag indicating whether the GPS represented by the measurement was used for computing
   1145      * the most recent fix.
   1146      *
   1147      * @return A non-null value if the data is available, null otherwise.
   1148      */
   1149     public boolean isUsedInFix() {
   1150         return mUsedInFix;
   1151     }
   1152 
   1153     /**
   1154      * Sets the Used-in-Fix flag.
   1155      */
   1156     public void setUsedInFix(boolean value) {
   1157         mUsedInFix = value;
   1158     }
   1159 
   1160     public static final Creator<GpsMeasurement> CREATOR = new Creator<GpsMeasurement>() {
   1161         @Override
   1162         public GpsMeasurement createFromParcel(Parcel parcel) {
   1163             GpsMeasurement gpsMeasurement = new GpsMeasurement();
   1164 
   1165             gpsMeasurement.mFlags = parcel.readInt();
   1166             gpsMeasurement.mPrn = parcel.readByte();
   1167             gpsMeasurement.mTimeOffsetInNs = parcel.readDouble();
   1168             gpsMeasurement.mState = (short) parcel.readInt();
   1169             gpsMeasurement.mReceivedGpsTowInNs = parcel.readLong();
   1170             gpsMeasurement.mReceivedGpsTowUncertaintyInNs = parcel.readLong();
   1171             gpsMeasurement.mCn0InDbHz = parcel.readDouble();
   1172             gpsMeasurement.mPseudorangeRateInMetersPerSec = parcel.readDouble();
   1173             gpsMeasurement.mPseudorangeRateUncertaintyInMetersPerSec = parcel.readDouble();
   1174             gpsMeasurement.mAccumulatedDeltaRangeState = (short) parcel.readInt();
   1175             gpsMeasurement.mAccumulatedDeltaRangeInMeters = parcel.readDouble();
   1176             gpsMeasurement.mAccumulatedDeltaRangeUncertaintyInMeters = parcel.readDouble();
   1177             gpsMeasurement.mPseudorangeInMeters = parcel.readDouble();
   1178             gpsMeasurement.mPseudorangeUncertaintyInMeters = parcel.readDouble();
   1179             gpsMeasurement.mCodePhaseInChips = parcel.readDouble();
   1180             gpsMeasurement.mCodePhaseUncertaintyInChips = parcel.readDouble();
   1181             gpsMeasurement.mCarrierFrequencyInHz = parcel.readFloat();
   1182             gpsMeasurement.mCarrierCycles = parcel.readLong();
   1183             gpsMeasurement.mCarrierPhase = parcel.readDouble();
   1184             gpsMeasurement.mCarrierPhaseUncertainty = parcel.readDouble();
   1185             gpsMeasurement.mLossOfLock = parcel.readByte();
   1186             gpsMeasurement.mBitNumber = parcel.readInt();
   1187             gpsMeasurement.mTimeFromLastBitInMs = (short) parcel.readInt();
   1188             gpsMeasurement.mDopplerShiftInHz = parcel.readDouble();
   1189             gpsMeasurement.mDopplerShiftUncertaintyInHz = parcel.readDouble();
   1190             gpsMeasurement.mMultipathIndicator = parcel.readByte();
   1191             gpsMeasurement.mSnrInDb = parcel.readDouble();
   1192             gpsMeasurement.mElevationInDeg = parcel.readDouble();
   1193             gpsMeasurement.mElevationUncertaintyInDeg = parcel.readDouble();
   1194             gpsMeasurement.mAzimuthInDeg = parcel.readDouble();
   1195             gpsMeasurement.mAzimuthUncertaintyInDeg = parcel.readDouble();
   1196             gpsMeasurement.mUsedInFix = parcel.readInt() != 0;
   1197 
   1198             return gpsMeasurement;
   1199         }
   1200 
   1201         @Override
   1202         public GpsMeasurement[] newArray(int i) {
   1203             return new GpsMeasurement[i];
   1204         }
   1205     };
   1206 
   1207     public void writeToParcel(Parcel parcel, int flags) {
   1208         parcel.writeInt(mFlags);
   1209         parcel.writeByte(mPrn);
   1210         parcel.writeDouble(mTimeOffsetInNs);
   1211         parcel.writeInt(mState);
   1212         parcel.writeLong(mReceivedGpsTowInNs);
   1213         parcel.writeLong(mReceivedGpsTowUncertaintyInNs);
   1214         parcel.writeDouble(mCn0InDbHz);
   1215         parcel.writeDouble(mPseudorangeRateInMetersPerSec);
   1216         parcel.writeDouble(mPseudorangeRateUncertaintyInMetersPerSec);
   1217         parcel.writeInt(mAccumulatedDeltaRangeState);
   1218         parcel.writeDouble(mAccumulatedDeltaRangeInMeters);
   1219         parcel.writeDouble(mAccumulatedDeltaRangeUncertaintyInMeters);
   1220         parcel.writeDouble(mPseudorangeInMeters);
   1221         parcel.writeDouble(mPseudorangeUncertaintyInMeters);
   1222         parcel.writeDouble(mCodePhaseInChips);
   1223         parcel.writeDouble(mCodePhaseUncertaintyInChips);
   1224         parcel.writeFloat(mCarrierFrequencyInHz);
   1225         parcel.writeLong(mCarrierCycles);
   1226         parcel.writeDouble(mCarrierPhase);
   1227         parcel.writeDouble(mCarrierPhaseUncertainty);
   1228         parcel.writeByte(mLossOfLock);
   1229         parcel.writeInt(mBitNumber);
   1230         parcel.writeInt(mTimeFromLastBitInMs);
   1231         parcel.writeDouble(mDopplerShiftInHz);
   1232         parcel.writeDouble(mDopplerShiftUncertaintyInHz);
   1233         parcel.writeByte(mMultipathIndicator);
   1234         parcel.writeDouble(mSnrInDb);
   1235         parcel.writeDouble(mElevationInDeg);
   1236         parcel.writeDouble(mElevationUncertaintyInDeg);
   1237         parcel.writeDouble(mAzimuthInDeg);
   1238         parcel.writeDouble(mAzimuthUncertaintyInDeg);
   1239         parcel.writeInt(mUsedInFix ? 1 : 0);
   1240     }
   1241 
   1242     @Override
   1243     public int describeContents() {
   1244         return 0;
   1245     }
   1246 
   1247     @Override
   1248     public String toString() {
   1249         final String format = "   %-29s = %s\n";
   1250         final String formatWithUncertainty = "   %-29s = %-25s   %-40s = %s\n";
   1251         StringBuilder builder = new StringBuilder("GpsMeasurement:\n");
   1252 
   1253         builder.append(String.format(format, "Prn", mPrn));
   1254 
   1255         builder.append(String.format(format, "TimeOffsetInNs", mTimeOffsetInNs));
   1256 
   1257         builder.append(String.format(format, "State", getStateString()));
   1258 
   1259         builder.append(String.format(
   1260                 formatWithUncertainty,
   1261                 "ReceivedGpsTowInNs",
   1262                 mReceivedGpsTowInNs,
   1263                 "ReceivedGpsTowUncertaintyInNs",
   1264                 mReceivedGpsTowUncertaintyInNs));
   1265 
   1266         builder.append(String.format(format, "Cn0InDbHz", mCn0InDbHz));
   1267 
   1268         builder.append(String.format(
   1269                 formatWithUncertainty,
   1270                 "PseudorangeRateInMetersPerSec",
   1271                 mPseudorangeRateInMetersPerSec,
   1272                 "PseudorangeRateUncertaintyInMetersPerSec",
   1273                 mPseudorangeRateUncertaintyInMetersPerSec));
   1274         builder.append(String.format(
   1275                 format,
   1276                 "PseudorangeRateIsCorrected",
   1277                 isPseudorangeRateCorrected()));
   1278 
   1279         builder.append(String.format(
   1280                 format,
   1281                 "AccumulatedDeltaRangeState",
   1282                 getAccumulatedDeltaRangeStateString()));
   1283 
   1284         builder.append(String.format(
   1285                 formatWithUncertainty,
   1286                 "AccumulatedDeltaRangeInMeters",
   1287                 mAccumulatedDeltaRangeInMeters,
   1288                 "AccumulatedDeltaRangeUncertaintyInMeters",
   1289                 mAccumulatedDeltaRangeUncertaintyInMeters));
   1290 
   1291         builder.append(String.format(
   1292                 formatWithUncertainty,
   1293                 "PseudorangeInMeters",
   1294                 hasPseudorangeInMeters() ? mPseudorangeInMeters : null,
   1295                 "PseudorangeUncertaintyInMeters",
   1296                 hasPseudorangeUncertaintyInMeters() ? mPseudorangeUncertaintyInMeters : null));
   1297 
   1298         builder.append(String.format(
   1299                 formatWithUncertainty,
   1300                 "CodePhaseInChips",
   1301                 hasCodePhaseInChips() ? mCodePhaseInChips : null,
   1302                 "CodePhaseUncertaintyInChips",
   1303                 hasCodePhaseUncertaintyInChips() ? mCodePhaseUncertaintyInChips : null));
   1304 
   1305         builder.append(String.format(
   1306                 format,
   1307                 "CarrierFrequencyInHz",
   1308                 hasCarrierFrequencyInHz() ? mCarrierFrequencyInHz : null));
   1309 
   1310         builder.append(String.format(
   1311                 format,
   1312                 "CarrierCycles",
   1313                 hasCarrierCycles() ? mCarrierCycles : null));
   1314 
   1315         builder.append(String.format(
   1316                 formatWithUncertainty,
   1317                 "CarrierPhase",
   1318                 hasCarrierPhase() ? mCarrierPhase : null,
   1319                 "CarrierPhaseUncertainty",
   1320                 hasCarrierPhaseUncertainty() ? mCarrierPhaseUncertainty : null));
   1321 
   1322         builder.append(String.format(format, "LossOfLock", getLossOfLockString()));
   1323 
   1324         builder.append(String.format(
   1325                 format,
   1326                 "BitNumber",
   1327                 hasBitNumber() ? mBitNumber : null));
   1328 
   1329         builder.append(String.format(
   1330                 format,
   1331                 "TimeFromLastBitInMs",
   1332                 hasTimeFromLastBitInMs() ? mTimeFromLastBitInMs : null));
   1333 
   1334         builder.append(String.format(
   1335                 formatWithUncertainty,
   1336                 "DopplerShiftInHz",
   1337                 hasDopplerShiftInHz() ? mDopplerShiftInHz : null,
   1338                 "DopplerShiftUncertaintyInHz",
   1339                 hasDopplerShiftUncertaintyInHz() ? mDopplerShiftUncertaintyInHz : null));
   1340 
   1341         builder.append(String.format(format, "MultipathIndicator", getMultipathIndicatorString()));
   1342 
   1343         builder.append(String.format(
   1344                 format,
   1345                 "SnrInDb",
   1346                 hasSnrInDb() ? mSnrInDb : null));
   1347 
   1348         builder.append(String.format(
   1349                 formatWithUncertainty,
   1350                 "ElevationInDeg",
   1351                 hasElevationInDeg() ? mElevationInDeg : null,
   1352                 "ElevationUncertaintyInDeg",
   1353                 hasElevationUncertaintyInDeg() ? mElevationUncertaintyInDeg : null));
   1354 
   1355         builder.append(String.format(
   1356                 formatWithUncertainty,
   1357                 "AzimuthInDeg",
   1358                 hasAzimuthInDeg() ? mAzimuthInDeg : null,
   1359                 "AzimuthUncertaintyInDeg",
   1360                 hasAzimuthUncertaintyInDeg() ? mAzimuthUncertaintyInDeg : null));
   1361 
   1362         builder.append(String.format(format, "UsedInFix", mUsedInFix));
   1363 
   1364         return builder.toString();
   1365     }
   1366 
   1367     private void initialize() {
   1368         mFlags = HAS_NO_FLAGS;
   1369         setPrn(Byte.MIN_VALUE);
   1370         setTimeOffsetInNs(Long.MIN_VALUE);
   1371         setState(STATE_UNKNOWN);
   1372         setReceivedGpsTowInNs(Long.MIN_VALUE);
   1373         setReceivedGpsTowUncertaintyInNs(Long.MAX_VALUE);
   1374         setCn0InDbHz(Double.MIN_VALUE);
   1375         setPseudorangeRateInMetersPerSec(Double.MIN_VALUE);
   1376         setPseudorangeRateUncertaintyInMetersPerSec(Double.MIN_VALUE);
   1377         setAccumulatedDeltaRangeState(ADR_STATE_UNKNOWN);
   1378         setAccumulatedDeltaRangeInMeters(Double.MIN_VALUE);
   1379         setAccumulatedDeltaRangeUncertaintyInMeters(Double.MIN_VALUE);
   1380         resetPseudorangeInMeters();
   1381         resetPseudorangeUncertaintyInMeters();
   1382         resetCodePhaseInChips();
   1383         resetCodePhaseUncertaintyInChips();
   1384         resetCarrierFrequencyInHz();
   1385         resetCarrierCycles();
   1386         resetCarrierPhase();
   1387         resetCarrierPhaseUncertainty();
   1388         setLossOfLock(LOSS_OF_LOCK_UNKNOWN);
   1389         resetBitNumber();
   1390         resetTimeFromLastBitInMs();
   1391         resetDopplerShiftInHz();
   1392         resetDopplerShiftUncertaintyInHz();
   1393         setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN);
   1394         resetSnrInDb();
   1395         resetElevationInDeg();
   1396         resetElevationUncertaintyInDeg();
   1397         resetAzimuthInDeg();
   1398         resetAzimuthUncertaintyInDeg();
   1399         setUsedInFix(false);
   1400     }
   1401 
   1402     private void setFlag(int flag) {
   1403         mFlags |= flag;
   1404     }
   1405 
   1406     private void resetFlag(int flag) {
   1407         mFlags &= ~flag;
   1408     }
   1409 
   1410     private boolean isFlagSet(int flag) {
   1411         return (mFlags & flag) == flag;
   1412     }
   1413 }
   1414