⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bluetoothgps.java

📁 关于J4ME J2ME实例
💻 JAVA
字号:
package org.j4me.bluetoothgps;

import java.io.*;
import javax.microedition.io.*;
import org.j4me.logging.*;
import org.j4me.util.*;

/**
 * Main class for communication with GPS receiver. Use this class to access GPS
 * receiver from other classes.
 */
class BluetoothGPS implements Runnable {

    /**
     * The timeout value for Bluetooth connections in milliseconds.
     * Since this tries to connect on 10 Bluetooth channels, the
     * total timeout for connecting is 10x this number.
     * <p>
     * The emulator's default timeout is 10,000 ms.
     */
    private static final short BLUETOOTH_TIMEOUT = 3000;

    /**
     * Time in ms to wait until resume to receive.
     */
    private static final short BREAK = 500;

    /**
     * Wait after calling disconnect
     */
    private static final short DISCONNECT_WAIT = 1000;

    /**
     * Time in ms to sleep before each read. This seems to solve the problem or
     * read hangs.
     */
    public static final short SLEEP_BEFORE_READ = 100;

    /**
     * How long to wait before we just kill the read. We add the sleep value
     * since this sleep is performed before every read and we start the timer
     * before the pre-read sleep.
     */
    public static final short READ_TIMEOUT = SLEEP_BEFORE_READ + 1000;

    /**
     * How long to wait to initialize the bluetooth connection
     */
    public static final short BLUETOOTH_CONNECTION_INIT_SLEEP = 200;
    
