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