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