Fields Summary |
---|
private static final String | TAG |
public static final String | GPS_ENABLED_CHANGE_ACTIONBroadcast intent action indicating that the GPS has either been
enabled or disabled. An intent extra provides this state as a boolean,
where {@code true} means enabled. |
public static final String | GPS_FIX_CHANGE_ACTIONBroadcast intent action indicating that the GPS has either started or
stopped receiving GPS fixes. An intent extra provides this state as a
boolean, where {@code true} means that the GPS is actively receiving fixes. |
public static final String | EXTRA_ENABLEDThe lookup key for a boolean that indicates whether GPS is enabled or
disabled. {@code true} means GPS is enabled. Retrieve it with
{@link android.content.Intent#getBooleanExtra(String,boolean)}.
{@hide} |
private static final int | GPS_POSITION_MODE_STANDALONE |
private static final int | GPS_POSITION_MODE_MS_BASED |
private static final int | GPS_POSITION_MODE_MS_ASSISTED |
private static final int | GPS_STATUS_NONE |
private static final int | GPS_STATUS_SESSION_BEGIN |
private static final int | GPS_STATUS_SESSION_END |
private static final int | GPS_STATUS_ENGINE_ON |
private static final int | GPS_STATUS_ENGINE_OFF |
private static final int | LOCATION_INVALID |
private static final int | LOCATION_HAS_LAT_LONG |
private static final int | LOCATION_HAS_ALTITUDE |
private static final int | LOCATION_HAS_SPEED |
private static final int | LOCATION_HAS_BEARING |
private static final int | LOCATION_HAS_ACCURACY |
private static final int | GPS_DELETE_EPHEMERIS |
private static final int | GPS_DELETE_ALMANAC |
private static final int | GPS_DELETE_POSITION |
private static final int | GPS_DELETE_TIME |
private static final int | GPS_DELETE_IONO |
private static final int | GPS_DELETE_UTC |
private static final int | GPS_DELETE_HEALTH |
private static final int | GPS_DELETE_SVDIR |
private static final int | GPS_DELETE_SVSTEER |
private static final int | GPS_DELETE_SADATA |
private static final int | GPS_DELETE_RTI |
private static final int | GPS_DELETE_CELLDB_INFO |
private static final int | GPS_DELETE_ALL |
private static final String | PROPERTIES_FILE |
private int | mLocationFlags |
private int | mStatus |
private long | mStatusUpdateTime |
private static final long | RECENT_FIX_TIMEOUT |
private boolean | mEnabled |
private boolean | mLocationTracking |
private boolean | mNetworkAvailable |
private boolean | mNavigating |
private int | mFixInterval |
private int | mPositionMode |
private boolean | mStarted |
private long | mFixRequestTime |
private int | mTTFF |
private long | mLastFixTime |
private Properties | mProperties |
private String | mNtpServer |
private android.content.Context | mContext |
private android.location.Location | mLocation |
private android.os.Bundle | mLocationExtras |
private ArrayList | mListeners |
private GpsEventThread | mEventThread |
private GpsNetworkThread | mNetworkThread |
private Object | mNetworkThreadLock |
private String | mSuplHost |
private int | mSuplPort |
private boolean | mSetSuplServer |
private static final long | NTP_INTERVAL |
private static final long | RETRY_INTERVAL |
private ILocationCollector | mCollector |
private static final int | MAX_SVS |
private static final int | EPHEMERIS_MASK |
private static final int | ALMANAC_MASK |
private static final int | USED_FOR_FIX_MASK |
private int[] | mSvs |
private float[] | mSnrs |
private float[] | mSvElevations |
private float[] | mSvAzimuths |
private int[] | mSvMasks |
private int | mSvCount |
Methods Summary |
---|
public void | addGpsStatusListener(android.location.IGpsStatusListener listener)
if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener");
synchronized(mListeners) {
IBinder binder = listener.asBinder();
int size = mListeners.size();
for (int i = 0; i < size; i++) {
Listener test = mListeners.get(i);
if (binder.equals(test.mListener.asBinder())) {
// listener already added
return;
}
}
Listener l = new Listener(listener);
binder.linkToDeath(l, 0);
mListeners.add(l);
}
|
private static native void | class_init_native()
|
private boolean | deleteAidingData(android.os.Bundle extras)
int flags;
if (extras == null) {
flags = GPS_DELETE_ALL;
} else {
flags = 0;
if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
}
if (flags != 0) {
native_delete_aiding_data(flags);
return true;
}
return false;
|
public synchronized void | disable()Disables this provider. When disabled, calls to getStatus()
and getLocation() need not be handled. Hardware may be shut
down while the provider is disabled.
if (Config.LOGD) Log.d(TAG, "disable");
if (!mEnabled) return;
mEnabled = false;
stopNavigating();
native_disable();
// make sure our event thread exits
if (mEventThread != null) {
try {
mEventThread.join();
} catch (InterruptedException e) {
Log.w(TAG, "InterruptedException when joining mEventThread");
}
mEventThread = null;
}
if (mNetworkThread != null) {
mNetworkThread.setDone();
mNetworkThread = null;
}
native_cleanup();
|
public synchronized void | enable()Enables this provider. When enabled, calls to getStatus()
and getLocation() must be handled. Hardware may be started up
when the provider is enabled.
if (Config.LOGD) Log.d(TAG, "enable");
if (mEnabled) return;
mEnabled = native_init();
if (mEnabled) {
// run event listener thread while we are enabled
mEventThread = new GpsEventThread();
mEventThread.start();
if (requiresNetwork()) {
// run network thread for NTP and XTRA support
if (mNetworkThread == null) {
mNetworkThread = new GpsNetworkThread();
mNetworkThread.start();
} else {
mNetworkThread.signal();
}
}
} else {
Log.w(TAG, "Failed to enable location provider");
}
|
public void | enableLocationTracking(boolean enable)
if (mLocationTracking == enable) {
return;
}
if (enable) {
mFixRequestTime = System.currentTimeMillis();
mTTFF = 0;
mLastFixTime = 0;
startNavigating();
} else {
stopNavigating();
}
mLocationTracking = enable;
|
public int | getAccuracy()Returns the horizontal accuracy of this provider
return Criteria.ACCURACY_FINE;
|
public boolean | getLocation(android.location.Location l)
synchronized (mLocation) {
// don't report locations without latitude and longitude
if ((mLocationFlags & LOCATION_HAS_LAT_LONG) == 0) {
return false;
}
l.set(mLocation);
l.setExtras(mLocationExtras);
return true;
}
|
public int | getPowerRequirement()Returns the power requirement for this provider.
return Criteria.POWER_HIGH;
|
public int | getStatus(android.os.Bundle extras)
if (extras != null) {
extras.putInt("satellites", mSvCount);
}
return mStatus;
|
public long | getStatusUpdateTime()
return mStatusUpdateTime;
|
public boolean | hasMonetaryCost()Returns true if the use of this provider may result in a
monetary charge to the user, false if use is free. It is up to
each provider to give accurate information.
return false;
|
public boolean | isEnabled()
return mEnabled;
|
public boolean | isLocationTracking()
return mLocationTracking;
|
public static boolean | isSupported()
return native_is_supported();
|
private native void | native_cleanup()
|
private native void | native_delete_aiding_data(int flags)
|
private native void | native_disable()
|
private native boolean | native_init()
|
private native void | native_inject_time(long time, long timeReference, int uncertainty)
|
private native void | native_inject_xtra_data(byte[] data, int length)
|
private static native boolean | native_is_supported()
|
private native int | native_read_sv_status(int[] svs, float[] snrs, float[] elevations, float[] azimuths, int[] masks)
|
private native void | native_set_fix_frequency(int fixFrequency)
|
private native void | native_set_supl_apn(java.lang.String apn)
|
private native void | native_set_supl_server(int addr, int port)
|
private native boolean | native_start(int positionMode, boolean singleFix, int fixInterval)
|
private native boolean | native_stop()
|
private native boolean | native_supports_xtra()
|
private native void | native_wait_for_event()
|
public void | removeGpsStatusListener(android.location.IGpsStatusListener listener)
if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener");
synchronized(mListeners) {
IBinder binder = listener.asBinder();
Listener l = null;
int size = mListeners.size();
for (int i = 0; i < size && l == null; i++) {
Listener test = mListeners.get(i);
if (binder.equals(test.mListener.asBinder())) {
l = test;
}
}
if (l != null) {
mListeners.remove(l);
binder.unlinkToDeath(l, 0);
}
}
|
private void | reportLocation(int flags, double latitude, double longitude, double altitude, float speed, float bearing, float accuracy, long timestamp)called from native code to update our position.
if (Config.LOGV) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude +
" timestamp: " + timestamp);
mLastFixTime = System.currentTimeMillis();
// report time to first fix
if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
mTTFF = (int)(mLastFixTime - mFixRequestTime);
if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF);
// notify status listeners
synchronized(mListeners) {
int size = mListeners.size();
for (int i = 0; i < size; i++) {
Listener listener = mListeners.get(i);
try {
listener.mListener.onFirstFix(mTTFF);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in stopNavigating");
mListeners.remove(listener);
// adjust for size of list changing
size--;
}
}
}
}
synchronized (mLocation) {
mLocationFlags = flags;
if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
mLocation.setLatitude(latitude);
mLocation.setLongitude(longitude);
mLocation.setTime(timestamp);
}
if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
mLocation.setAltitude(altitude);
} else {
mLocation.removeAltitude();
}
if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
mLocation.setSpeed(speed);
} else {
mLocation.removeSpeed();
}
if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
mLocation.setBearing(bearing);
} else {
mLocation.removeBearing();
}
if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
mLocation.setAccuracy(accuracy);
} else {
mLocation.removeAccuracy();
}
// Send to collector
if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG
&& mCollector != null) {
mCollector.updateLocation(mLocation);
}
}
if (mStarted && mStatus != AVAILABLE) {
// send an intent to notify that the GPS is receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, true);
mContext.sendBroadcast(intent);
updateStatus(AVAILABLE, mSvCount);
}
|
private void | reportStatus(int status)called from native code to update our status
if (Config.LOGV) Log.v(TAG, "reportStatus status: " + status);
boolean wasNavigating = mNavigating;
mNavigating = (status == GPS_STATUS_SESSION_BEGIN);
if (wasNavigating != mNavigating) {
synchronized(mListeners) {
int size = mListeners.size();
for (int i = 0; i < size; i++) {
Listener listener = mListeners.get(i);
try {
if (mNavigating) {
listener.mListener.onGpsStarted();
} else {
listener.mListener.onGpsStopped();
}
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in reportStatus");
mListeners.remove(listener);
// adjust for size of list changing
size--;
}
}
}
// send an intent to notify that the GPS has been enabled or disabled.
Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, mNavigating);
mContext.sendBroadcast(intent);
}
|
private void | reportSvStatus()called from native code to update SV info
int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks);
synchronized(mListeners) {
int size = mListeners.size();
for (int i = 0; i < size; i++) {
Listener listener = mListeners.get(i);
try {
listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs,
mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK],
mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in reportSvInfo");
mListeners.remove(listener);
// adjust for size of list changing
size--;
}
}
}
if (Config.LOGD) {
if (Config.LOGV) Log.v(TAG, "SV count: " + svCount +
" ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) +
" almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK]));
for (int i = 0; i < svCount; i++) {
if (Config.LOGV) Log.v(TAG, "sv: " + mSvs[i] +
" snr: " + (float)mSnrs[i]/10 +
" elev: " + mSvElevations[i] +
" azimuth: " + mSvAzimuths[i] +
((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") +
((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") +
((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U"));
}
}
updateStatus(mStatus, svCount);
if (mNavigating && mStatus == AVAILABLE && mLastFixTime > 0 &&
System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) {
// send an intent to notify that the GPS is no longer receiving fixes.
Intent intent = new Intent(GPS_FIX_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, false);
mContext.sendBroadcast(intent);
updateStatus(TEMPORARILY_UNAVAILABLE, mSvCount);
}
|
public boolean | requiresCell()Returns true if the provider requires access to an appropriate
cellular network (e.g., to make use of cell tower IDs), false
otherwise.
return false;
|
public boolean | requiresNetwork()Returns true if the provider requires access to a
data network (e.g., the Internet), false otherwise.
// We want updateNetworkState() to get called when the network state changes
// for XTRA and NTP time injection support.
return (mNtpServer != null || native_supports_xtra() || mSuplHost != null);
|
public boolean | requiresSatellite()Returns true if the provider requires access to a
satellite-based positioning system (e.g., GPS), false
otherwise.
return true;
|
public boolean | sendExtraCommand(java.lang.String command, android.os.Bundle extras)
if ("delete_aiding_data".equals(command)) {
return deleteAidingData(extras);
}
Log.w(TAG, "sendExtraCommand: unknown command " + command);
return false;
|
public void | setLocationCollector(ILocationCollector collector)
mCollector = collector;
|
public void | setMinTime(long minTime)
super.setMinTime(minTime);
if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime);
if (minTime >= 0) {
int interval = (int)(minTime/1000);
if (interval < 1) {
interval = 1;
}
mFixInterval = interval;
native_set_fix_frequency(mFixInterval);
}
|
public void | startNavigating()
if (!mStarted) {
if (Config.LOGV) Log.v(TAG, "startNavigating");
mStarted = true;
if (!native_start(mPositionMode, false, mFixInterval)) {
mStarted = false;
Log.e(TAG, "native_start failed in startNavigating()");
}
// reset SV count to zero
updateStatus(TEMPORARILY_UNAVAILABLE, 0);
}
|
public void | stopNavigating()
if (Config.LOGV) Log.v(TAG, "stopNavigating");
if (mStarted) {
mStarted = false;
native_stop();
mTTFF = 0;
mLastFixTime = 0;
mLocationFlags = LOCATION_INVALID;
// reset SV count to zero
updateStatus(TEMPORARILY_UNAVAILABLE, 0);
}
|
public boolean | supportsAltitude()Returns true if the provider is able to provide altitude
information, false otherwise. A provider that reports altitude
under most circumstances but may occassionally not report it
should return true.
return true;
|
public boolean | supportsBearing()Returns true if the provider is able to provide bearing
information, false otherwise. A provider that reports bearing
under most circumstances but may occassionally not report it
should return true.
return true;
|
public boolean | supportsSpeed()Returns true if the provider is able to provide speed
information, false otherwise. A provider that reports speed
under most circumstances but may occassionally not report it
should return true.
return true;
|
public void | updateNetworkState(int state)
mNetworkAvailable = (state == LocationProvider.AVAILABLE);
if (Config.LOGD) {
Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable"));
}
if (mNetworkAvailable && mNetworkThread != null && mEnabled) {
// signal the network thread when the network becomes available
mNetworkThread.signal();
}
|
private void | updateStatus(int status, int svCount)
if (status != mStatus || svCount != mSvCount) {
mStatus = status;
mSvCount = svCount;
mLocationExtras.putInt("satellites", svCount);
mStatusUpdateTime = SystemClock.elapsedRealtime();
}
|
private void | xtraDownloadRequest()
if (Config.LOGD) Log.d(TAG, "xtraDownloadRequest");
if (mNetworkThread != null) {
mNetworkThread.xtraDownloadRequest();
}
|