📄 jsr179locationprovider.java
字号:
package org.j4me.bluetoothgps;
import org.j4me.collections.*;
import org.j4me.logging.*;
/**
* Wraps all <code>LocationProvider</code>s returned by the JSR 179 implementation.
* <p>
* This class is <i>only</i> used on devices that have JSR 179 on them. Therefore
* it can make calls into the <code>javax.microedition.location</code> classes since those
* files are guaranteed to exist on the device. Conversely, this file always exists
* in the J4ME implementation so <code>org.j4me.bluetoothgps.LocationProvider</code> can
* always reference it. It can only use it, however, if the JSR 179 implementation
* is available otherwise the JVM will throw errors.
*/
class JSR179LocationProvider
extends org.j4me.bluetoothgps.LocationProvider
implements Runnable
{
/**
* A copy of the actual location provider object
*/
private final javax.microedition.location.LocationProvider original;
/**
* Stores the latest location provider update. It is put there by the JSR 179
* implementation. This class's background thread takes it and passes it off
* to <code>locationListener</code>.
* <p>
* The object stored in the cubby hole will either be an <code>Integer</code>
* or a <code>javax.microedition.location.Location</code>. When the JSR 179
* provider notifies a state change to unavailable it will be the <code>Integer</code>
* containing the new state code as defined by
* <code>javax.microedition.location.LocationProvider</code>. Otherwise, if
* the JSR 179 provider is in service, it will be the last
* <code>javax.microedition.location.Location</code> update.
* <p>
* Some JSR 179 implementations give location events on the main UI thread.
* This is dangerous because they can cause the application to become unresponsive
* or even crash unless they are immediately handled. By shuffling the events
* to our own background thread the user is free to implement long running
* operations.
*/
private final CubbyHole update = new CubbyHole();
/**
* The application's object registered to listen to location updates.
* This can be <code>null</code> meaning the application isn't receiving
* events.
*/
private org.j4me.bluetoothgps.LocationListener locationListener;
/**
* The worker thread used to raise location events to <code>locationListener</code>.
* This thread will only exist so long as <code>locationListener</code> is not
* <code>null</code>.
*/
private final Thread worker = new Thread( this );
/**
* A flag indicating if this provider has ever been in the <code>AVAILABLE</code>
* state or not. If it has, then it becomes <code>TEMPORARILY_UNAVAILABLE</code>
* again, we know to reset the provider to try to get a fix again.
*/
private boolean hasBeenAvailable = false;
/**
* The last known state of the location provider.
*/
private int lastState = javax.microedition.location.LocationProvider.TEMPORARILY_UNAVAILABLE;
/**
* Records the location update interval set by the user.
*/
private int interval;
/**
* Records the location update timeout set by the user.
*/
private int timeout;
/**
* Records the location update maximum age set by the user.
*/
private int maxAge;
/**
* Returns a JSR 179 <code>LocationProvider</code> wrapped by an object of this
* class.
*/
public static org.j4me.bluetoothgps.LocationProvider getInstance (org.j4me.bluetoothgps.Criteria criteria)
throws org.j4me.bluetoothgps.LocationException
{
try
{
// Change the J4ME Criteria object into a JSR 179 Criteria object.
javax.microedition.location.Criteria c = convertCriteria( criteria );
// Call the JSR 179 implementation to see if it has any providers.
javax.microedition.location.LocationProvider jsr179provider = javax.microedition.location.LocationProvider.getInstance( c );
if ( jsr179provider != null )
{
return new JSR179LocationProvider( jsr179provider );
}
}
catch (javax.microedition.location.LocationException e)
{
throw convertLocationException( e );
}
// If we made it here, there are no JSR 179 providers that match the criteria.
return null;
}
/**
* Create an instance of the actual location provider.
*/
private JSR179LocationProvider (javax.microedition.location.LocationProvider provider)
{
this.original = provider;
}
/**
* @see org.j4me.bluetoothgps.LocationProvider#getState()
*/
public int getState ()
{
// Map the JSR 179 status to one of ours
int status = original.getState();
status = convertAvailabilityStatusCode( lastState );
return status;
}
/**
* @see org.j4me.bluetoothgps.LocationProvider#getLocation(int)
*/
public Location getLocation (int timeout)
throws LocationException, InterruptedException
{
try
{
javax.microedition.location.Location location = original.getLocation( timeout );
org.j4me.bluetoothgps.Location j4me = convertLocation( location );
return j4me;
}
catch (javax.microedition.location.LocationException e)
{
throw convertLocationException( e );
}
}
/**
* Returns the last known location by the provider.
*
* @return a location object. <code>null</code> is returned if the implementation
* doesn't have any previous location information.
* @throws SecurityException - if the calling application does not have a
* permission to query the location information
*
* @see LocationProvider#getLastKnownLocationToProvider()
*/
protected Location getLastKnownLocationToProvider ()
{
javax.microedition.location.Location location = javax.microedition.location.LocationProvider.getLastKnownLocation();
org.j4me.bluetoothgps.Location j4me = convertLocation( location );
return j4me;
}
/**
* @see org.j4me.bluetoothgps.LocationProvider#setLocationListener(org.j4me.bluetoothgps.LocationListener, int, int, int)
*/
public void setLocationListener (org.j4me.bluetoothgps.LocationListener locationListener, int interval, int timeout, int maxAge)
{
this.locationListener = locationListener;
this.interval = interval;
this.timeout = timeout;
this.maxAge = maxAge;
// Is the provider working yet?
if ( original.getState() == javax.microedition.location.LocationProvider.AVAILABLE )
{
hasBeenAvailable = true;
}
// Kill our worker thread to start fresh.
if ( worker.isAlive() )
{
worker.interrupt();
}
// Set the new location listner for the JSR 179 implementation
if ( locationListener == null )
{
// Nothing listening for events.
original.setLocationListener( null, interval, timeout, maxAge );
}
else
{
// Start listening for events.
lastState = TEMPORARILY_UNAVAILABLE;
original.setLocationListener( new JSR179Listener(), interval, timeout, maxAge );
// Start notifying the user's location listener with a new worker thread.
worker.start();
}
}
/**
* @see org.j4me.bluetoothgps.LocationProvider#reset()
*/
public void reset ()
{
original.reset();
// Register a new location listener.
// Some implementation, like the BlackBerry, will not actually reset until
// the location listener is changed.
if ( locationListener != null )
{
original.setLocationListener( new JSR179Listener(), interval, timeout, maxAge );
}
}
/**
* @see org.j4me.bluetoothgps.LocationProvider#close()
*/
public void close ()
{
reset();
setLocationListener( null, -1, -1, -1 );
worker.interrupt();
}
/**
* Listens to the JSR 179 implementation for location information.
* It then hands it off to this class's background thread which
* forwards the event to the application's location listener.
*
* @see JSR179LocationProvider#update
*/
private final class JSR179Listener
implements javax.microedition.location.LocationListener
{
/**
* Called whenever the location provider changes state.
*
* @see javax.microedition.location.LocationListener#providerStateChanged(javax.microedition.location.LocationProvider, int)
*/
public void providerStateChanged (javax.microedition.location.LocationProvider provider, int newState)
{
if ( newState != javax.microedition.location.LocationProvider.AVAILABLE )
{
// Notify that the provider is unavailable.
Integer state = new Integer( newState );
update.set( state );
}
// Ignore AVAILABLE updates. We will signal them along with the latest
// location update.
}
/**
* Called at scheduled intervals with the latest location.
*
* @see javax.microedition.location.LocationListener#locationUpdated(javax.microedition.location.LocationProvider, javax.microedition.location.Location)
*/
public void locationUpdated (javax.microedition.location.LocationProvider provider, javax.microedition.location.Location location)
{
// The provider has been available at one point in time.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -