org.j4me.bluetoothgps
Class LocationProvider

java.lang.Object
  extended by org.j4me.bluetoothgps.LocationProvider
Direct Known Subclasses:
MockLocationProvider

public abstract class LocationProvider
extends java.lang.Object

This is the starting point for applications using this API and represents a source of the location information. A LocationProvider represents a location-providing module, generating Locations.

Applications obtain LocationProvider instances (classes implementing the actual functionality by extending this abstract class) by calling the factory method. It is the responsibility of the implementation to return the correct LocationProvider-derived object.

Applications that need to specify criteria for the location provider selection, must first create a Criteria object, and pass it to the factory method. The methods that access the location related information shall throw SecurityException if the application does not have the relevant permission to access the location information.

A typical implementation will get a list of Bluetooth devices and let the user select their GPS device. Then it will persist that address using the J2ME Record Management System (RMS) for the future. Once the address is known, we can use that as criteria for selecting the GPS device. The following demonstrates how to do this (note it is a lengthy operation and should be handled appropriately such as on a different thread):

        // Create our location criteria assuming the hosting device has it.
        Criteria criteria = new Criteria();
        criteria.setHorizontalAccuracy( 1 );  // +/- 1 meter 68.27% of the time
        // [Set other criteria here]
 
        // See if anything matches on the local device.
        LocationProvider provider = LocationProvider.getInstance( criteria );
 
        // Is there a LBS on the local device?
        if ( provider == null )  // then nothing on local device
        {
                // Get the Bluetooth devices within 10 meters that are accepting
                // connections.  This can take 10 seconds or more.
                String[][] remoteDevices = LocationProvider.discoverRemoteDevices();
 
                if ( remoteDevices == null )
                {
                        return;
                }
 
                // Show the user a list of devices by the human readable names.
                String[] deviceNames = new String[remoteDevices.length];
 
                for ( int i = 0; i < remoteDevices.length; i++ )
                {
                        deviceNames[i] = remoteDevices[i][0];
                }
 
                // [Show the list here and set an integer deviceIndex to it]
 
                // Get the Bluetooth address of the device.
                String address = remoteDevices[deviceIndex][1];
 
                // [Store the device's name and address for next time]

                // See if the remote device will work.
                criteria.setRemoteDeviceAddress( address );
                provider = LocationProvider.getInstance( criteria );
        }
 


Field Summary
static int AVAILABLE
          Availability status code: the location provider is available.
static int OUT_OF_SERVICE
          Availability status code: the location provider is out of service.
static int TEMPORARILY_UNAVAILABLE
          Availability status code: the location provider is temporarily unavailable.
 
Constructor Summary
protected LocationProvider()
          Empty constructor to help implementations and extensions.
 
Method Summary
abstract  void close()
          Closes the location provider.
static java.lang.String[][] discoverBluetoothDevices()
          Uses Bluetooth device discovery to get a list of the nearby (within 10 meters) Bluetooth GPS devices that are turned on.
static LocationProvider getInstance(Criteria criteria)
          This factory method is used to get an actual LocationProvider implementation based on the defined criteria.
static Location getLastKnownLocation()
          Returns the last known location that the implementation has.
protected abstract  Location getLastKnownLocationToProvider()
          Returns the last known location by the provider.
abstract  Location getLocation(int timeout)
          Retrieves a Location with the constraints given by the Criteria associated with this class.
abstract  int getState()
          Returns the current state of this LocationProvider.
abstract  void reset()
          Resets the LocationProvider.
abstract  void setLocationListener(LocationListener locationlistener, int interval, int timeout, int maxAge)
          Adds a LocationListener for updates at the defined interval.
static boolean supportsBluetoothAPI()
          Returns if the device supports the Bluetooth API (JSR 82).
static boolean supportsLocationAPI()
          Returns if the device supports the Location API (JSR 179).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

AVAILABLE

public static final int AVAILABLE
Availability status code: the location provider is available.

See Also:
Constant Field Values

TEMPORARILY_UNAVAILABLE

public static final int TEMPORARILY_UNAVAILABLE
Availability status code: the location provider is temporarily unavailable. Temporary unavailability means that the method is unavailable due to reasons that can be expected to possibly change in the future and the provider to become available. An example is not being able to receive the signal because the signal used by the location method is currently being obstructed, e.g. when deep inside a building for satellite based methods. However, a very short transient obstruction of the signal should not cause the provider to toggle quickly between TEMPORARILY_UNAVAILABLE and AVAILABLE.

See Also:
Constant Field Values

OUT_OF_SERVICE

public static final int OUT_OF_SERVICE
Availability status code: the location provider is out of service. Being out of service means that the method is unavailable and the implementation is not able to expect that this situation would change in the near future. An example is when using a location method implemented in an external device and the external device is detached.

See Also:
Constant Field Values
Constructor Detail

LocationProvider

protected LocationProvider()
Empty constructor to help implementations and extensions. This is not intended to be used by applications. Applications should not make subclasses of this class and invoke this constructor from the subclass.

Method Detail

discoverBluetoothDevices

public static java.lang.String[][] discoverBluetoothDevices()
                                                     throws java.io.IOException,
                                                            java.lang.SecurityException
Uses Bluetooth device discovery to get a list of the nearby (within 10 meters) Bluetooth GPS devices that are turned on. If more than one device is returned, the user should select which is their GPS device.

The address of the Bluetooth device should be set using the Criteria.setRemoteDeviceAddress method. That Criteria object can then be used as the argument to the getInstance factory method.

Discovering Bluetooth devices is a lengthy operation. It usually takes more than ten seconds. Therefore this method call normally should be made from a separate thread to keep the application responsive.

Returns:
An array of all the nearby Bluetooth devices that will accept a connection, not just GPS devices. Each array element returns another String[2] where the first element is the device's human readable name and the second is the address (devices that do not support human readable names will be set to the address). If the operation completed successfully, and no devices are nearby, the returned array will have length 0. If the operation terminated, for example because the device does not support the Bluetooth API, the returned array will be null.
Throws:
java.io.IOException - if any Bluetooth I/O errors occur. For example if another Bluetooth discovery operation is already in progess.
java.lang.SecurityException - if the user did not grant access to Bluetooth on the device.

getInstance

public static LocationProvider getInstance(Criteria criteria)
                                    throws LocationException,
                                           java.io.IOException,
                                           java.lang.SecurityException
This factory method is used to get an actual LocationProvider implementation based on the defined criteria. The implementation chooses the LocationProvider so that it best fits the defined criteria, taking into account also possible implementation dependent preferences of the end user. If no concrete LocationProvider could be created that typically can match the defined criteria but there are other location providers not meeting the criteria that could be returned for a more relaxed criteria, null is returned to indicate this. The LocationException is thrown, if all supported location providers are out of service.

A LocationProvider instance is returned if there is a location provider meeting the criteria in either the available or temporarily unavailable state. Implementations should try to select providers in the available state before providers in temporarily unavailable state, but this can't be always guaranteed because the implementation may not always know the state correctly at this point in time. If a LocationProvider meeting the criteria can be supported but is currently out of service, it shall not be returned.

When this method is called with a Criteria that has all fields set to the default values (i.e. the least restrictive criteria possible), the implementation shall return a LocationProvider if there is any provider that isn't in the out of service state. Passing null as the parameter is equal to passing a Criteria that has all fields set to the default values, i.e. the least restrictive set of criteria.

This method only makes the selection of the provider based on the criteria and is intended to return it quickly to the application. Any possible initialization of the provider is done at an implementation dependent time and MUST NOT block the call to this method.