	/**
	 * The number of days since January 1 for the start of a month.  This does not
	 * include leap year days.
	 * 
	 * @see #convertUTCTime(String, String)
	 */
	private static final int MONTH_OFFSET[] =
			{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
	
    /**
     * Connection to bluetooth device.
     */
    private StreamConnection connection;

    /**
     * The input stream from the GPS device.  Location data is received through it.
     */
    private InputStream inputStream;

    /**
     * The output stream to the GPS device.  Configuration commands are sent through it.
     */
    private OutputStream outputStream;
    
    /**
     * Receiving happens in separate thread.
     */
    private Thread runner;

    /**
     * Flag to indicate that the runner thread should stop
     */
    private boolean stop = false;

    /**
     * URL used to connect to bluetooth device.
     */
    private String url;

    /**
     * Listener to notify of location events.  If this is <code>null</code> then
     * don't notify anything of location events.
     */
    private LocationListener locationListener;

    /**
     * The source of location information.
     */
    private final BluetoothLocationProvider locationProvider;

    /**
     * The interval, in milliseconds, between calls made to the registered
     * <code>LocationListener.locationUpdated</code>.
     * 
     * @see #setLocationListener(LocationListener, BluetoothLocationProvider)
     */
    private long locationUpdateInterval;
    
    /**
     * The system time for when <code>LocationListener.locationUpdated</code>
     * was last raised.
     * 
     * @see #locationUpdateInterval
     */
    private long lastLocationUpdateTime;

    /**
     * The last <code>Location</code> obtained from the GPS.  This is the provider's
     * best guess about the current location.  It is usually less than a second old.
     */
    private Location location;
    
    /**
     * Creates new receiver. Does not start automatically, use start() instead.
     *
     * @param url -
     *            URL of bluetooth device to connect to.
     */
    public BluetoothGPS(BluetoothLocationProvider provider, String url) {
    	this.locationProvider = provider;
        this.url = url;
    }
    
    /**
     * @return The last <code>Location</code> obtained from the GPS or <code>null</code>
     *  if no location has yet been obtained.
     */
    public Location getLastKnownLocation ()
    {
    	return location;
    }

    /**
     * Establishes a bluetooth serial connection (specified in GPS_BT_URL) and
     * opens an input stream.
     *
     * @see #isConnected()
     * @see #disconnect()
     *
     * @throws ConnectionNotFoundException - If the target of the name cannot be found, or if the requested protocol type is not supported. 
     * @throws IOException - If error occurs while establishing bluetooth connection or opening input stream. 
     * @throws SecurityException - May be thrown if access to the protocol handler is prohibited.
     */
    private synchronized void connect()
    	throws ConnectionNotFoundException, IOException, SecurityException {
    	
        if (!isConnected()) {
        	// Connect to the GPS device.
            Log.info("Connecting to Bluetooth device at " + url);

            connection = (StreamConnection) ConnectorHelper.open(
            		url, Connector.READ_WRITE, BLUETOOTH_TIMEOUT );

            Log.debug("Bluetooth connection established");

            // Record the connection.
            configureBluetoothGPSSettings(connection);

            inputStream = connection.openInputStream();
            outputStream = connection.openOutputStream();
        }
    }

    /**
     * Configure the GPS device.
     * <p>
     * This sends NMEA input sentences to the Bluetooth GPS device.  The type and
     * frequency of output sentences sent back from the device should be altered
     * such that we do not receive messages we do not care about (to avoid the
     * overhead of processing them) and we receive the messages we do care about
     * once a second (maximum rate so that if any are corrupt we get our data as
     * fast as possible).
     * <p>
     * On a few devices it is possible to adjust the baud rate.  However, this is
     * not a good option.  It isn't the speed data is transmitted (actually faster
     * is better), it is the amount of quality data that comes through.
     * <p>
     * A good list of the proprietary input sentences is here:
     * http://www.gpsinformation.org/dale/nmea.htm
     * 
     * @param connection
     *            is the connection object to the Bluetooth GPS unit. The
     *            connection must be {@link Connector#READ} or
     *            {@link Connector#READ_WRITE}.
     */
    private void configureBluetoothGPSSettings(StreamConnection connection)
    {
        if (outputStream != null) {
        	try {

        		// Send SiRF configuration.
            	//  These are specific to the SiRF chipset and are ignored by others.
            	//  They are also ignored if the GPS device is in SiRF mode which it
            	//  should not be.
	        	//
	        	//  The sentences are discussed here:
	        	//     http://www.gpsinformation.org/dale/nmea.htm#sirf
	        	//     http://www.elgps.com/public_ftp/Documentos/SIRF_Protocol.pdf
	        	//  They can be tested using the SiRFDemo application:
	        	//     http://www.gpspassion.com/forumsen/topic.asp?TOPIC_ID=25575
        		//
            	// The Bluetooth modems in SiRF devices do not allow the baud rate
            	// to be changed.  It is usually 38400 or higher.
            	// The SiRF input sentence that controls output sentences is:
            	//     $PSRF103,05,00,01,01*20
				//	where
				//	   $PSRF103
				//	   05         00=GGA
				//	              01=GLL
				//	              02=GSA
				//	              03=GSV
				//	              04=RMC
				//	              05=VTG
            	//                ... through 10
				//	   00         mode, 0=set rate, 1=query
				//	   01         rate in seconds, 0-255
				//	   01         checksum 0=no, 1=yes
				//	   *20        checksum
            	
            	// Send the NMEA sentences we care about every second.
        		outputStream.write( createSentence("PSRF103,00,00,01,01") );  // GPGGA
        		outputStream.write( createSentence("PSRF103,02,00,01,01") );  // GPGSA
        		outputStream.write( createSentence("PSRF103,04,00,01,01") );  // GPRMC

            	// Disable the remaining sentences.
            	//     This avoids the overhead of receiving them, processing them, and
            	//   throwing them away.  They can be very frequent and cause problems
            	//   for slow processors such as on the Motorola SLVR.
            	//     Not all of these are NMEA sentences.  Some are SiRF specific
            	//   PSRFTXT sentences which are the most frequent and therefore most
            	//   problematic.
        		outputStream.write( createSentence("PSRF103,01,00,00,01") );  // GPGLL
        		outputStream.write( createSentence("PSRF103,03,00,00,01") );  // GPGSV
        		outputStream.write( createSentence("PSRF103,05,00,00,01") );  // GPVTG
        		outputStream.write( createSentence("PSRF103,06,00,00,01") );  // GPMSS
        		outputStream.write( createSentence("PSRF103,07,00,00,01") );  // ? (Untested but might be the PSRFTXT we turn off)
        		outputStream.write( createSentence("PSRF103,08,00,00,01") );  // ? (Untested but might be the PSRFTXT we turn off)
        		outputStream.write( createSentence("PSRF103,09,00,00,01") );  // GPZDA
        		outputStream.write( createSentence("PSRF103,10,00,00,01") );  // ? (Untested but might be the PSRFTXT we turn off)
                
	            
	            // Send Garmin configuration. 
				//	Garmin device programming (see section 3.1.5)
				//	http://www.garmin.com/manuals/GPS10_TechnicalSpecifications.pdf
            	//
            	//  Output sentence enable/disable (PGRMO).  The format is:
            	//     $PGRMO,<1>,<2>*hh\r\n
				//	where
            	//     <1> Target sentence description (e.g. GPGSV)
            	//     <2> Mode where:
            	//          0 = disable specific sentence
            	//          1 = enable specific sentence
            	//          2 = disable all output sentences
            	//          3 = enable all output sentences (except GPALM)
            	//          4 = restore factory default output sentences
        		outputStream.write( createSentence("PGRMO,,2") );  // Turn off all sentences
        		outputStream.write( createSentence("PGRMO,GPGGA,1") );  // Turn on GPGGA
            	outputStream.write( createSentence("PGRMO,GPGSA,1") );  // Turn on GPGSA
            	outputStream.write( createSentence("PGRMO,GPRMC,1") );  // Turn on GPRMC

            	
            	// Note the following doesn't work.  The iBlue is apparently locked
            	// at the factory presets according to a note on a discussion board.
            	//
            	// Send Martech (MTK) configuration.  It is the chipset used in the i-Blue 747.
            	//  MTK is produced by Transystem, a company in Taiwan.  It is a chipset
            	//  comparable to the SiRF III.  See the programming guide:
            	//  http://www.transystem.com.tw/driver_manual/EB-230-Data-Sheet-V1.2.pdf
            	//
            	//  Output sentence to enable frequency of input sentences is:
            	//     $PMTK314,<0>,...,<18>*hh\r\n
            	//  where each field
            	//     0=off, 1=every second, 2=every two seconds, etc.
            	//  and the field numbers are
				//	   0 NMEA_SEN_GLL, // GPGLL interval - Geographic Position - Latitude longitude
				//	   1 NMEA_SEN_RMC, // GPRMC interval - Recommended Min. specific GNSS sentence
				//	   2 NMEA_SEN_VTG, // GPVTG interval - Course Over Ground and Ground Speed
				//	   3 NMEA_SEN_GGA, // GPGGA interval - GPS Fix Data
				//	   4 NMEA_SEN_GSA, // GPGSA interval - GNSS DOPS and Active Satellites
				//	   5 NMEA_SEN_GSV, // GPGSV interval - GNSS Satellites in View
				//	   6 NMEA_SEN_GRS, // GPGRS interval - GNSS Range Residuals
				//	   7 NMEA_SEN_GST, // GPGST interval - GNSS Pseudorange Error Statistics
				//	   13 NMEA_SEN_MALM, // PMTKALM interval - GPS almanac information
				//	   14 NMEA_SEN_MEPH, // PMTKEPH interval - GPS ephemeris information
				//	   15 NMEA_SEN_MDGP, // PMTKDGP interval - GPS differential correction information
				//	   16 NMEA_SEN_MDBG, // PMTKDBG interval 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -