Package com.rim.samples.device.gpsdemoadvanced

Source Code of com.rim.samples.device.gpsdemoadvanced.ExtendedGPSDiagnosticScreen

/**
* ExtendedGPSDiagnosticScreen.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings.  However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies.  For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/

package com.rim.samples.device.gpsdemoadvanced;

import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationListener;
import javax.microedition.location.LocationProvider;

import net.rim.blackberry.api.invoke.Invoke;
import net.rim.blackberry.api.invoke.MapsArguments;
import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.gps.BlackBerryCriteria;
import net.rim.device.api.gps.BlackBerryLocation;
import net.rim.device.api.gps.BlackBerryLocationProvider;
import net.rim.device.api.gps.GPSInfo;
import net.rim.device.api.gps.GPSSettings;
import net.rim.device.api.gps.LocationInfo;
import net.rim.device.api.i18n.SimpleDateFormat;
import net.rim.device.api.io.LineReader;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.EventLogger;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BasicEditField;
import net.rim.device.api.ui.component.CheckboxField;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.ObjectChoiceField;
import net.rim.device.api.ui.component.SeparatorField;
import net.rim.device.api.ui.component.TextField;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.util.StringProvider;

/**
* Tests the use of the extended APIs included in the net.rim.device.api.gps
* package.
*
* There are several available modes the user can choose. (m) stands for
* 'multiple fix' and (s) stands for 'single fix'
*
* In Smart Mode the application operates in MS-Based mode but falls back to
* MS-Assisted for a single fix if the LocationProvider is unable to return a
* valid fix in (maxInvalidTime) seconds. The provider then goes back to
* MS-Based again.
*
* For any assisted modes (all those except Stand Alone or Cellsite), additional
* helper data from a PDE server is required.
*/
public class ExtendedGPSDiagnosticScreen extends MainScreen implements
        FieldChangeListener {
    // Provides a reference to the UIApplication for faster updating
    private final UiApplication _uiApp;

    // TextField to show the logs
    private TextField _log;

    // The available modes the user can choose
    private ObjectChoiceField _primaryModeField;

    // Checkbox to enable geolocation falback
    private CheckboxField _enableGeolocationFallbackField;

    // Checkbox to enable concurrent geolocation
    private CheckboxField _enableConcurrentGeolocationField;

    // Check box to indicate whether location should be displayed on a map
    private CheckboxField _isMapLocationField;

    // Check box to specify whether to set gpsRestartInterval
    private CheckboxField _useGPSRestartIntervalField;

    // Check box to specify whether detailed satellite info is required
    private CheckboxField _isSatelliteInfoRequiredField;

    // Indicates if the device is on Verizon. If so, app credentials will be set
    // instead of PDE IP and Port.
    private CheckboxField _isVerizonField;

    // Field to choose a failover mode
    private ObjectChoiceField _failOverModeField;

    // Field to choose a mode to be used after the first fix
    private ObjectChoiceField _subsequentModeField;

    // Field to specify the zoom level used in the BlackBerry Maps application
    private BasicEditField _zoomLevelField;

    // Field to enter the preferred response time
    private BasicEditField _preferredResponseTimeField;

    // Field to enter the interval parameter for a LocationListener
    private BasicEditField _frequencyField;

    // Field to enter the timeout parameter for a LocationListener
    private BasicEditField _timeoutField;

    // Field to enter the maximum age of the returned location in seconds
    private BasicEditField _maxAgeField;

    // Field to enter the maximum number of GPS retries (using the selected
    // mode)
    // before a failover occurs.
    private BasicEditField _failOverRetriesField;

    // Field to enter the maximum wait time (in seconds) to get a fix before a
    // failover occurs
    private BasicEditField _failoverTimeoutField;

    // Field to enter the time (in seconds) the JSR179 extension will wait
    // before
    // automatically restarting GPS.
    private BasicEditField _gpsRestartIntervalField;

    // Field to enter the maximum number of GPS restarts
    private BasicEditField _gpsRestartRetriesField;

    // Field to enter the PDE IP
    private BasicEditField _pdeIPField;

    // Field to enter the PDE port
    private BasicEditField _pdePortField;

    // Displays the supported location data sources for the device
    private BasicEditField _supportedSourcesField;

    // Displays the available location data sources of the device
    private BasicEditField _availableSourcesField;

    // Displays the GPS mode used for the current location
    private BasicEditField _currentModeField;

    // Displays the number of satellites used to compute the current fix
    private BasicEditField _currentSatellitesCountField;

    // Displays the location information for the current fix
    private EditField _currentLocationField;

    // Displays the average satellite signal quality of the current fix
    private EditField _currentAverageSatelliteSignalField;

    // Displays the DataSource used to get the current fix
    private EditField _currentDataSourceField;

    // Displays an error for the current GPS fix
    private EditField _currentErrorField;

    // Displays the status of the current fix
    private EditField _currentStatusField;

    // Displays the total number of updates that have occurred
    private EditField _numberUpdatesField;

    // Displays the total number of MS-Assisted updates that have occurred
    private EditField _numberAssistedUpdatesField;

    // Displays the total number of MS-Based updates that have occurred
    private EditField _numberUnassistedUpdatesField;

    // Displays the total number of valid updates that have occurred
    private EditField _numberValidUpdatesField;

    // Displays the total number of invalid updates that have occurred
    private EditField _numberInvalidUpdatesField;

    // This Thread performs all location related work
    private LocationThread _locThread;

    // Flag indicating an immediate reset is required due to
    // TEMPORARILY_UNAVAILABLE event
    private boolean _resetNow;

    // A menu item for stopping a running test
    private final MenuItem _stopTestItem;

    private boolean _PDESet;

    /**
     * Creates a new ExtendedGPSDiagnosticScreen object
     */
    public ExtendedGPSDiagnosticScreen() {
        // Initialize the reference to the UiApplication
        _uiApp = UiApplication.getUiApplication();

        // Initialize UI components
        setTitle("Extended GPS Diagnostic Test");
        initFields();
        _isVerizonField.setChangeListener(this);

        // A MenuItem to start the diagnostic test
        final MenuItem startTestItem =
                new MenuItem(new StringProvider("Start Test"), 0x300010, 0);
        ;
        startTestItem.setCommand(new Command(new CommandHandler() {
            /**
             * @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
             *      Object)
             */
            public void execute(final ReadOnlyCommandMetadata metadata,
                    final Object context) {
                // Format the UI for output
                showOutputFields();

                // Begin test
                if (_locThread != null) {
                    if (!_locThread.isStopped()) {
                        _locThread.stop();
                    }
                }

                _log.setText("");
                log("Extended GPS API test starting");
                log("Device: " + DeviceInfo.getDeviceName());
                log("Device Software: " + DeviceInfo.getSoftwareVersion());
                log("Carrier: " + RadioInfo.getCurrentNetworkName());

                _locThread = new LocationThread();
                _locThread.start();
            }
        }));
        addMenuItem(startTestItem);
        _stopTestItem =
                new MenuItem(new StringProvider("Stop Test"), 0x300020, 1);
        _stopTestItem.setCommand(new Command(new CommandHandler() {
            /**
             * @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
             *      Object)
             */
            public void execute(final ReadOnlyCommandMetadata metadata,
                    final Object context) {
                // Stop the thread
                log("Stopping test");
                _locThread.stop();
                _locThread = null;
            }
        }));
        addMenuItem(_stopTestItem);

        // A MenuItem to display the help dialog
        final MenuItem helpItem =
                new MenuItem(new StringProvider("Help"), 0x300030, 2);
        helpItem.setCommand(new Command(new CommandHandler() {
            /**
             * @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
             *      Object)
             */
            public void execute(final ReadOnlyCommandMetadata metadata,
                    final Object context) {
                // Display a pop-up dialog with instructions for using this
                // application
                displayHelp();
            }
        }));
        addMenuItem(helpItem);
        showInputFields();
    }

    /**
     * Initializes the UI fields
     */
    private void initFields() {
        _log = new TextField();
        _log.setLabel("Log: ");
        _primaryModeField =
                new ObjectChoiceField("Mode: ", new String[] {
                        "Stand Alone(s)", "Stand Alone(m)", "Data Optimal(m)",
                        "Speed Optimal(m)", "MS-Based(m)",
                        "Accuracy Optimal(s)", "PDE Calculate(s)",
                        "Cellsite(s)", "Cellsite(m)", "Default(s)",
                        "Default(m)", "Optimal Geolocation(s)",
                        "Optimal Geolocation(m)", "Cell Geolocation(s)",
                        "Cell Geolocation(m)", "WLAN Geolocation(s)",
                        "WLAN Geolocation(m)" }, 1);
        _enableGeolocationFallbackField =
                new CheckboxField("Enable Geolocation Fallback", false);
        _enableConcurrentGeolocationField =
                new CheckboxField("Enable Concurrent Geolocation", false);
        _isMapLocationField = new CheckboxField("Map Location", false);
        _useGPSRestartIntervalField =
                new CheckboxField("GPS Restart Interval?", false);
        _isSatelliteInfoRequiredField =
                new CheckboxField("Satellite information required?", false);
        _isVerizonField = new CheckboxField("Verizon?", false);
        _failOverModeField =
                new ObjectChoiceField("Failover Mode: ",
                        new String[] { "Stand Alone", "Data Optimal",
                                "Speed Optimal", "MS-Based",
                                "Accuracy Optimal", "PDE Calculate", "None" },
                        6);
        _subsequentModeField =
                new ObjectChoiceField("Subsequent Mode: ",
                        new String[] { "Stand Alone", "Data Optimal",
                                "Speed Optimal", "MS-Based",
                                "Accuracy Optimal", "PDE Calculate", "None" },
                        6);
        _zoomLevelField = new BasicEditField("Zoom: ", "1");
        _preferredResponseTimeField =
                new BasicEditField("Pref'd Response Time (sec): ", "16", 6,
                        BasicEditField.FILTER_INTEGER);
        _frequencyField =
                new BasicEditField("Fix Frequency (sec): ", "5", 5,
                        BasicEditField.FILTER_INTEGER);
        _timeoutField =
                new BasicEditField("Timeout (sec): ", "-1", 5,
                        BasicEditField.FILTER_INTEGER);
        _maxAgeField =
                new BasicEditField("MaxAge (sec): ", "-1", 5,
                        BasicEditField.FILTER_INTEGER);
        _failOverRetriesField =
                new BasicEditField("Max Retries [0-3]: ", "0", 1,
                        BasicEditField.FILTER_INTEGER);
        _failoverTimeoutField =
                new BasicEditField("Failover Timeout [30-300]: ", "30", 3,
                        BasicEditField.FILTER_INTEGER);
        _gpsRestartIntervalField =
                new BasicEditField("Restart Interval [2-900]: ", "100", 3,
                        BasicEditField.FILTER_INTEGER);
        _gpsRestartRetriesField =
                new BasicEditField("Restart Retries [1-3]: ", "3", 1,
                        BasicEditField.FILTER_INTEGER);
        _pdeIPField = new BasicEditField("PDE IP: ", "");
        _pdePortField = new BasicEditField("PDE Port: ", "");
        _supportedSourcesField = new BasicEditField("Supported Sources: ", "-");
        _availableSourcesField = new BasicEditField("Available Sources: ", "-");
        _currentModeField = new BasicEditField("Current Mode: ", "-");
        _currentSatellitesCountField = new BasicEditField("Satellites: ", "-");
        _currentLocationField = new EditField("Location: ", "-");
        _currentAverageSatelliteSignalField =
                new EditField("Satellite Signal: ", "-");
        _currentDataSourceField = new EditField("Data Source: ", "-");
        _currentErrorField = new EditField("Error: ", "-");
        _currentStatusField = new EditField("Status: ", "-");
        _numberUpdatesField = new EditField("Total Updates: ", "0");
        _numberAssistedUpdatesField = new EditField("Assisted: ", "0");
        _numberUnassistedUpdatesField = new EditField("Unassisted: ", "0");
        _numberValidUpdatesField = new EditField("Valid Updates: ", "0");
        _numberInvalidUpdatesField = new EditField("Invalid Updates: ", "0");
    }

    /**
     * Empties the screen and adds the input fields
     */
    private void showInputFields() {
        // Remove existing UI components
        deleteAll();

        // Add all input UI components
        add(_primaryModeField);
        add(new SeparatorField());
        add(_enableGeolocationFallbackField);
        add(new SeparatorField());
        add(_enableConcurrentGeolocationField);
        add(new SeparatorField());
        add(_isVerizonField);
        add(_pdeIPField);
        add(_pdePortField);
        add(new SeparatorField());
        add(_isMapLocationField);
        add(_zoomLevelField);
        add(new SeparatorField());
        add(_preferredResponseTimeField);
        add(new SeparatorField());
        add(_frequencyField);
        add(_timeoutField);
        add(_maxAgeField);
        add(new SeparatorField());
        add(_failOverModeField);
        add(_failOverRetriesField);
        add(_failoverTimeoutField);
        add(new SeparatorField());
        add(_useGPSRestartIntervalField);
        add(_gpsRestartIntervalField);
        add(_gpsRestartRetriesField);
        add(new SeparatorField());
        add(_subsequentModeField);
        add(new SeparatorField());
        add(_isSatelliteInfoRequiredField);
        add(new SeparatorField());
    }

    /**
     * Empties the screen and adds the output fields
     */
    private void showOutputFields() {
        // Remove existing UI components
        deleteAll();

        // Add all output UI components
        add(_supportedSourcesField);
        add(new SeparatorField());
        add(_availableSourcesField);
        add(new SeparatorField());
        add(new SeparatorField());
        add(_currentModeField);
        add(new SeparatorField());
        add(_currentSatellitesCountField);
        add(new SeparatorField());
        add(_currentLocationField);
        add(new SeparatorField());
        add(_currentAverageSatelliteSignalField);
        add(new SeparatorField());
        add(_currentDataSourceField);
        add(new SeparatorField());
        add(_currentErrorField);
        add(new SeparatorField());
        add(_currentStatusField);
        add(new SeparatorField());
        add(new SeparatorField());
        add(_numberUpdatesField);
        add(new SeparatorField());
        add(_numberAssistedUpdatesField);
        add(new SeparatorField());
        add(_numberUnassistedUpdatesField);
        add(new SeparatorField());
        add(_numberValidUpdatesField);
        add(new SeparatorField());
        add(_numberInvalidUpdatesField);
        add(new SeparatorField());
        add(new SeparatorField());
        add(_log);
    }

    /**
     * Displays a message in the log EditField as well as in the device event
     * log
     *
     * @param message
     *            The text to be logged
     */
    private void log(final String message) {
        if (message != null) {
            final String newMsg =
                    formatDate(System.currentTimeMillis()) + message + "\n";

            // Add event to device log
            EventLogger.logEvent(0x9876543212345L, newMsg.getBytes(),
                    EventLogger.ALWAYS_LOG);
            _uiApp.invokeLater(new Runnable() {
                /**
                 * @see java.lang.Runnable#run()
                 */
                public void run() {
                    // If log too long, reset log
                    if (_log.getText().length() > 1500) {
                        _log.setText("");
                    }

                    // Output message to screen
                    _log.setText(_log.getText() + newMsg);
                }
            });
        }
    }

    /**
     * Returns a String representation of a date provided in long format
     *
     * @param date
     *            Date in long format
     * @return String representation of <code>date</code>
     */
    private String formatDate(final long date) {
        final SimpleDateFormat sdf =
                new SimpleDateFormat(SimpleDateFormat.TIME_LONG);
        final Date d = new Date(date);
        final Calendar cal = Calendar.getInstance();
        cal.setTime(d);

        final StringBuffer buff = new StringBuffer();
        buff.append('[');
        buff.append(cal.get(Calendar.DAY_OF_MONTH));
        buff.append('-');
        buff.append(sdf.format(cal, new StringBuffer(), null).toString());
        buff.append("] ");

        return buff.toString();
    }

    /**
     * Resets the fix-related UI items to their initial value
     */
    void resetDataFields() {
        _uiApp.invokeLater(new Runnable() {
            /**
             * @see java.lang.Runnable#run()
             */
            public void run() {
                // Clear all fields and set to default values
                _currentModeField.setText("-");
                _currentSatellitesCountField.setText("-");
                _currentLocationField.setText("-");
                _currentAverageSatelliteSignalField.setText("-");
                _currentDataSourceField.setText("-");
                _currentErrorField.setText("-");
                _currentStatusField.setText("-");
                _numberUpdatesField.setText("0");
                _numberAssistedUpdatesField.setText("0");
                _numberUnassistedUpdatesField.setText("0");
                _numberValidUpdatesField.setText("0");
                _numberInvalidUpdatesField.setText("0");
            }
        });
    }

    /**
     * @see net.rim.device.api.ui.Screen#onClose()
     */
    public boolean onClose() {
        log("Closing Application");

        if (_locThread != null) {
            _locThread.stop();
            _locThread = null;
        }

        return super.onClose();
    }

    /**
     * @see net.rim.device.api.ui.Screen#onSavePrompt()
     */
    public boolean onSavePrompt() {
        // Suppress the save dialog
        return true;
    }

    /**
     * @see net.rim.device.api.ui.container.MainScreen#makeMenu(Menu, int)
     */
    protected void makeMenu(final Menu menu, final int instance) {
        super.makeMenu(menu, instance);

        if (_locThread != null) {
            menu.setDefault(_stopTestItem);
        }
    }

    /**
     * @see net.rim.device.api.ui.FieldChangeListener#fieldChanged(Field, int)
     */
    public void fieldChanged(final Field field, final int context) {
        if (field == _isVerizonField) {
            if (_isVerizonField.getChecked()) {
                _pdeIPField.setLabel("Client ID: ");
                _pdePortField.setLabel("Password: ");
            } else {
                _pdeIPField.setLabel("PDE IP: ");
                _pdePortField.setLabel("PDE Port: ");
            }
        }
    }

    /**
     * Displays the help dialog
     */
    private void displayHelp() {
        final InputStream stream =
                getClass().getResourceAsStream("/resource/help_extended.txt");
        final LineReader lineReader = new LineReader(stream);
        final StringBuffer help = new StringBuffer();

        for (;;) {
            try {
                help.append(new String(lineReader.readLine()));
                help.append('\n');
            } catch (final EOFException eof) {
                // We've reached the end of the file
                break;
            } catch (final IOException ioe) {
                Dialog.alert("LineReader#readLine() threw " + ioe.toString());
                return;
            }
        }

        Dialog.inform(help.toString());
    }

    /**
     * All the location related tasks are performed in this Thread
     */
    private class LocationThread extends Thread {
        /**
         * If true, the application will use a LocationListener to continually
         * provide updates with regard to location. If false, a single call to
         * LocationProvider.getLocation() will be made.
         */
        private boolean _isMultipleFixes = true;

        // Determines the mode of the LocationProvider
        private BlackBerryCriteria _bbCriteria;

        // Counter variables for valid, invalid, assisted, unassisted and total
        // updates
        private int _totalUpdates, _validUpdates, _inValidUpdates,
                _assistedUpdates, _unassistedUpdates;

        // Reference to the BlackBerryLocationProvider
        private BlackBerryLocationProvider _bbProvider;

        // Location object that holds the current fix
        private BlackBerryLocation _bbLocation;

        // Holds integer values representing supported and available location
        // data sources
        private int _supportedSourcesMask, _availableSourcesMask;

        // Indicates whether the thread has been stopped
        private boolean _isStopped;

        /**
         * @see java.lang.Thread#run()
         */
        public void run() {
            // Clear the current data
            resetDataFields();

            if (!LocationInfo.isLocationOn()) {
                LocationInfo.setLocationOn();
            }

            _supportedSourcesMask = LocationInfo.getSupportedLocationSources();
            _availableSourcesMask = LocationInfo.getAvailableLocationSources();

            _uiApp.invokeLater(new Runnable() {
                /**
                 * @see java.lang.Runnable#run()
                 */
                public void run() {
                    _supportedSourcesField
                            .setText(getDataSourceString(_supportedSourcesMask));
                    _availableSourcesField
                            .setText(getDataSourceString(_availableSourcesMask));
                }
            });

            // Setup and connect to the provider
            try {
                setupCriteria();
            } catch (final net.rim.device.api.system.UnsupportedOperationException uoe) {
                log(_primaryModeField.getChoice(_primaryModeField
                        .getSelectedIndex())
                        + " is not supported on this device\nTest stopped");
                return;
            }

            log("Criteria initialized");

            if (!_PDESet) {
                setupPDE();
            }

            log("Starting Updates: " + formatDate(System.currentTimeMillis()));

            setupProvider();
        }

        /*
         * Sets up the PDE server
         */
        private void setupPDE() {
            final String pdeIPText = _pdeIPField.getText();
            final String pdePortText = _pdePortField.getText();

            if (pdeIPText.length() > 0) {
                if (!_isVerizonField.getChecked()) {
                    log("Using PDE: " + pdeIPText + ":" + pdePortText);
                    final boolean setPDESuccess =
                            GPSSettings.setPDEInfo(pdeIPText, Integer
                                    .parseInt(pdePortText));
                    if (setPDESuccess) {
                        _PDESet = true;
                        log("setPDEInfo() successful");
                    }
                } else {
                    // Set Verizon specific settings
                    log("Using VZ Credentials: " + ";" + pdeIPText + ";"
                            + pdePortText);
                    GPSSettings.setPDEInfo(";" + pdeIPText + ";" + pdePortText,
                            0);

                    // Verizon Verizon PDE server sessions time out after
                    // 12 hours. Set up a timer to reset the connection
                    // at ~12 hour intervals.
                    final Timer timer = new Timer();

                    final TimerTask task = new TimerTask() {
                        /**
                         * @see java.util.TimerTask#run()
                         */
                        public void run() {
                            clearVerizonCredential();
                            setupPDE();
                            resetProvider();
                            setupProvider();
                        }
                    };

                    // Set period to just under 12 hours
                    final long period = 1000 * 60 * 60 * 12 - 60000;

                    // Set date to just under 12 hours from now
                    long date = new Date().getTime();
                    date = date + period;

                    timer.scheduleAtFixedRate(task, period, date);
                    _PDESet = true;
                }
            }
        }

        /**
         * Initializes criteria according to the mode selected by the user. The
         * following algorithm is used: If costAllowed = FALSE mode is Stand
         * Alone Otherwise, if costAllowed=TRUE, -if horizontalAccuracy = 0,
         * mode is Data Optimal -if horizontalAccuracy > 0, -if multiple fixes
         * requested, -if Telus, mode is MS-based -otherwise, -if powerUsage =
         * HIGH, mode is Speed Optimal; -if powerUsage != HIGH, mode is MS-based
         * -else if single fix requested, -if powerUsage = HIGH, mode is
         * Accuracy Optimal -if powerUsage != HIGH, mode is PDE Calculate -if
         * powerUsage = LOW mode is Cellsite
         */
        private void setupCriteria() {
            _bbCriteria = new BlackBerryCriteria();
            _bbCriteria.setPreferredResponseTime(Integer
                    .parseInt(_preferredResponseTimeField.getText()));

            if (_enableConcurrentGeolocationField.getChecked()) {
                _bbCriteria
                        .enableGeolocationWithGPS(BlackBerryCriteria.FASTEST_FIX_PREFERRED);
            } else if (_enableGeolocationFallbackField.getChecked()) {
                _bbCriteria.enableGeolocationWithGPS();
            }

            switch (_primaryModeField.getSelectedIndex()) {
            case 0: // Stand Alone(s)
                _isMultipleFixes = false;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_AUTONOMOUS);
                log("Primary mode set to Stand Alone");
                break;
            case 1: // Stand Alone(m)
                _isMultipleFixes = true;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_AUTONOMOUS);
                log("Primary mode set to Stand Alone");
                break;
            case 2: // Data Optimal(m)
                _isMultipleFixes = true;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CDMA_DATA_OPTIMAL);
                log("Primary mode set to Data Optimal");
                break;
            case 3: // Speed Optimal(m)
                _isMultipleFixes = true;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CDMA_SPEED_OPTIMAL);
                log("Primary mode set to Speed Optimal");
                break;
            case 4: // MS-Based(m)
                _isMultipleFixes = true;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CDMA_MS_BASED);
                log("Primary mode set to MS-Based");
                break;
            case 5: // Accuracy Optimal(s)
                _isMultipleFixes = false;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CDMA_ACCURACY_OPTIMAL);
                log("Primary mode set to Accuracy Optimal");
                break;
            case 6: // PDE Calculate(s)
                _isMultipleFixes = false;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CDMA_MS_ASSIST);
                log("Primary mode set to PDE Calculate");
                break;
            case 7: // Cellsite(s)
                _isMultipleFixes = false;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CELLSITE);
                log("Primary mode set to Cellsite(s)");
                break;
            case 8: // Cellsite(m)
                _isMultipleFixes = true;
                _bbCriteria.setMode(GPSInfo.GPS_MODE_CELLSITE);
                log("Primary mode set to Cellsite(m)");
                break;
            case 9: // Default(s)
                _isMultipleFixes = false;
                log("Primary mode set to Default(m)");
                break;
            case 10: // Default(m)
                _isMultipleFixes = true;
                log("Primary mode set to Default(m)");
                break;
            case 11: // Optimal Geolocation(s)
                _isMultipleFixes = false;
                _bbCriteria =
                        new BlackBerryCriteria(LocationInfo.GEOLOCATION_MODE);
                break;
            case 12: // Optimal Geolocation(m)
                _isMultipleFixes = true;
                _bbCriteria =
                        new BlackBerryCriteria(LocationInfo.GEOLOCATION_MODE);
                break;
            case 13: // Cell Geolocation(s)
                _isMultipleFixes = false;
                _bbCriteria =
                        new BlackBerryCriteria(
                                LocationInfo.GEOLOCATION_MODE_CELL);
                break;
            case 14: // Cell Geolocation(m)
                _isMultipleFixes = true;
                _bbCriteria =
                        new BlackBerryCriteria(
                                LocationInfo.GEOLOCATION_MODE_CELL);
                break;
            case 15: // WLAN Geolocation(s)
                _isMultipleFixes = false;
                _bbCriteria =
                        new BlackBerryCriteria(
                                LocationInfo.GEOLOCATION_MODE_WLAN);
                break;
            case 16: // WLAN Geolocation(m)
                _isMultipleFixes = true;
                _bbCriteria =
                        new BlackBerryCriteria(
                                LocationInfo.GEOLOCATION_MODE_WLAN);
                break;
            }

            if (_failOverModeField.getSelectedIndex() < 6) {
                final int foRetries =
                        Integer.parseInt(_failOverRetriesField.getText());
                final int foTimeout =
                        Integer.parseInt(_failoverTimeoutField.getText());

                switch (_failOverModeField.getSelectedIndex()) {
                case 0: // Stand Alone
                    _bbCriteria.setFailoverMode(GPSInfo.GPS_MODE_AUTONOMOUS,
                            foRetries, foTimeout);
                    log("failOverMode set to Stand Alone");
                    break;
                case 1: // Data Optimal
                    _bbCriteria.setFailoverMode(
                            GPSInfo.GPS_MODE_CDMA_DATA_OPTIMAL, foRetries,
                            foTimeout);
                    log("failOverMode set to Data Optimal");
                    break;
                case 2: // Speed Optimal
                    _bbCriteria.setFailoverMode(
                            GPSInfo.GPS_MODE_CDMA_SPEED_OPTIMAL, foRetries,
                            foTimeout);
                    log("failOverMode set to Speed Optimal");
                    break;
                case 3: // MS-Based
                    _bbCriteria.setFailoverMode(GPSInfo.GPS_MODE_CDMA_MS_BASED,
                            foRetries, foTimeout);
                    log("failOverMode set to MS-Based");
                    break;
                case 4: // Accuracy Optimal
                    _bbCriteria.setFailoverMode(
                            GPSInfo.GPS_MODE_CDMA_ACCURACY_OPTIMAL, foRetries,
                            foTimeout);
                    log("failOverMode set to Accuracy Optimal");
                    break;
                case 5: // PDE Calculate
                    _bbCriteria.setFailoverMode(
                            GPSInfo.GPS_MODE_CDMA_MS_ASSIST, foRetries,
                            foTimeout);
                    log("failOverMode set to PDE Calculate");
                    break;
                }
            }

            // Apply user settings
            if (_useGPSRestartIntervalField.getChecked()) {
                final int interval =
                        Integer.parseInt(_gpsRestartIntervalField.getText());
                final int maximumRetry =
                        Integer.parseInt(_gpsRestartRetriesField.getText());
                _bbCriteria.setGPSRestartInterval(interval, maximumRetry);
            }

            if (_isSatelliteInfoRequiredField.getChecked()) {
                _bbCriteria.setSatelliteInfoRequired(true, true);
            }

            if (_subsequentModeField.getSelectedIndex() < 6) {
                switch (_subsequentModeField.getSelectedIndex()) {
                case 0: // Stand Alone
                    _bbCriteria.setSubsequentMode(GPSInfo.GPS_MODE_AUTONOMOUS);
                    log("subsequentMode set to Stand Alone");
                    break;
                case 1: // Data Optimal
                    _bbCriteria
                            .setSubsequentMode(GPSInfo.GPS_MODE_CDMA_DATA_OPTIMAL);
                    log("subsequentMode set to Data Optimal");
                    break;
                case 2: // Speed Optimal
                    _bbCriteria
                            .setSubsequentMode(GPSInfo.GPS_MODE_CDMA_SPEED_OPTIMAL);
                    log("subsequentMode set to Speed Optimal");
                    break;
                case 3: // MS-Based
                    _bbCriteria
                            .setSubsequentMode(GPSInfo.GPS_MODE_CDMA_MS_BASED);
                    log("subsequentMode set to MS-Based");
                    break;
                case 4: // Accuracy Optimal
                    _bbCriteria
                            .setSubsequentMode(GPSInfo.GPS_MODE_CDMA_ACCURACY_OPTIMAL);
                    log("subsequentMode set to Accuracy Optimal");
                    break;
                case 5: // PDE Calculate
                    _bbCriteria
                            .setSubsequentMode(GPSInfo.GPS_MODE_CDMA_MS_ASSIST);
                    log("subsequentMode set to PDE Calculate");
                    break;
                }
            }
        }

        /**
         * Reset logic for LocationProvider
         */
        private void resetProvider() {
            log("Resetting LocationProvider");
            _bbProvider.setLocationListener(null, 0, 0, 0);
            _bbProvider.reset();
            _bbProvider = null;
        }

        /**
         * Reset credential logic for Verizon. The Verizon PDE session needs to
         * be refreshed every 12 hours (contact Verizon for more information).
         */
        private void clearVerizonCredential() {
            final Thread resetThread = new Thread() {
                /**
                 * @see java.lang.Thread#run()
                 */
                public void run() {
                    final BlackBerryCriteria oldBBCriteria = _bbCriteria;
                    _bbCriteria.setMode(GPSInfo.GPS_MODE_CDMA_MS_ASSIST);
                    LocationProvider tempProvider = null;

                    try {
                        tempProvider =
                                LocationProvider.getInstance(_bbCriteria);
                    } catch (final LocationException e) {
                        log(e.toString());
                    }

                    if (tempProvider != null) {
                        log("Clearing VZ credentials. Please wait...");

                        try {
                            Thread.sleep(2000);
                        } catch (final InterruptedException e) {
                            log(e.toString());
                        }

                        GPSSettings.setPDEInfo("127.0.0.1", 0);

                        try {
                            Thread.sleep(2000);
                        } catch (final InterruptedException e) {
                            log(e.toString());
                        }

                        try {
                            tempProvider.getLocation(1);
                        } catch (final Exception e) {
                            log(e.toString());
                        }

                        try {
                            Thread.sleep(15000);
                        } catch (final InterruptedException e) {
                            log(e.toString());
                        }

                        tempProvider = null;
                        log("Old Verizon session cleared");
                    }
                    _bbCriteria = oldBBCriteria;
                }
            };
            resetThread.start();
            try {
                resetThread.join();
            } catch (final InterruptedException e) {
                log(e.toString());
            }
        }

        /**
         * This method initializes the LocationProvider and sets a
         * LocationListener if <code>isMultipleFixes</code> is TRUE. Otherwise
         * it simply calls singleFixLocationUpdate() which calls
         * LocationProvider.getLocation() once to get a single fix.
         */
        private void setupProvider() {
            try {
                // Disable resetNow
                if (_resetNow) {
                    _resetNow = false;
                }

                log("setupProvider()");

                try {
                    // Sleep to ensure _bbProvider and _bbCriteria have enough
                    // time to be instantiated
                    Thread.sleep(5000);
                } catch (final InterruptedException ie) {
                    log(ie.toString());
                }

                _bbProvider =
                        (BlackBerryLocationProvider) LocationProvider
                                .getInstance(_bbCriteria);
                log("LocationProvider initialized");
                if (_bbProvider != null) {
                    if (_isMultipleFixes) {
                        final int frequency =
                                Integer.parseInt(_frequencyField.getText());
                        final int timeout =
                                Integer.parseInt(_timeoutField.getText());
                        final int maxage =
                                Integer.parseInt(_maxAgeField.getText());
                        _bbProvider.setLocationListener(new LocListener(),
                                frequency, timeout, maxage);
                        log("LocationListener started");
                    } else {
                        log("Initiating single shot GPS fix");
                        singleFixLocationUpdate();
                    }
                } else {
                    log("Provider unavailable for Criteria");
                }
            } catch (final LocationException le) {
                log(le.toString());
            }
        }

        /**
         * Gets a single fix by calling LocationProvider.getLocation(). Updates
         * the UI with the fix information. In case of a valid fix it maps the
         * fix by invoking the Maps application.
         */
        private void singleFixLocationUpdate() {
            try {
                _bbLocation =
                        (BlackBerryLocation) _bbProvider.getLocation(Integer
                                .parseInt(_timeoutField.getText()));
            } catch (final InterruptedException ie) {
                log("InterruptedException thrown by getLocation(): "
                        + ie.getMessage());
            } catch (final LocationException le) {
                log("LocationException thrown by getLocation(): "
                        + le.getMessage());
            }

            if (_bbLocation != null) {
                logLocation(_bbLocation);
            } else {
                log("Location is null");
            }
        }

        /**
         * Displays and logs information about the given location object
         *
         * @param location
         *            location object to display and log
         */
        private void logLocation(final BlackBerryLocation location) {
            _uiApp.invokeLater(new Runnable() {
                /**
                 * @see java.lang.Runnable#run()
                 */
                public void run() {
                    _numberUpdatesField.setText(Integer
                            .toString(++_totalUpdates));
                }
            });
            if (location.isValid()) {
                _uiApp.invokeLater(new Runnable() {
                    /**
                     * @see java.lang.Runnable#run()
                     */
                    public void run() {
                        // Update UI fields to reflect new location
                        _currentModeField.setText(getGPSModeString(location
                                .getGPSMode())
                                + getLocMethodString(location
                                        .getLocationMethod()));

                        final StringBuffer buff =
                                new StringBuffer(location
                                        .getQualifiedCoordinates()
                                        .getLatitude()
                                        + " ");
                        buff.append(location.getQualifiedCoordinates()
                                .getLongitude());
                        buff.append(' ');
                        buff.append(location.getQualifiedCoordinates()
                                .getAltitude());
                        buff.append(' ');
                        _currentLocationField.setText(buff.toString());

                        _currentSatellitesCountField.setText(Integer
                                .toString(location.getSatelliteCount()));
                        _currentAverageSatelliteSignalField.setText(Integer
                                .toString(location
                                        .getAverageSatelliteSignalQuality()));
                        _currentDataSourceField
                                .setText(getDataSourceString(location
                                        .getDataSource()));
                        _currentErrorField.setText(getErrorMessage(location
                                .getError()));
                        _currentStatusField.setText(getStatusString(location
                                .getStatus()));

                        _numberValidUpdatesField.setText(Integer
                                .toString(++_validUpdates));

                        if (location.getGPSMode() != GPSInfo.GPS_MODE_AUTONOMOUS) {
                            _numberAssistedUpdatesField.setText(Integer
                                    .toString(++_assistedUpdates));
                        } else {
                            _numberUnassistedUpdatesField.setText(Integer
                                    .toString(++_unassistedUpdates));
                        }
                    }
                });

                StringBuffer buff = new StringBuffer();
                buff.append(location.getQualifiedCoordinates().getLatitude());
                buff.append(", ");
                buff.append(location.getQualifiedCoordinates().getLongitude());
                buff.append(' ');
                buff.append(location.getQualifiedCoordinates().getAltitude());

                if (_isMultipleFixes) {
                    _currentLocationField.setText("Valid single fix: "
                            + buff.toString());
                } else {
                    log("Valid multiple fix: " + buff.toString());
                }

                buff = new StringBuffer("\tGPS Mode: ");
                buff.append(getGPSModeString(location.getGPSMode()));
                buff.append(getLocMethodString(location.getLocationMethod()));
                buff.append(", Satellite Count: ");
                buff.append(Integer.toString(location.getSatelliteCount()));
                buff.append(", Signal Strength: ");
                buff.append(Integer.toString(location
                        .getAverageSatelliteSignalQuality()));
                log(buff.toString());

                buff = new StringBuffer("\tData Source: ");
                buff.append(getDataSourceString(location.getDataSource()));
                buff.append(", GPS Error: ");
                buff.append(getErrorMessage(location.getError()));
                buff.append(", Status: ");
                buff.append(getStatusString(location.getStatus()));
                log(buff.toString());

                if (_isMapLocationField.getChecked()) {
                    // Launch the Maps application to display the given location
                    displayLocationOnMap(location);
                }
            } else {
                if (_isMultipleFixes && _resetNow) {
                    resetProvider();
                    setupProvider();
                    return;
                }

                _uiApp.invokeLater(new Runnable() {
                    /**
                     * @see java.lang.Runnable#run()
                     */
                    public void run() {
                        // Update the UI to reflect invalid fix
                        _currentModeField.setText(getGPSModeString(location
                                .getGPSMode()));
                        _currentLocationField.setText("*UNKNOWN*");
                        _currentSatellitesCountField.setText(Integer
                                .toString(location.getSatelliteCount()));
                        _currentAverageSatelliteSignalField.setText(Integer
                                .toString(location
                                        .getAverageSatelliteSignalQuality()));
                        _currentDataSourceField
                                .setText(getDataSourceString(location
                                        .getDataSource()));
                        _currentErrorField.setText(getErrorMessage(location
                                .getError()));
                        _currentStatusField.setText(getStatusString(location
                                .getStatus()));

                        _numberInvalidUpdatesField.setText(Integer
                                .toString(++_inValidUpdates));
                    }
                });
                if (_isMultipleFixes) {
                    log("Invalid multiple fix");
                } else {
                    log("Invalid single fix");
                }

                StringBuffer buff = new StringBuffer("\tGPS Mode: ");
                buff.append(getGPSModeString(location.getGPSMode()));
                buff.append(getLocMethodString(location.getLocationMethod()));
                buff.append(", Satellite Count: ");
                buff.append(Integer.toString(location.getSatelliteCount()));
                buff.append(", Signal Strength: ");
                buff.append(Integer.toString(location
                        .getAverageSatelliteSignalQuality()));
                log(buff.toString());

                buff = new StringBuffer("\tData Source: ");
                buff.append(getDataSourceString(location.getDataSource()));
                buff.append(", GPS Error: ");
                buff.append(getErrorMessage(location.getError()));
                buff.append(", Status: ");
                buff.append(getStatusString(location.getStatus()));
                log(buff.toString());
            }
        }

        /**
         * Returns a String representation of a given fix status code
         *
         * @param status
         *            Given status code
         * @return String representation of status code
         */
        private String getStatusString(final int status) {
            final StringBuffer statusString = new StringBuffer();

            switch (status) {
            case BlackBerryLocation.GPS_ERROR:
                statusString.append("*ERROR");
                break;
            case BlackBerryLocation.GPS_FIX_COMPLETE:
                statusString.append("*FIX_COMPLETE");
                break;
            case BlackBerryLocation.GPS_FIX_PARTIAL:
                statusString.append("*FIX_PARTIAL");
                break;
            case BlackBerryLocation.GPS_FIX_UNAVAILABLE:
                statusString.append("*FIX_UNAVAILABLE");
                break;
            case BlackBerryLocation.FAILOVER_MODE_ON:
                statusString.append("*FAILOVER_MODE_ON");
                break;
            case BlackBerryLocation.SUBSEQUENT_MODE_ON:
                statusString.append("*SUBSEQUENT_MODE_ON");
                break;
            }

            statusString.append("*");

            return statusString.toString();
        }

        /**
         * Returns a String representation for a given data source
         *
         * @param source
         *            Integer representation of data source
         * @return String representation of data source
         */
        private String getDataSourceString(final int source) {
            final StringBuffer result = new StringBuffer("*");

            switch (source) {
            case GPSInfo.GPS_DEVICE_BLUETOOTH:
                result.append("GPS_DEVICE_BLUETOOTH");
                break;
            case GPSInfo.GPS_DEVICE_INTERNAL:
                result.append("GPS_DEVICE_INTERNAL");
                break;
            case LocationInfo.LOCATION_SOURCE_GEOLOCATION:
                result.append("LOCATION_SOURCE_GEOLOCATION");
                break;
            case LocationInfo.LOCATION_SOURCE_GEOLOCATION_CELL:
                result.append("LOCATION_SOURCE_GEOLOCATION_CELL");
                break;
            case LocationInfo.LOCATION_SOURCE_GEOLOCATION_WLAN:
                result.append("LOCATION_SOURCE_GEOLOCATION_WLAN");
                break;
            default:
                return "*UNKNOWN*";

            }

            result.append("*");

            return result.toString();
        }

        /**
         * Returns a String representation of the location method being used
         *
         * @param method
         *            The location method for which to retrieve a string
         * @return location Location method String
         */
        private String getLocMethodString(final int method) {
            final StringBuffer buf = new StringBuffer();

            if ((method & Location.MTA_ASSISTED) != 0) {
                buf.append("*MTA_ASSISTED");
            }
            if ((method & Location.MTA_UNASSISTED) != 0) {
                buf.append("*MTA_UNASSISTED");
            }
            if ((method & Location.MTE_ANGLEOFARRIVAL) != 0) {
                buf.append("*MTE_ANGLEOFARRIVAL");
            }
            if ((method & Location.MTE_CELLID) != 0) {
                buf.append("*MTE_CELLID");
            }
            if ((method & Location.MTE_SATELLITE) != 0) {
                buf.append("*MTE_SATELLITE");
            }
            if ((method & Location.MTE_SHORTRANGE) != 0) {
                buf.append("*MTE_SHORTRANGE");
            }
            if ((method & Location.MTE_TIMEDIFFERENCE) != 0) {
                buf.append("*MTE_TIMEDIFFERENCE");
            }
            if ((method & Location.MTE_TIMEOFARRIVAL) != 0) {
                buf.append("*MTE_TIMEOFARRIVAL");
            }
            if ((method & Location.MTY_NETWORKBASED) != 0) {
                buf.append("*MTY_NETWORKBASED");
            }
            if ((method & Location.MTY_TERMINALBASED) != 0) {
                buf.append("*MTY_TERMINALBASED");
            }

            buf.append("*");

            if (buf.length() < 2) {
                return "";
            } else {
                return buf.toString();
            }
        }

        /**
         * Returns a String representation of a given GPS mode
         *
         * @param mode
         *            GPS mode for which to retrieve a String
         * @return String representation of GPS mode
         */
        private String getGPSModeString(final int mode) {
            final StringBuffer modeString = new StringBuffer();

            if (mode == GPSInfo.GPS_MODE_ASSIST) {
                modeString.append("*ASSIST");
            }
            if (mode == GPSInfo.GPS_MODE_AUTONOMOUS) {
                modeString.append("*AUTONOMOUS");
            }
            if (mode == GPSInfo.GPS_MODE_BT) {
                modeString.append("*BT");
            }
            if (mode == GPSInfo.GPS_MODE_CDMA_ACCURACY_OPTIMAL) {
                modeString.append("*CDMA_ACCURACY_OPTIMAL");
            }
            if (mode == GPSInfo.GPS_MODE_CDMA_DATA_OPTIMAL) {
                modeString.append("*CDMA_DATA_OPTIMAL");
            }
            if (mode == GPSInfo.GPS_MODE_CDMA_MS_ASSIST) {
                modeString.append("*CDMA_MS_ASSIST");
            }
            if (mode == GPSInfo.GPS_MODE_CDMA_MS_BASED) {
                modeString.append("*CDMA_MS_BASED");
            }
            if (mode == GPSInfo.GPS_MODE_CDMA_SPEED_OPTIMAL) {
                modeString.append("*CDMA_SPEED_OPTIMAL");
            }
            if (mode == GPSInfo.GPS_MODE_CELLSITE) {
                modeString.append("*CELLSITE");
            }
            if (mode == GPSInfo.GPS_MODE_NONE) {
                modeString.append("*NONE");
            }
            if (mode == LocationInfo.GEOLOCATION_MODE_WLAN) {
                modeString.append("*GEOLOCATION_MODE_WLAN");
            } else if (mode == LocationInfo.GEOLOCATION_MODE_CELL) {
                modeString.append("*GEOLOCATION_MODE_CELL");
            } else if (mode == LocationInfo.GEOLOCATION_MODE) {
                modeString.append("*GEOLOCATION_MODE");
            }

            modeString.append("*");

            if (modeString.length() < 2) {
                return "";
            } else {
                return modeString.toString();
            }
        }

        /**
         * Invoke the Maps application to show the fix on a map
         *
         * @param location
         *            The Location object to map
         */
        private void displayLocationOnMap(final Location location) {
            try {
                String lon =
                        Double.toString(location.getQualifiedCoordinates()
                                .getLongitude() * 100000);
                lon = lon.substring(0, 8);
                String lat =
                        Double.toString(location.getQualifiedCoordinates()
                                .getLatitude() * 100000);
                lat = lat.substring(0, 7);
                final StringBuffer document =
                        new StringBuffer("<lbs><location lon='");
                document.append(lon);
                document.append("' lat='");
                document.append(lat);
                document.append("' label='MyLocation' zoom='");
                document.append(_zoomLevelField.getText());
                document.append("'/></lbs>");

                Invoke.invokeApplication(Invoke.APP_TYPE_MAPS,
                        new MapsArguments(MapsArguments.ARG_LOCATION_DOCUMENT,
                                document.toString()));
            } catch (final Exception e) {
                log("Unable to map Location. Please make sure that BlackBerry Maps is installed.");
            }
        }

        /**
         * Resets the BlackBerryLocationProvider and removes reference
         */
        public void stop() {
            _isStopped = true;

            // Log the statistics for the location session
            log("Stopping Updates: " + formatDate(System.currentTimeMillis()));
            log("Total Updates: " + _numberUpdatesField);
            log("Assisted Updates: " + _numberAssistedUpdatesField);
            log("Unassisted Updates: " + _numberUnassistedUpdatesField);
            log("Valid Updates: " + _numberValidUpdatesField);
            log("Invalid Updates: " + _numberInvalidUpdatesField);

            if (_bbProvider != null) {
                _bbProvider.setLocationListener(null, 0, 0, 0);
                _bbProvider.reset();
                _bbProvider = null;
            }
        }

        /**
         * Returns the running/stopped status of this thread
         *
         * @return The running/stopped status of this thread
         */
        boolean isStopped() {
            return _isStopped;
        }

        /**
         * Returns a readable error message for a given GPS error code
         *
         * @param err
         *            Error code
         * @return Human readable error message
         */
        private String getErrorMessage(final int err) {
            String msg = "";

            switch (err) {
            case GPSInfo.GPS_ERROR_ALMANAC_OUTDATED:
                msg = "Almanac outdated";
                break;
            case GPSInfo.GPS_ERROR_AUTHENTICATION_FAILURE:
                msg = "Authentication failed with the network";
                break;
            case GPSInfo.GPS_ERROR_CHIPSET_DEAD:
                msg = "GPS chipset dead; no fix";
                break;
            case GPSInfo.GPS_ERROR_DEGRADED_FIX_IN_ALLOTTED_TIME:
                msg = "Degraded fix; poor accuracy";
                break;
            case GPSInfo.GPS_ERROR_GPS_LOCKED:
                msg = "GPS service locked";
                break;
            case GPSInfo.GPS_ERROR_INVALID_NETWORK_CREDENTIAL:
                msg = "Invalid network credential";
                break;
            case GPSInfo.GPS_ERROR_INVALID_REQUEST:
                msg = "Request is invalid";
                break;
            case GPSInfo.GPS_ERROR_LOW_BATTERY:
                msg = "Low battery; fix cannot be obtained";
                break;
            case GPSInfo.GPS_ERROR_NETWORK_CONNECTION_FAILURE:
                msg = "Unable to connect to the data network";
                break;
            case GPSInfo.GPS_ERROR_NO_FIX_IN_ALLOTTED_TIME:
                msg = "No fix obtained in alloted time.";
                break;
            case GPSInfo.GPS_ERROR_NO_SATELLITE_IN_VIEW:
                msg =
                        "No Satellite is in view or the signal strength is too low to get a position fix";
                break;
            case GPSInfo.GPS_ERROR_NONE:
                msg = "No GPS Error";
                break;
            case GPSInfo.GPS_ERROR_PRIVACY_ACCESS_DENIED:
                msg = "Privacy setting denies getting a fix";
                break;
            case GPSInfo.GPS_ERROR_SERVICE_UNAVAILABLE:
                msg =
                        "GPS service is not available due to no cellular service or no data service or no resources, etc.";
                break;
            case GPSInfo.GPS_ERROR_TIMEOUT_DEGRADED_FIX_NO_ASSIST_DATA:
                msg = "Degraded fix (no assist data); poor accuracy";
                break;
            case GPSInfo.GPS_ERROR_TIMEOUT_NO_FIX_NO_ASSIST_DATA:
                msg = "No fix in alloted time, no assist";
                break;
            default:
                msg = "Unknown error";
                break;
            }

            return msg;
        }

        /**
         * LocationListener implementation
         */
        private class LocListener implements LocationListener {
            /**
             * @see javax.microedition.location.LocationListener#locationUpdated(LocationProvider,
             *      Location)
             */
            public void locationUpdated(final LocationProvider provider,
                    final Location location) {
                _bbLocation = (BlackBerryLocation) location;
                if (_bbLocation != null) {
                    logLocation(_bbLocation);
                } else {
                    log("Location is null");
                }
            }

            /**
             * @see javax.microedition.location.LocationListener#providerStateChanged(LocationProvider,
             *      int)
             */
            public void providerStateChanged(final LocationProvider provider,
                    final int newState) {
                switch (newState) {
                case LocationProvider.OUT_OF_SERVICE: // Triggered when a BES
                                                      // policy does not allow
                                                      // location capabilities
                    log("State Change: Out of Service");
                    break;
                case LocationProvider.TEMPORARILY_UNAVAILABLE: // Triggered when
                                                               // the system has
                                                               // stopped
                                                               // looking for a
                                                               // fix
                    log("State Change: Temp Unavailable");
                    log("Resetting Location Provider due to TEMPORARILY UNAVAILABLE state");
                    _resetNow = true;
                    break;
                }
            }
        }
    }

}
TOP

Related Classes of com.rim.samples.device.gpsdemoadvanced.ExtendedGPSDiagnosticScreen

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.