This method may, depending on the implementation, return the same LocationProvider instance as has been returned previously from this method to the calling application, if the same instance can be used to fulfil both defined criteria. Note that there can be only one LocationListener associated with a LocationProvider instance.

Obtaining a provider can be a lengthy operation. For example, connecting to a remote Bluetooth GPS device requires establishing a Bluetooth connection. Although this usually takes less than a second, this method should usually be performed in a different thread to keep the application responsive.

Parameters:
criteria - - the criteria for provider selection or null to indicate the least restrictive criteria with default values
Returns:
a LocationProvider meeting the defined criteria or null if a LocationProvider that meets the defined criteria can't be returned but there are other supported available or temporarily unavailable providers that do not meet the criteria.
Throws:
LocationException - - if all LocationProviders are currently out of service.
java.io.IOException - - if an I/O error occurs establishing a connection to a remote device.
java.lang.SecurityException - - if the user does not give the MIDlet permissions to either the location API (for local LBS) or to the Bluetooth API (for remote LBS). Note some JVM implementations use an IOException instead.
See Also:
Criteria

supportsLocationAPI

public static boolean supportsLocationAPI()
Returns if the device supports the Location API (JSR 179).

Returns:
true if the device supports JSR 179; false otherwise.

supportsBluetoothAPI

public static boolean supportsBluetoothAPI()
Returns if the device supports the Bluetooth API (JSR 82). Once you know the device supports the API you can query for other Bluetooth information through the API's javax.bluetooth.LocalDevice.getProperty method.

Returns:
true if the device supports JSR 82; false otherwise.

getState

public abstract int getState()
Returns the current state of this LocationProvider. The return value shall be one of the availability status code constants defined in this class.

Returns:
the availability state of this LocationProvider

getLocation

public abstract Location getLocation(int timeout)
                              throws LocationException,
                                     java.lang.InterruptedException
Retrieves a Location with the constraints given by the Criteria associated with this class. If no result could be retrieved, a LocationException is thrown. If the location can't be determined within the timeout period specified in the parameter, the method shall throw a LocationException.

If the provider is temporarily unavailable, the implementation shall wait and try to obtain the location until the timeout expires. If the provider is out of service, then the LocationException is thrown immediately.

Note that the individual Location returned might not fulfil exactly the criteria used for selecting this LocationProvider. The Criteria is used to select a location provider that typically is able to meet the defined criteria, but not necessarily for every individual location measurement.

Parameters:
timeout - - a timeout value in seconds. -1 is used to indicate that the implementation shall use its default timeout value for this provider.
Returns:
a Location object
Throws:
LocationException - - if the location couldn't be retrieved or if the timeout period expired
java.lang.InterruptedException - - if the operation is interrupted by calling reset() from another thread
java.lang.SecurityException - - if the calling application does not have a permission to query the location information
java.lang.IllegalArgumentException - - if the timeout = 0 or timeout < -1

setLocationListener

public abstract void setLocationListener(LocationListener locationlistener,
                                         int interval,
                                         int timeout,
                                         int maxAge)
Adds a LocationListener for updates at the defined interval. The listener will be called with updated location at the defined interval. The listener also gets updates when the availablilty state of the LocationProvider changes.

Passing in -1 as the interval selects the default interval which is dependent on the used location method. Passing in 0 as the interval registers the listener to only receive provider status updates and not location updates at all.

Only one listener can be registered with each LocationProvider instance. Setting the listener replaces any possibly previously set listener. Setting the listener to null cancels the registration of any previously set listener.

The implementation shall initiate obtaining the first location result immediately when the listener is registered and provide the location to the listener as soon as it is available. Subsequent location updates will happen at the defined interval after the first one. If the specified update interval is smaller than the time it takes to obtain the first result, the listener shall receive location updates with invalid Locations at the defined interval until the first location result is available.

The timeout parameter determines a timeout that is used if it's not possible to obtain a new location result when the update is scheduled to be provided. This timeout value indicates how many seconds the update is allowed to be provided late compared to the defined interval. If it's not possible to get a new location result (interval + timeout) seconds after the previous update, the update will be made and an invalid Location instance is returned. This is also done if the reason for the inability to obtain a new location result is due to the provider being temporarily unavailable or out of service. For example, if the interval is 60 seconds and the timeout is 10 seconds, the update must be delivered at most 70 seconds after the previous update and if no new location result is available by that time the update will be made with an invalid Location instance.

The maxAge parameter defines how old the location result is allowed to be provided when the update is made. This allows the implementation to reuse location results if it has a recent location result when the update is due to be delivered. This parameter can only be used to indicate a larger value than the normal time of obtaining a location result by a location method. The normal time of obtaining the location result means the time it takes normally to obtain the result when a request is made. If the application specifies a time value that is less than what can be realized with the used location method, the implementation shall provide as recent location results as are possible with the used location method. For example, if the interval is 60 seconds, the maxAge is 20 seconds and normal time to obtain the result is 10 seconds, the implementation would normally start obtaining the result 50 seconds after the previous update. If there is a location result otherwise available that is more recent than 40 seconds after the previous update, then the maxAge setting to 20 seconds allows to return this result and not start obtaining a new one.

Parameters:
locationlistener - - the listener to be registered. If set to null the registration of any previously set listener is cancelled.
interval - - the interval in seconds. -1 is used for the default interval of this provider. 0 is used to indicate that the application wants to receive only provider status updates and not location updates at all.
timeout - - timeout value in seconds, must be greater than 0. if the value is -1, the default timeout for this provider is used. Also, if the interval is -1 to indicate the default, the value of this parameter has no effect and the default timeout for this provider is used. If the interval is 0, this parameter has no effect.
maxAge - - maximum age of the returned location in seconds, must be greater than 0 or equal to -1 to indicate that the default maximum age for this provider is used. Also, if the interval is -1 to indicate the default, the value of this parameter has no effect and the default maximum age for this provider is used. If the interval is 0, this parameter has no effect.
Throws:
java.lang.IllegalArgumentException - - if interval < -1, or if (interval != -1) and (timeout > interval or maxAge > interval or (timeout < 1 and timeout != -1) or (maxAge < 1 and maxAge != -1))
java.lang.SecurityException - - if the calling application does not have a permission to query the location information

close

public abstract void close()
Closes the location provider. Removes any LocationListener from the provider. This should be called when the MIDlet no longer requires LBS including when MIDlet.destroyApp is called.

Closing an already closed provider has no effect.

This method is new to the J4ME implementation (it is not part of the JSR 179 spec). It is used, for example, to close the Bluetooth connection.


reset

public abstract void reset()
                    throws java.io.IOException
Resets the LocationProvider.

All pending synchronous location requests will be aborted and any blocked getLocation method calls will terminate with InterruptedException.

Applications can use this method e.g. when exiting to have its threads freed from blocking synchronous operations.

Throws:
java.io.IOException - - if an I/O error occurs establishing a connection to a remote device.

getLastKnownLocation

public static Location getLastKnownLocation()
Returns the last known location that the implementation has. This is the best estimate that the implementation has for the previously known location.

Applications can use this method to obtain the last known location and check the timestamp and other fields to determine if this is recent enough and good enough for the application to use without needing to make a new request for the current location.

Returns:
a location object. null is returned if the implementation doesn't have any previous location information.
Throws:
java.lang.SecurityException - - if the calling application does not have a permission to query the location information

getLastKnownLocationToProvider

protected abstract Location getLastKnownLocationToProvider()
Returns the last known location by the provider. This is a helper method for JSR-179's static method getLastKnownLocation.

Returns:
a location object. null is returned if the implementation doesn't have any previous location information.
Throws:
java.lang.SecurityException - - if the calling application does not have a permission to query the location information
See Also:
getLastKnownLocation()