M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2008, The Android Open Source Project
*
* 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.
*/
package android.location;
parcelable Address;

View File

@ -0,0 +1,569 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package android.location;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A class representing an Address, i.e, a set of Strings describing a location.
*
* The addres format is a simplified version of xAL (eXtensible Address Language)
* http://www.oasis-open.org/committees/ciq/ciq.html#6
*/
public class Address implements Parcelable {
private Locale mLocale;
private String mFeatureName;
private HashMap<Integer, String> mAddressLines;
private int mMaxAddressLineIndex = -1;
private String mAdminArea;
private String mSubAdminArea;
private String mLocality;
private String mSubLocality;
private String mThoroughfare;
private String mSubThoroughfare;
private String mPremises;
private String mPostalCode;
private String mCountryCode;
private String mCountryName;
private double mLatitude;
private double mLongitude;
private boolean mHasLatitude = false;
private boolean mHasLongitude = false;
private String mPhone;
private String mUrl;
private Bundle mExtras = null;
/**
* Constructs a new Address object set to the given Locale and with all
* other fields initialized to null or false.
*/
public Address(Locale locale) {
mLocale = locale;
}
/**
* Returns the Locale associated with this address.
*/
public Locale getLocale() {
return mLocale;
}
/**
* Returns the largest index currently in use to specify an address line.
* If no address lines are specified, -1 is returned.
*/
public int getMaxAddressLineIndex() {
return mMaxAddressLineIndex;
}
/**
* Returns a line of the address numbered by the given index
* (starting at 0), or null if no such line is present.
*
* @throws IllegalArgumentException if index < 0
*/
public String getAddressLine(int index) {
if (index < 0) {
throw new IllegalArgumentException("index = " + index + " < 0");
}
return mAddressLines == null? null : mAddressLines.get(index);
}
/**
* Sets the line of the address numbered by index (starting at 0) to the
* given String, which may be null.
*
* @throws IllegalArgumentException if index < 0
*/
public void setAddressLine(int index, String line) {
if (index < 0) {
throw new IllegalArgumentException("index = " + index + " < 0");
}
if (mAddressLines == null) {
mAddressLines = new HashMap<Integer, String>();
}
mAddressLines.put(index, line);
if (line == null) {
// We've eliminated a line, recompute the max index
mMaxAddressLineIndex = -1;
for (Integer i : mAddressLines.keySet()) {
mMaxAddressLineIndex = Math.max(mMaxAddressLineIndex, i);
}
} else {
mMaxAddressLineIndex = Math.max(mMaxAddressLineIndex, index);
}
}
/**
* Returns the feature name of the address, for example, "Golden Gate Bridge", or null
* if it is unknown
*/
public String getFeatureName() {
return mFeatureName;
}
/**
* Sets the feature name of the address to the given String, which may be null
*/
public void setFeatureName(String featureName) {
mFeatureName = featureName;
}
/**
* Returns the administrative area name of the address, for example, "CA", or null if
* it is unknown
*/
public String getAdminArea() {
return mAdminArea;
}
/**
* Sets the administrative area name of the address to the given String, which may be null
*/
public void setAdminArea(String adminArea) {
this.mAdminArea = adminArea;
}
/**
* Returns the sub-administrative area name of the address, for example, "Santa Clara County",
* or null if it is unknown
*/
public String getSubAdminArea() {
return mSubAdminArea;
}
/**
* Sets the sub-administrative area name of the address to the given String, which may be null
*/
public void setSubAdminArea(String subAdminArea) {
this.mSubAdminArea = subAdminArea;
}
/**
* Returns the locality of the address, for example "Mountain View", or null if it is unknown.
*/
public String getLocality() {
return mLocality;
}
/**
* Sets the locality of the address to the given String, which may be null.
*/
public void setLocality(String locality) {
mLocality = locality;
}
/**
* Returns the sub-locality of the address, or null if it is unknown.
* For example, this may correspond to the neighborhood of the locality.
*/
public String getSubLocality() {
return mSubLocality;
}
/**
* Sets the sub-locality of the address to the given String, which may be null.
*/
public void setSubLocality(String sublocality) {
mSubLocality = sublocality;
}
/**
* Returns the thoroughfare name of the address, for example, "1600 Ampitheater Parkway",
* which may be null
*/
public String getThoroughfare() {
return mThoroughfare;
}
/**
* Sets the thoroughfare name of the address, which may be null.
*/
public void setThoroughfare(String thoroughfare) {
this.mThoroughfare = thoroughfare;
}
/**
* Returns the sub-thoroughfare name of the address, which may be null.
* This may correspond to the street number of the address.
*/
public String getSubThoroughfare() {
return mSubThoroughfare;
}
/**
* Sets the sub-thoroughfare name of the address, which may be null.
*/
public void setSubThoroughfare(String subthoroughfare) {
this.mSubThoroughfare = subthoroughfare;
}
/**
* Returns the premises of the address, or null if it is unknown.
*/
public String getPremises() {
return mPremises;
}
/**
* Sets the premises of the address to the given String, which may be null.
*/
public void setPremises(String premises) {
mPremises = premises;
}
/**
* Returns the postal code of the address, for example "94110",
* or null if it is unknown.
*/
public String getPostalCode() {
return mPostalCode;
}
/**
* Sets the postal code of the address to the given String, which may
* be null.
*/
public void setPostalCode(String postalCode) {
mPostalCode = postalCode;
}
/**
* Returns the country code of the address, for example "US",
* or null if it is unknown.
*/
public String getCountryCode() {
return mCountryCode;
}
/**
* Sets the country code of the address to the given String, which may
* be null.
*/
public void setCountryCode(String countryCode) {
mCountryCode = countryCode;
}
/**
* Returns the localized country name of the address, for example "Iceland",
* or null if it is unknown.
*/
public String getCountryName() {
return mCountryName;
}
/**
* Sets the country name of the address to the given String, which may
* be null.
*/
public void setCountryName(String countryName) {
mCountryName = countryName;
}
/**
* Returns true if a latitude has been assigned to this Address,
* false otherwise.
*/
public boolean hasLatitude() {
return mHasLatitude;
}
/**
* Returns the latitude of the address if known.
*
* @throws IllegalStateException if this Address has not been assigned
* a latitude.
*/
public double getLatitude() {
if (mHasLatitude) {
return mLatitude;
} else {
throw new IllegalStateException();
}
}
/**
* Sets the latitude associated with this address.
*/
public void setLatitude(double latitude) {
mLatitude = latitude;
mHasLatitude = true;
}
/**
* Removes any latitude associated with this address.
*/
public void clearLatitude() {
mHasLatitude = false;
}
/**
* Returns true if a longitude has been assigned to this Address,
* false otherwise.
*/
public boolean hasLongitude() {
return mHasLongitude;
}
/**
* Returns the longitude of the address if known.
*
* @throws IllegalStateException if this Address has not been assigned
* a longitude.
*/
public double getLongitude() {
if (mHasLongitude) {
return mLongitude;
} else {
throw new IllegalStateException();
}
}
/**
* Sets the longitude associated with this address.
*/
public void setLongitude(double longitude) {
mLongitude = longitude;
mHasLongitude = true;
}
/**
* Removes any longitude associated with this address.
*/
public void clearLongitude() {
mHasLongitude = false;
}
/**
* Returns the phone number of the address if known,
* or null if it is unknown.
*
* @throws IllegalStateException if this Address has not been assigned
* a latitude.
*/
public String getPhone() {
return mPhone;
}
/**
* Sets the phone number associated with this address.
*/
public void setPhone(String phone) {
mPhone = phone;
}
/**
* Returns the public URL for the address if known,
* or null if it is unknown.
*/
public String getUrl() {
return mUrl;
}
/**
* Sets the public URL associated with this address.
*/
public void setUrl(String Url) {
mUrl = Url;
}
/**
* Returns additional provider-specific information about the
* address as a Bundle. The keys and values are determined
* by the provider. If no additional information is available,
* null is returned.
*
* <!--
* <p> A number of common key/value pairs are listed
* below. Providers that use any of the keys on this list must
* provide the corresponding value as described below.
*
* <ul>
* </ul>
* -->
*/
public Bundle getExtras() {
return mExtras;
}
/**
* Sets the extra information associated with this fix to the
* given Bundle.
*/
public void setExtras(Bundle extras) {
mExtras = (extras == null) ? null : new Bundle(extras);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Address[addressLines=[");
for (int i = 0; i <= mMaxAddressLineIndex; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(i);
sb.append(':');
String line = mAddressLines.get(i);
if (line == null) {
sb.append("null");
} else {
sb.append('\"');
sb.append(line);
sb.append('\"');
}
}
sb.append(']');
sb.append(",feature=");
sb.append(mFeatureName);
sb.append(",admin=");
sb.append(mAdminArea);
sb.append(",sub-admin=");
sb.append(mSubAdminArea);
sb.append(",locality=");
sb.append(mLocality);
sb.append(",thoroughfare=");
sb.append(mThoroughfare);
sb.append(",postalCode=");
sb.append(mPostalCode);
sb.append(",countryCode=");
sb.append(mCountryCode);
sb.append(",countryName=");
sb.append(mCountryName);
sb.append(",hasLatitude=");
sb.append(mHasLatitude);
sb.append(",latitude=");
sb.append(mLatitude);
sb.append(",hasLongitude=");
sb.append(mHasLongitude);
sb.append(",longitude=");
sb.append(mLongitude);
sb.append(",phone=");
sb.append(mPhone);
sb.append(",url=");
sb.append(mUrl);
sb.append(",extras=");
sb.append(mExtras);
sb.append(']');
return sb.toString();
}
public static final Parcelable.Creator<Address> CREATOR =
new Parcelable.Creator<Address>() {
public Address createFromParcel(Parcel in) {
String language = in.readString();
String country = in.readString();
Locale locale = country.length() > 0 ?
new Locale(language, country) :
new Locale(language);
Address a = new Address(locale);
int N = in.readInt();
if (N > 0) {
a.mAddressLines = new HashMap<Integer, String>(N);
for (int i = 0; i < N; i++) {
int index = in.readInt();
String line = in.readString();
a.mAddressLines.put(index, line);
a.mMaxAddressLineIndex =
Math.max(a.mMaxAddressLineIndex, index);
}
} else {
a.mAddressLines = null;
a.mMaxAddressLineIndex = -1;
}
a.mFeatureName = in.readString();
a.mAdminArea = in.readString();
a.mSubAdminArea = in.readString();
a.mLocality = in.readString();
a.mSubLocality = in.readString();
a.mThoroughfare = in.readString();
a.mSubThoroughfare = in.readString();
a.mPremises = in.readString();
a.mPostalCode = in.readString();
a.mCountryCode = in.readString();
a.mCountryName = in.readString();
a.mHasLatitude = in.readInt() == 0 ? false : true;
if (a.mHasLatitude) {
a.mLatitude = in.readDouble();
}
a.mHasLongitude = in.readInt() == 0 ? false : true;
if (a.mHasLongitude) {
a.mLongitude = in.readDouble();
}
a.mPhone = in.readString();
a.mUrl = in.readString();
a.mExtras = in.readBundle();
return a;
}
public Address[] newArray(int size) {
return new Address[size];
}
};
public int describeContents() {
return (mExtras != null) ? mExtras.describeContents() : 0;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mLocale.getLanguage());
parcel.writeString(mLocale.getCountry());
if (mAddressLines == null) {
parcel.writeInt(0);
} else {
Set<Map.Entry<Integer, String>> entries = mAddressLines.entrySet();
parcel.writeInt(entries.size());
for (Map.Entry<Integer, String> e : entries) {
parcel.writeInt(e.getKey());
parcel.writeString(e.getValue());
}
}
parcel.writeString(mFeatureName);
parcel.writeString(mAdminArea);
parcel.writeString(mSubAdminArea);
parcel.writeString(mLocality);
parcel.writeString(mSubLocality);
parcel.writeString(mThoroughfare);
parcel.writeString(mSubThoroughfare);
parcel.writeString(mPremises);
parcel.writeString(mPostalCode);
parcel.writeString(mCountryCode);
parcel.writeString(mCountryName);
parcel.writeInt(mHasLatitude ? 1 : 0);
if (mHasLatitude) {
parcel.writeDouble(mLatitude);
}
parcel.writeInt(mHasLongitude ? 1 : 0);
if (mHasLongitude){
parcel.writeDouble(mLongitude);
}
parcel.writeString(mPhone);
parcel.writeString(mUrl);
parcel.writeBundle(mExtras);
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2007, The Android Open Source Project
*
* 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.
*/
package android.location;
parcelable Criteria;

View File

@ -0,0 +1,363 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.os.Parcel;
import android.os.Parcelable;
/**
* A class indicating the application criteria for selecting a
* location provider. Providers maybe ordered according to accuracy,
* power usage, ability to report altitude, speed,
* and bearing, and monetary cost.
*/
public class Criteria implements Parcelable {
/**
* A constant indicating that the application does not choose to
* place requirement on a particular feature.
*/
public static final int NO_REQUIREMENT = 0;
/**
* A constant indicating a low power requirement.
*/
public static final int POWER_LOW = 1;
/**
* A constant indicating a medium power requirement.
*/
public static final int POWER_MEDIUM = 2;
/**
* A constant indicating a high power requirement.
*/
public static final int POWER_HIGH = 3;
/**
* A constant indicating a finer location accuracy requirement
*/
public static final int ACCURACY_FINE = 1;
/**
* A constant indicating an approximate accuracy requirement
*/
public static final int ACCURACY_COARSE = 2;
/**
* A constant indicating a low location accuracy requirement
* - may be used for horizontal, altitude, speed or bearing accuracy.
* For horizontal and vertical position this corresponds roughly to
* an accuracy of greater than 500 meters.
*/
public static final int ACCURACY_LOW = 1;
/**
* A constant indicating a medium accuracy requirement
* - currently used only for horizontal accuracy.
* For horizontal position this corresponds roughly to to an accuracy
* of between 100 and 500 meters.
*/
public static final int ACCURACY_MEDIUM = 2;
/**
* a constant indicating a high accuracy requirement
* - may be used for horizontal, altitude, speed or bearing accuracy.
* For horizontal and vertical position this corresponds roughly to
* an accuracy of less than 100 meters.
*/
public static final int ACCURACY_HIGH = 3;
private int mHorizontalAccuracy = NO_REQUIREMENT;
private int mVerticalAccuracy = NO_REQUIREMENT;
private int mSpeedAccuracy = NO_REQUIREMENT;
private int mBearingAccuracy = NO_REQUIREMENT;
private int mPowerRequirement = NO_REQUIREMENT;
private boolean mAltitudeRequired = false;
private boolean mBearingRequired = false;
private boolean mSpeedRequired = false;
private boolean mCostAllowed = false;
/**
* Constructs a new Criteria object. The new object will have no
* requirements on accuracy, power, or response time; will not
* require altitude, speed, or bearing; and will not allow monetary
* cost.
*/
public Criteria() {}
/**
* Constructs a new Criteria object that is a copy of the given criteria.
*/
public Criteria(Criteria criteria) {
mHorizontalAccuracy = criteria.mHorizontalAccuracy;
mVerticalAccuracy = criteria.mVerticalAccuracy;
mSpeedAccuracy = criteria.mSpeedAccuracy;
mBearingAccuracy = criteria.mBearingAccuracy;
mPowerRequirement = criteria.mPowerRequirement;
mAltitudeRequired = criteria.mAltitudeRequired;
mBearingRequired = criteria.mBearingRequired;
mSpeedRequired = criteria.mSpeedRequired;
mCostAllowed = criteria.mCostAllowed;
}
/**
* Indicates the desired horizontal accuracy (latitude and longitude).
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
* {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
* More accurate location may consume more power and may take longer.
*
* @throws IllegalArgumentException if accuracy is not one of the supported constants
*/
public void setHorizontalAccuracy(int accuracy) {
if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
throw new IllegalArgumentException("accuracy=" + accuracy);
}
mHorizontalAccuracy = accuracy;
}
/**
* Returns a constant indicating the desired horizontal accuracy (latitude and longitude).
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
* {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
*/
public int getHorizontalAccuracy() {
return mHorizontalAccuracy;
}
/**
* Indicates the desired vertical accuracy (altitude).
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
* {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
* More accurate location may consume more power and may take longer.
*
* @throws IllegalArgumentException if accuracy is not one of the supported constants
*/
public void setVerticalAccuracy(int accuracy) {
if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
throw new IllegalArgumentException("accuracy=" + accuracy);
}
mVerticalAccuracy = accuracy;
}
/**
* Returns a constant indicating the desired vertical accuracy (altitude).
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
* or {@link #NO_REQUIREMENT}.
*/
public int getVerticalAccuracy() {
return mVerticalAccuracy;
}
/**
* Indicates the desired speed accuracy.
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
* or {@link #NO_REQUIREMENT}.
* More accurate location may consume more power and may take longer.
*
* @throws IllegalArgumentException if accuracy is not one of the supported constants
*/
public void setSpeedAccuracy(int accuracy) {
if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
throw new IllegalArgumentException("accuracy=" + accuracy);
}
mSpeedAccuracy = accuracy;
}
/**
* Returns a constant indicating the desired speed accuracy
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
* or {@link #NO_REQUIREMENT}.
*/
public int getSpeedAccuracy() {
return mSpeedAccuracy;
}
/**
* Indicates the desired bearing accuracy.
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
* or {@link #NO_REQUIREMENT}.
* More accurate location may consume more power and may take longer.
*
* @throws IllegalArgumentException if accuracy is not one of the supported constants
*/
public void setBearingAccuracy(int accuracy) {
if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
throw new IllegalArgumentException("accuracy=" + accuracy);
}
mBearingAccuracy = accuracy;
}
/**
* Returns a constant indicating the desired bearing accuracy.
* Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
* or {@link #NO_REQUIREMENT}.
*/
public int getBearingAccuracy() {
return mBearingAccuracy;
}
/**
* Indicates the desired accuracy for latitude and longitude. Accuracy
* may be {@link #ACCURACY_FINE} if desired location
* is fine, else it can be {@link #ACCURACY_COARSE}.
* More accurate location may consume more power and may take longer.
*
* @throws IllegalArgumentException if accuracy is not one of the supported constants
*/
public void setAccuracy(int accuracy) {
if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_COARSE) {
throw new IllegalArgumentException("accuracy=" + accuracy);
}
if (accuracy == ACCURACY_FINE) {
mHorizontalAccuracy = ACCURACY_HIGH;
} else {
mHorizontalAccuracy = ACCURACY_LOW;
}
}
/**
* Returns a constant indicating desired accuracy of location
* Accuracy may be {@link #ACCURACY_FINE} if desired location
* is fine, else it can be {@link #ACCURACY_COARSE}.
*/
public int getAccuracy() {
if (mHorizontalAccuracy >= ACCURACY_HIGH) {
return ACCURACY_FINE;
} else {
return ACCURACY_COARSE;
}
}
/**
* Indicates the desired maximum power level. The level parameter
* must be one of NO_REQUIREMENT, POWER_LOW, POWER_MEDIUM, or
* POWER_HIGH.
*/
public void setPowerRequirement(int level) {
if (level < NO_REQUIREMENT || level > POWER_HIGH) {
throw new IllegalArgumentException("level=" + level);
}
mPowerRequirement = level;
}
/**
* Returns a constant indicating the desired power requirement. The
* returned
*/
public int getPowerRequirement() {
return mPowerRequirement;
}
/**
* Indicates whether the provider is allowed to incur monetary cost.
*/
public void setCostAllowed(boolean costAllowed) {
mCostAllowed = costAllowed;
}
/**
* Returns whether the provider is allowed to incur monetary cost.
*/
public boolean isCostAllowed() {
return mCostAllowed;
}
/**
* Indicates whether the provider must provide altitude information.
* Not all fixes are guaranteed to contain such information.
*/
public void setAltitudeRequired(boolean altitudeRequired) {
mAltitudeRequired = altitudeRequired;
}
/**
* Returns whether the provider must provide altitude information.
* Not all fixes are guaranteed to contain such information.
*/
public boolean isAltitudeRequired() {
return mAltitudeRequired;
}
/**
* Indicates whether the provider must provide speed information.
* Not all fixes are guaranteed to contain such information.
*/
public void setSpeedRequired(boolean speedRequired) {
mSpeedRequired = speedRequired;
}
/**
* Returns whether the provider must provide speed information.
* Not all fixes are guaranteed to contain such information.
*/
public boolean isSpeedRequired() {
return mSpeedRequired;
}
/**
* Indicates whether the provider must provide bearing information.
* Not all fixes are guaranteed to contain such information.
*/
public void setBearingRequired(boolean bearingRequired) {
mBearingRequired = bearingRequired;
}
/**
* Returns whether the provider must provide bearing information.
* Not all fixes are guaranteed to contain such information.
*/
public boolean isBearingRequired() {
return mBearingRequired;
}
public static final Parcelable.Creator<Criteria> CREATOR =
new Parcelable.Creator<Criteria>() {
public Criteria createFromParcel(Parcel in) {
Criteria c = new Criteria();
c.mHorizontalAccuracy = in.readInt();
c.mVerticalAccuracy = in.readInt();
c.mSpeedAccuracy = in.readInt();
c.mBearingAccuracy = in.readInt();
c.mPowerRequirement = in.readInt();
c.mAltitudeRequired = in.readInt() != 0;
c.mBearingRequired = in.readInt() != 0;
c.mSpeedRequired = in.readInt() != 0;
c.mCostAllowed = in.readInt() != 0;
return c;
}
public Criteria[] newArray(int size) {
return new Criteria[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(mHorizontalAccuracy);
parcel.writeInt(mVerticalAccuracy);
parcel.writeInt(mSpeedAccuracy);
parcel.writeInt(mBearingAccuracy);
parcel.writeInt(mPowerRequirement);
parcel.writeInt(mAltitudeRequired ? 1 : 0);
parcel.writeInt(mBearingRequired ? 1 : 0);
parcel.writeInt(mSpeedRequired ? 1 : 0);
parcel.writeInt(mCostAllowed ? 1 : 0);
}
}

View File

@ -0,0 +1,260 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.content.Context;
import android.location.Address;
import android.os.RemoteException;
import android.os.IBinder;
import android.os.ServiceManager;
import android.util.Log;
import java.io.IOException;
import java.util.Locale;
import java.util.ArrayList;
import java.util.List;
/**
* A class for handling geocoding and reverse geocoding. Geocoding is
* the process of transforming a street address or other description
* of a location into a (latitude, longitude) coordinate. Reverse
* geocoding is the process of transforming a (latitude, longitude)
* coordinate into a (partial) address. The amount of detail in a
* reverse geocoded location description may vary, for example one
* might contain the full street address of the closest building, while
* another might contain only a city name and postal code.
*
* The Geocoder class requires a backend service that is not included in
* the core android framework. The Geocoder query methods will return an
* empty list if there no backend service in the platform. Use the
* isPresent() method to determine whether a Geocoder implementation
* exists.
*/
public final class Geocoder {
private static final String TAG = "Geocoder";
private GeocoderParams mParams;
private ILocationManager mService;
/**
* Returns true if the Geocoder methods getFromLocation and
* getFromLocationName are implemented. Lack of network
* connectivity may still cause these methods to return null or
* empty lists.
*/
public static boolean isPresent() {
IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
ILocationManager lm = ILocationManager.Stub.asInterface(b);
try {
return lm.geocoderIsPresent();
} catch (RemoteException e) {
Log.e(TAG, "isPresent: got RemoteException", e);
return false;
}
}
/**
* Constructs a Geocoder whose responses will be localized for the
* given Locale.
*
* @param context the Context of the calling Activity
* @param locale the desired Locale for the query results
*
* @throws NullPointerException if Locale is null
*/
public Geocoder(Context context, Locale locale) {
if (locale == null) {
throw new NullPointerException("locale == null");
}
mParams = new GeocoderParams(context, locale);
IBinder b = ServiceManager.getService(Context.LOCATION_SERVICE);
mService = ILocationManager.Stub.asInterface(b);
}
/**
* Constructs a Geocoder whose responses will be localized for the
* default system Locale.
*
* @param context the Context of the calling Activity
*/
public Geocoder(Context context) {
this(context, Locale.getDefault());
}
/**
* Returns an array of Addresses that are known to describe the
* area immediately surrounding the given latitude and longitude.
* The returned addresses will be localized for the locale
* provided to this class's constructor.
*
* <p> The returned values may be obtained by means of a network lookup.
* The results are a best guess and are not guaranteed to be meaningful or
* correct. It may be useful to call this method from a thread separate from your
* primary UI thread.
*
* @param latitude the latitude a point for the search
* @param longitude the longitude a point for the search
* @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
*
* @return a list of Address objects. Returns null or empty list if no matches were
* found or there is no backend service available.
*
* @throws IllegalArgumentException if latitude is
* less than -90 or greater than 90
* @throws IllegalArgumentException if longitude is
* less than -180 or greater than 180
* @throws IOException if the network is unavailable or any other
* I/O problem occurs
*/
public List<Address> getFromLocation(double latitude, double longitude, int maxResults)
throws IOException {
if (latitude < -90.0 || latitude > 90.0) {
throw new IllegalArgumentException("latitude == " + latitude);
}
if (longitude < -180.0 || longitude > 180.0) {
throw new IllegalArgumentException("longitude == " + longitude);
}
try {
List<Address> results = new ArrayList<Address>();
String ex = mService.getFromLocation(latitude, longitude, maxResults,
mParams, results);
if (ex != null) {
throw new IOException(ex);
} else {
return results;
}
} catch (RemoteException e) {
Log.e(TAG, "getFromLocation: got RemoteException", e);
return null;
}
}
/**
* Returns an array of Addresses that are known to describe the
* named location, which may be a place name such as "Dalvik,
* Iceland", an address such as "1600 Amphitheatre Parkway,
* Mountain View, CA", an airport code such as "SFO", etc.. The
* returned addresses will be localized for the locale provided to
* this class's constructor.
*
* <p> The query will block and returned values will be obtained by means of a network lookup.
* The results are a best guess and are not guaranteed to be meaningful or
* correct. It may be useful to call this method from a thread separate from your
* primary UI thread.
*
* @param locationName a user-supplied description of a location
* @param maxResults max number of results to return. Smaller numbers (1 to 5) are recommended
*
* @return a list of Address objects. Returns null or empty list if no matches were
* found or there is no backend service available.
*
* @throws IllegalArgumentException if locationName is null
* @throws IOException if the network is unavailable or any other
* I/O problem occurs
*/
public List<Address> getFromLocationName(String locationName, int maxResults) throws IOException {
if (locationName == null) {
throw new IllegalArgumentException("locationName == null");
}
try {
List<Address> results = new ArrayList<Address>();
String ex = mService.getFromLocationName(locationName,
0, 0, 0, 0, maxResults, mParams, results);
if (ex != null) {
throw new IOException(ex);
} else {
return results;
}
} catch (RemoteException e) {
Log.e(TAG, "getFromLocationName: got RemoteException", e);
return null;
}
}
/**
* Returns an array of Addresses that are known to describe the
* named location, which may be a place name such as "Dalvik,
* Iceland", an address such as "1600 Amphitheatre Parkway,
* Mountain View, CA", an airport code such as "SFO", etc.. The
* returned addresses will be localized for the locale provided to
* this class's constructor.
*
* <p> You may specify a bounding box for the search results by including
* the Latitude and Longitude of the Lower Left point and Upper Right
* point of the box.
*
* <p> The query will block and returned values will be obtained by means of a network lookup.
* The results are a best guess and are not guaranteed to be meaningful or
* correct. It may be useful to call this method from a thread separate from your
* primary UI thread.
*
* @param locationName a user-supplied description of a location
* @param maxResults max number of addresses to return. Smaller numbers (1 to 5) are recommended
* @param lowerLeftLatitude the latitude of the lower left corner of the bounding box
* @param lowerLeftLongitude the longitude of the lower left corner of the bounding box
* @param upperRightLatitude the latitude of the upper right corner of the bounding box
* @param upperRightLongitude the longitude of the upper right corner of the bounding box
*
* @return a list of Address objects. Returns null or empty list if no matches were
* found or there is no backend service available.
*
* @throws IllegalArgumentException if locationName is null
* @throws IllegalArgumentException if any latitude is
* less than -90 or greater than 90
* @throws IllegalArgumentException if any longitude is
* less than -180 or greater than 180
* @throws IOException if the network is unavailable or any other
* I/O problem occurs
*/
public List<Address> getFromLocationName(String locationName, int maxResults,
double lowerLeftLatitude, double lowerLeftLongitude,
double upperRightLatitude, double upperRightLongitude) throws IOException {
if (locationName == null) {
throw new IllegalArgumentException("locationName == null");
}
if (lowerLeftLatitude < -90.0 || lowerLeftLatitude > 90.0) {
throw new IllegalArgumentException("lowerLeftLatitude == "
+ lowerLeftLatitude);
}
if (lowerLeftLongitude < -180.0 || lowerLeftLongitude > 180.0) {
throw new IllegalArgumentException("lowerLeftLongitude == "
+ lowerLeftLongitude);
}
if (upperRightLatitude < -90.0 || upperRightLatitude > 90.0) {
throw new IllegalArgumentException("upperRightLatitude == "
+ upperRightLatitude);
}
if (upperRightLongitude < -180.0 || upperRightLongitude > 180.0) {
throw new IllegalArgumentException("upperRightLongitude == "
+ upperRightLongitude);
}
try {
ArrayList<Address> result = new ArrayList<Address>();
String ex = mService.getFromLocationName(locationName,
lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude,
maxResults, mParams, result);
if (ex != null) {
throw new IOException(ex);
} else {
return result;
}
} catch (RemoteException e) {
Log.e(TAG, "getFromLocationName: got RemoteException", e);
return null;
}
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2010, The Android Open Source Project
*
* 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.
*/
package android.location;
parcelable GeocoderParams;

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.Locale;
/**
* This class contains extra parameters to pass to an IGeocodeProvider
* implementation from the Geocoder class. Currently this contains the
* language, country and variant information from the Geocoder's locale
* as well as the Geocoder client's package name for geocoder server
* logging. This information is kept in a separate class to allow for
* future expansion of the IGeocodeProvider interface.
*
* @hide
*/
public class GeocoderParams implements Parcelable {
private Locale mLocale;
private String mPackageName;
// used only for parcelling
private GeocoderParams() {
}
/**
* This object is only constructed by the Geocoder class
*
* @hide
*/
public GeocoderParams(Context context, Locale locale) {
mLocale = locale;
mPackageName = context.getPackageName();
}
/**
* returns the Geocoder's locale
*/
public Locale getLocale() {
return mLocale;
}
/**
* returns the package name of the Geocoder's client
*/
public String getClientPackage() {
return mPackageName;
}
public static final Parcelable.Creator<GeocoderParams> CREATOR =
new Parcelable.Creator<GeocoderParams>() {
public GeocoderParams createFromParcel(Parcel in) {
GeocoderParams gp = new GeocoderParams();
String language = in.readString();
String country = in.readString();
String variant = in.readString();
gp.mLocale = new Locale(language, country, variant);
gp.mPackageName = in.readString();
return gp;
}
public GeocoderParams[] newArray(int size) {
return new GeocoderParams[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mLocale.getLanguage());
parcel.writeString(mLocale.getCountry());
parcel.writeString(mLocale.getVariant());
parcel.writeString(mPackageName);
}
}

View File

@ -0,0 +1,117 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.
*/
package android.location;
/**
* This class represents the current state of a GPS satellite.
* This class is used in conjunction with the {@link GpsStatus} class.
*/
public final class GpsSatellite {
/* These package private values are modified by the GpsStatus class */
boolean mValid;
boolean mHasEphemeris;
boolean mHasAlmanac;
boolean mUsedInFix;
int mPrn;
float mSnr;
float mElevation;
float mAzimuth;
GpsSatellite(int prn) {
mPrn = prn;
}
/**
* Used by {@link LocationManager#getGpsStatus} to copy LocationManager's
* cached GpsStatus instance to the client's copy.
*/
void setStatus(GpsSatellite satellite) {
mValid = satellite.mValid;
mHasEphemeris = satellite.mHasEphemeris;
mHasAlmanac = satellite.mHasAlmanac;
mUsedInFix = satellite.mUsedInFix;
mSnr = satellite.mSnr;
mElevation = satellite.mElevation;
mAzimuth = satellite.mAzimuth;
}
/**
* Returns the PRN (pseudo-random number) for the satellite.
*
* @return PRN number
*/
public int getPrn() {
return mPrn;
}
/**
* Returns the signal to noise ratio for the satellite.
*
* @return the signal to noise ratio
*/
public float getSnr() {
return mSnr;
}
/**
* Returns the elevation of the satellite in degrees.
* The elevation can vary between 0 and 90.
*
* @return the elevation in degrees
*/
public float getElevation() {
return mElevation;
}
/**
* Returns the azimuth of the satellite in degrees.
* The azimuth can vary between 0 and 360.
*
* @return the azimuth in degrees
*/
public float getAzimuth() {
return mAzimuth;
}
/**
* Returns true if the GPS engine has ephemeris data for the satellite.
*
* @return true if the satellite has ephemeris data
*/
public boolean hasEphemeris() {
return mHasEphemeris;
}
/**
* Returns true if the GPS engine has almanac data for the satellite.
*
* @return true if the satellite has almanac data
*/
public boolean hasAlmanac() {
return mHasAlmanac;
}
/**
* Returns true if the satellite was used by the GPS engine when
* calculating the most recent GPS fix.
*
* @return true if the satellite was used to compute the most recent fix.
*/
public boolean usedInFix() {
return mUsedInFix;
}
}

View File

@ -0,0 +1,214 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.
*/
package android.location;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* This class represents the current state of the GPS engine.
* This class is used in conjunction with the {@link Listener} interface.
*/
public final class GpsStatus {
private static final int NUM_SATELLITES = 255;
/* These package private values are modified by the LocationManager class */
private int mTimeToFirstFix;
private GpsSatellite mSatellites[] = new GpsSatellite[NUM_SATELLITES];
private final class SatelliteIterator implements Iterator<GpsSatellite> {
private GpsSatellite[] mSatellites;
int mIndex = 0;
SatelliteIterator(GpsSatellite[] satellites) {
mSatellites = satellites;
}
public boolean hasNext() {
for (int i = mIndex; i < mSatellites.length; i++) {
if (mSatellites[i].mValid) {
return true;
}
}
return false;
}
public GpsSatellite next() {
while (mIndex < mSatellites.length) {
GpsSatellite satellite = mSatellites[mIndex++];
if (satellite.mValid) {
return satellite;
}
}
throw new NoSuchElementException();
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private Iterable<GpsSatellite> mSatelliteList = new Iterable<GpsSatellite>() {
public Iterator<GpsSatellite> iterator() {
return new SatelliteIterator(mSatellites);
}
};
/**
* Event sent when the GPS system has started.
*/
public static final int GPS_EVENT_STARTED = 1;
/**
* Event sent when the GPS system has stopped.
*/
public static final int GPS_EVENT_STOPPED = 2;
/**
* Event sent when the GPS system has received its first fix since starting.
* Call {@link #getTimeToFirstFix()} to find the time from start to first fix.
*/
public static final int GPS_EVENT_FIRST_FIX = 3;
/**
* Event sent periodically to report GPS satellite status.
* Call {@link #getSatellites()} to retrieve the status for each satellite.
*/
public static final int GPS_EVENT_SATELLITE_STATUS = 4;
/**
* Used for receiving notifications when GPS status has changed.
*/
public interface Listener {
/**
* Called to report changes in the GPS status.
* The event number is one of:
* <ul>
* <li> {@link GpsStatus#GPS_EVENT_STARTED}
* <li> {@link GpsStatus#GPS_EVENT_STOPPED}
* <li> {@link GpsStatus#GPS_EVENT_FIRST_FIX}
* <li> {@link GpsStatus#GPS_EVENT_SATELLITE_STATUS}
* </ul>
*
* When this method is called, the client should call
* {@link LocationManager#getGpsStatus} to get additional
* status information.
*
* @param event event number for this notification
*/
void onGpsStatusChanged(int event);
}
/**
* Used for receiving NMEA sentences from the GPS.
* NMEA 0183 is a standard for communicating with marine electronic devices
* and is a common method for receiving data from a GPS, typically over a serial port.
* See <a href="http://en.wikipedia.org/wiki/NMEA_0183">NMEA 0183</a> for more details.
* You can implement this interface and call {@link LocationManager#addNmeaListener}
* to receive NMEA data from the GPS engine.
*/
public interface NmeaListener {
void onNmeaReceived(long timestamp, String nmea);
}
GpsStatus() {
for (int i = 0; i < mSatellites.length; i++) {
mSatellites[i] = new GpsSatellite(i + 1);
}
}
/**
* Used internally within {@link LocationManager} to copy GPS status
* data from the Location Manager Service to its cached GpsStatus instance.
* Is synchronized to ensure that GPS status updates are atomic.
*/
synchronized void setStatus(int svCount, int[] prns, float[] snrs,
float[] elevations, float[] azimuths, int ephemerisMask,
int almanacMask, int usedInFixMask) {
int i;
for (i = 0; i < mSatellites.length; i++) {
mSatellites[i].mValid = false;
}
for (i = 0; i < svCount; i++) {
int prn = prns[i] - 1;
int prnShift = (1 << prn);
if (prn >= 0 && prn < mSatellites.length) {
GpsSatellite satellite = mSatellites[prn];
satellite.mValid = true;
satellite.mSnr = snrs[i];
satellite.mElevation = elevations[i];
satellite.mAzimuth = azimuths[i];
satellite.mHasEphemeris = ((ephemerisMask & prnShift) != 0);
satellite.mHasAlmanac = ((almanacMask & prnShift) != 0);
satellite.mUsedInFix = ((usedInFixMask & prnShift) != 0);
}
}
}
/**
* Used by {@link LocationManager#getGpsStatus} to copy LocationManager's
* cached GpsStatus instance to the client's copy.
* Since this method is only used within {@link LocationManager#getGpsStatus},
* it does not need to be synchronized.
*/
void setStatus(GpsStatus status) {
mTimeToFirstFix = status.getTimeToFirstFix();
for (int i = 0; i < mSatellites.length; i++) {
mSatellites[i].setStatus(status.mSatellites[i]);
}
}
void setTimeToFirstFix(int ttff) {
mTimeToFirstFix = ttff;
}
/**
* Returns the time required to receive the first fix since the most recent
* restart of the GPS engine.
*
* @return time to first fix in milliseconds
*/
public int getTimeToFirstFix() {
return mTimeToFirstFix;
}
/**
* Returns an array of {@link GpsSatellite} objects, which represent the
* current state of the GPS engine.
*
* @return the list of satellites
*/
public Iterable<GpsSatellite> getSatellites() {
return mSatelliteList;
}
/**
* Returns the maximum number of satellites that can be in the satellite
* list that can be returned by {@link #getSatellites()}.
*
* @return the maximum number of satellites
*/
public int getMaxSatellites() {
return NUM_SATELLITES;
}
}

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.location.Address;
import android.location.GeocoderParams;
/**
* An interface for location providers implementing the Geocoder services.
*
* {@hide}
*/
interface IGeocodeProvider {
String getFromLocation(double latitude, double longitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
String getFromLocationName(String locationName,
double lowerLeftLatitude, double lowerLeftLongitude,
double upperRightLatitude, double upperRightLongitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2008, The Android Open Source Project
*
* 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.
*/
package android.location;
import android.location.Location;
/**
* {@hide}
*/
oneway interface IGpsStatusListener
{
void onGpsStarted();
void onGpsStopped();
void onFirstFix(int ttff);
void onSvStatusChanged(int svCount, in int[] prns, in float[] snrs,
in float[] elevations, in float[] azimuths,
int ephemerisMask, int almanacMask, int usedInFixMask);
void onNmeaReceived(long timestamp, String nmea);
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.location.IGpsStatusListener;
/**
* An interface for location providers that provide GPS status information.
*
* {@hide}
*/
interface IGpsStatusProvider {
void addGpsStatusListener(IGpsStatusListener listener);
void removeGpsStatusListener(IGpsStatusListener listener);
}

View File

@ -0,0 +1,32 @@
/* //device/java/android/android/location/ILocationListener.aidl
**
** Copyright 2008, The Android Open Source Project
**
** 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.
*/
package android.location;
import android.location.Location;
import android.os.Bundle;
/**
* {@hide}
*/
oneway interface ILocationListener
{
void onLocationChanged(in Location location);
void onStatusChanged(String provider, int status, in Bundle extras);
void onProviderEnabled(String provider);
void onProviderDisabled(String provider);
}

View File

@ -0,0 +1,91 @@
/*
* Copyright (C) 2007, The Android Open Source Project
*
* 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.
*/
package android.location;
import android.app.PendingIntent;
import android.location.Address;
import android.location.Criteria;
import android.location.GeocoderParams;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
import android.location.ILocationListener;
import android.location.Location;
import android.os.Bundle;
/**
* System private API for talking with the location service.
*
* {@hide}
*/
interface ILocationManager
{
List<String> getAllProviders();
List<String> getProviders(in Criteria criteria, boolean enabledOnly);
String getBestProvider(in Criteria criteria, boolean enabledOnly);
boolean providerMeetsCriteria(String provider, in Criteria criteria);
void requestLocationUpdates(String provider, in Criteria criteria, long minTime, float minDistance,
boolean singleShot, in ILocationListener listener);
void requestLocationUpdatesPI(String provider, in Criteria criteria, long minTime, float minDistance,
boolean singleShot, in PendingIntent intent);
void removeUpdates(in ILocationListener listener);
void removeUpdatesPI(in PendingIntent intent);
boolean addGpsStatusListener(IGpsStatusListener listener);
void removeGpsStatusListener(IGpsStatusListener listener);
// for reporting callback completion
void locationCallbackFinished(ILocationListener listener);
boolean sendExtraCommand(String provider, String command, inout Bundle extras);
void addProximityAlert(double latitude, double longitude, float distance,
long expiration, in PendingIntent intent);
void removeProximityAlert(in PendingIntent intent);
Bundle getProviderInfo(String provider);
boolean isProviderEnabled(String provider);
Location getLastKnownLocation(String provider);
// Used by location providers to tell the location manager when it has a new location.
// Passive is true if the location is coming from the passive provider, in which case
// it need not be shared with other providers.
void reportLocation(in Location location, boolean passive);
boolean geocoderIsPresent();
String getFromLocation(double latitude, double longitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
String getFromLocationName(String locationName,
double lowerLeftLatitude, double lowerLeftLongitude,
double upperRightLatitude, double upperRightLongitude, int maxResults,
in GeocoderParams params, out List<Address> addrs);
void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy);
void removeTestProvider(String provider);
void setTestProviderLocation(String provider, in Location loc);
void clearTestProviderLocation(String provider);
void setTestProviderEnabled(String provider, boolean enabled);
void clearTestProviderEnabled(String provider);
void setTestProviderStatus(String provider, int status, in Bundle extras, long updateTime);
void clearTestProviderStatus(String provider);
// for NI support
boolean sendNiResponse(int notifId, int userResponse);
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.location.Criteria;
import android.location.Location;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.WorkSource;
/**
* Binder interface for services that implement location providers.
*
* {@hide}
*/
interface ILocationProvider {
boolean requiresNetwork();
boolean requiresSatellite();
boolean requiresCell();
boolean hasMonetaryCost();
boolean supportsAltitude();
boolean supportsSpeed();
boolean supportsBearing();
int getPowerRequirement();
boolean meetsCriteria(in Criteria criteria);
int getAccuracy();
void enable();
void disable();
int getStatus(out Bundle extras);
long getStatusUpdateTime();
String getInternalState();
void enableLocationTracking(boolean enable);
void setMinTime(long minTime, in WorkSource ws);
void updateNetworkState(int state, in NetworkInfo info);
void updateLocation(in Location location);
boolean sendExtraCommand(String command, inout Bundle extras);
void addListener(int uid);
void removeListener(int uid);
}

View File

@ -0,0 +1,26 @@
/*
**
** Copyright 2008, The Android Open Source Project
**
** 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.
*/
package android.location;
/**
* {@hide}
*/
interface INetInitiatedListener
{
boolean sendNiResponse(int notifId, int userResponse);
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (C) 2007, The Android Open Source Project
*
* 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.
*/
package android.location;
parcelable Location;

View File

@ -0,0 +1,741 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Printer;
import java.text.DecimalFormat;
import java.util.StringTokenizer;
/**
* A class representing a geographic location sensed at a particular
* time (a "fix"). A location consists of a latitude and longitude, a
* UTC timestamp. and optionally information on altitude, speed, and
* bearing.
*
* <p> Information specific to a particular provider or class of
* providers may be communicated to the application using getExtras,
* which returns a Bundle of key/value pairs. Each provider will only
* provide those entries for which information is available.
*/
public class Location implements Parcelable {
/**
* Constant used to specify formatting of a latitude or longitude
* in the form "[+-]DDD.DDDDD where D indicates degrees.
*/
public static final int FORMAT_DEGREES = 0;
/**
* Constant used to specify formatting of a latitude or longitude
* in the form "[+-]DDD:MM.MMMMM" where D indicates degrees and
* M indicates minutes of arc (1 minute = 1/60th of a degree).
*/
public static final int FORMAT_MINUTES = 1;
/**
* Constant used to specify formatting of a latitude or longitude
* in the form "DDD:MM:SS.SSSSS" where D indicates degrees, M
* indicates minutes of arc, and S indicates seconds of arc (1
* minute = 1/60th of a degree, 1 second = 1/3600th of a degree).
*/
public static final int FORMAT_SECONDS = 2;
private String mProvider;
private long mTime = 0;
private double mLatitude = 0.0;
private double mLongitude = 0.0;
private boolean mHasAltitude = false;
private double mAltitude = 0.0f;
private boolean mHasSpeed = false;
private float mSpeed = 0.0f;
private boolean mHasBearing = false;
private float mBearing = 0.0f;
private boolean mHasAccuracy = false;
private float mAccuracy = 0.0f;
private Bundle mExtras = null;
// Cache the inputs and outputs of computeDistanceAndBearing
// so calls to distanceTo() and bearingTo() can share work
private double mLat1 = 0.0;
private double mLon1 = 0.0;
private double mLat2 = 0.0;
private double mLon2 = 0.0;
private float mDistance = 0.0f;
private float mInitialBearing = 0.0f;
// Scratchpad
private float[] mResults = new float[2];
public void dump(Printer pw, String prefix) {
pw.println(prefix + "mProvider=" + mProvider + " mTime=" + mTime);
pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude);
pw.println(prefix + "mHasAltitude=" + mHasAltitude + " mAltitude=" + mAltitude);
pw.println(prefix + "mHasSpeed=" + mHasSpeed + " mSpeed=" + mSpeed);
pw.println(prefix + "mHasBearing=" + mHasBearing + " mBearing=" + mBearing);
pw.println(prefix + "mHasAccuracy=" + mHasAccuracy + " mAccuracy=" + mAccuracy);
pw.println(prefix + "mExtras=" + mExtras);
}
/**
* Constructs a new Location. By default, time, latitude,
* longitude, and numSatellites are 0; hasAltitude, hasSpeed, and
* hasBearing are false; and there is no extra information.
*
* @param provider the name of the location provider that generated this
* location fix.
*/
public Location(String provider) {
mProvider = provider;
}
/**
* Constructs a new Location object that is a copy of the given
* location.
*/
public Location(Location l) {
set(l);
}
/**
* Sets the contents of the location to the values from the given location.
*/
public void set(Location l) {
mProvider = l.mProvider;
mTime = l.mTime;
mLatitude = l.mLatitude;
mLongitude = l.mLongitude;
mHasAltitude = l.mHasAltitude;
mAltitude = l.mAltitude;
mHasSpeed = l.mHasSpeed;
mSpeed = l.mSpeed;
mHasBearing = l.mHasBearing;
mBearing = l.mBearing;
mHasAccuracy = l.mHasAccuracy;
mAccuracy = l.mAccuracy;
mExtras = (l.mExtras == null) ? null : new Bundle(l.mExtras);
}
/**
* Clears the contents of the location.
*/
public void reset() {
mProvider = null;
mTime = 0;
mLatitude = 0;
mLongitude = 0;
mHasAltitude = false;
mAltitude = 0;
mHasSpeed = false;
mSpeed = 0;
mHasBearing = false;
mBearing = 0;
mHasAccuracy = false;
mAccuracy = 0;
mExtras = null;
}
/**
* Converts a coordinate to a String representation. The outputType
* may be one of FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
* The coordinate must be a valid double between -180.0 and 180.0.
*
* @throws IllegalArgumentException if coordinate is less than
* -180.0, greater than 180.0, or is not a number.
* @throws IllegalArgumentException if outputType is not one of
* FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS.
*/
public static String convert(double coordinate, int outputType) {
if (coordinate < -180.0 || coordinate > 180.0 ||
Double.isNaN(coordinate)) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
if ((outputType != FORMAT_DEGREES) &&
(outputType != FORMAT_MINUTES) &&
(outputType != FORMAT_SECONDS)) {
throw new IllegalArgumentException("outputType=" + outputType);
}
StringBuilder sb = new StringBuilder();
// Handle negative values
if (coordinate < 0) {
sb.append('-');
coordinate = -coordinate;
}
DecimalFormat df = new DecimalFormat("###.#####");
if (outputType == FORMAT_MINUTES || outputType == FORMAT_SECONDS) {
int degrees = (int) Math.floor(coordinate);
sb.append(degrees);
sb.append(':');
coordinate -= degrees;
coordinate *= 60.0;
if (outputType == FORMAT_SECONDS) {
int minutes = (int) Math.floor(coordinate);
sb.append(minutes);
sb.append(':');
coordinate -= minutes;
coordinate *= 60.0;
}
}
sb.append(df.format(coordinate));
return sb.toString();
}
/**
* Converts a String in one of the formats described by
* FORMAT_DEGREES, FORMAT_MINUTES, or FORMAT_SECONDS into a
* double.
*
* @throws NullPointerException if coordinate is null
* @throws IllegalArgumentException if the coordinate is not
* in one of the valid formats.
*/
public static double convert(String coordinate) {
// IllegalArgumentException if bad syntax
if (coordinate == null) {
throw new NullPointerException("coordinate");
}
boolean negative = false;
if (coordinate.charAt(0) == '-') {
coordinate = coordinate.substring(1);
negative = true;
}
StringTokenizer st = new StringTokenizer(coordinate, ":");
int tokens = st.countTokens();
if (tokens < 1) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
try {
String degrees = st.nextToken();
double val;
if (tokens == 1) {
val = Double.parseDouble(degrees);
return negative ? -val : val;
}
String minutes = st.nextToken();
int deg = Integer.parseInt(degrees);
double min;
double sec = 0.0;
if (st.hasMoreTokens()) {
min = Integer.parseInt(minutes);
String seconds = st.nextToken();
sec = Double.parseDouble(seconds);
} else {
min = Double.parseDouble(minutes);
}
boolean isNegative180 = negative && (deg == 180) &&
(min == 0) && (sec == 0);
// deg must be in [0, 179] except for the case of -180 degrees
if ((deg < 0.0) || (deg > 179 && !isNegative180)) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
if (min < 0 || min > 59) {
throw new IllegalArgumentException("coordinate=" +
coordinate);
}
if (sec < 0 || sec > 59) {
throw new IllegalArgumentException("coordinate=" +
coordinate);
}
val = deg*3600.0 + min*60.0 + sec;
val /= 3600.0;
return negative ? -val : val;
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("coordinate=" + coordinate);
}
}
private static void computeDistanceAndBearing(double lat1, double lon1,
double lat2, double lon2, float[] results) {
// Based on http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
// using the "Inverse Formula" (section 4)
int MAXITERS = 20;
// Convert lat/long to radians
lat1 *= Math.PI / 180.0;
lat2 *= Math.PI / 180.0;
lon1 *= Math.PI / 180.0;
lon2 *= Math.PI / 180.0;
double a = 6378137.0; // WGS84 major axis
double b = 6356752.3142; // WGS84 semi-major axis
double f = (a - b) / a;
double aSqMinusBSqOverBSq = (a * a - b * b) / (b * b);
double L = lon2 - lon1;
double A = 0.0;
double U1 = Math.atan((1.0 - f) * Math.tan(lat1));
double U2 = Math.atan((1.0 - f) * Math.tan(lat2));
double cosU1 = Math.cos(U1);
double cosU2 = Math.cos(U2);
double sinU1 = Math.sin(U1);
double sinU2 = Math.sin(U2);
double cosU1cosU2 = cosU1 * cosU2;
double sinU1sinU2 = sinU1 * sinU2;
double sigma = 0.0;
double deltaSigma = 0.0;
double cosSqAlpha = 0.0;
double cos2SM = 0.0;
double cosSigma = 0.0;
double sinSigma = 0.0;
double cosLambda = 0.0;
double sinLambda = 0.0;
double lambda = L; // initial guess
for (int iter = 0; iter < MAXITERS; iter++) {
double lambdaOrig = lambda;
cosLambda = Math.cos(lambda);
sinLambda = Math.sin(lambda);
double t1 = cosU2 * sinLambda;
double t2 = cosU1 * sinU2 - sinU1 * cosU2 * cosLambda;
double sinSqSigma = t1 * t1 + t2 * t2; // (14)
sinSigma = Math.sqrt(sinSqSigma);
cosSigma = sinU1sinU2 + cosU1cosU2 * cosLambda; // (15)
sigma = Math.atan2(sinSigma, cosSigma); // (16)
double sinAlpha = (sinSigma == 0) ? 0.0 :
cosU1cosU2 * sinLambda / sinSigma; // (17)
cosSqAlpha = 1.0 - sinAlpha * sinAlpha;
cos2SM = (cosSqAlpha == 0) ? 0.0 :
cosSigma - 2.0 * sinU1sinU2 / cosSqAlpha; // (18)
double uSquared = cosSqAlpha * aSqMinusBSqOverBSq; // defn
A = 1 + (uSquared / 16384.0) * // (3)
(4096.0 + uSquared *
(-768 + uSquared * (320.0 - 175.0 * uSquared)));
double B = (uSquared / 1024.0) * // (4)
(256.0 + uSquared *
(-128.0 + uSquared * (74.0 - 47.0 * uSquared)));
double C = (f / 16.0) *
cosSqAlpha *
(4.0 + f * (4.0 - 3.0 * cosSqAlpha)); // (10)
double cos2SMSq = cos2SM * cos2SM;
deltaSigma = B * sinSigma * // (6)
(cos2SM + (B / 4.0) *
(cosSigma * (-1.0 + 2.0 * cos2SMSq) -
(B / 6.0) * cos2SM *
(-3.0 + 4.0 * sinSigma * sinSigma) *
(-3.0 + 4.0 * cos2SMSq)));
lambda = L +
(1.0 - C) * f * sinAlpha *
(sigma + C * sinSigma *
(cos2SM + C * cosSigma *
(-1.0 + 2.0 * cos2SM * cos2SM))); // (11)
double delta = (lambda - lambdaOrig) / lambda;
if (Math.abs(delta) < 1.0e-12) {
break;
}
}
float distance = (float) (b * A * (sigma - deltaSigma));
results[0] = distance;
if (results.length > 1) {
float initialBearing = (float) Math.atan2(cosU2 * sinLambda,
cosU1 * sinU2 - sinU1 * cosU2 * cosLambda);
initialBearing *= 180.0 / Math.PI;
results[1] = initialBearing;
if (results.length > 2) {
float finalBearing = (float) Math.atan2(cosU1 * sinLambda,
-sinU1 * cosU2 + cosU1 * sinU2 * cosLambda);
finalBearing *= 180.0 / Math.PI;
results[2] = finalBearing;
}
}
}
/**
* Computes the approximate distance in meters between two
* locations, and optionally the initial and final bearings of the
* shortest path between them. Distance and bearing are defined using the
* WGS84 ellipsoid.
*
* <p> The computed distance is stored in results[0]. If results has length
* 2 or greater, the initial bearing is stored in results[1]. If results has
* length 3 or greater, the final bearing is stored in results[2].
*
* @param startLatitude the starting latitude
* @param startLongitude the starting longitude
* @param endLatitude the ending latitude
* @param endLongitude the ending longitude
* @param results an array of floats to hold the results
*
* @throws IllegalArgumentException if results is null or has length < 1
*/
public static void distanceBetween(double startLatitude, double startLongitude,
double endLatitude, double endLongitude, float[] results) {
if (results == null || results.length < 1) {
throw new IllegalArgumentException("results is null or has length < 1");
}
computeDistanceAndBearing(startLatitude, startLongitude,
endLatitude, endLongitude, results);
}
/**
* Returns the approximate distance in meters between this
* location and the given location. Distance is defined using
* the WGS84 ellipsoid.
*
* @param dest the destination location
* @return the approximate distance in meters
*/
public float distanceTo(Location dest) {
// See if we already have the result
synchronized (mResults) {
if (mLatitude != mLat1 || mLongitude != mLon1 ||
dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {
computeDistanceAndBearing(mLatitude, mLongitude,
dest.mLatitude, dest.mLongitude, mResults);
mLat1 = mLatitude;
mLon1 = mLongitude;
mLat2 = dest.mLatitude;
mLon2 = dest.mLongitude;
mDistance = mResults[0];
mInitialBearing = mResults[1];
}
return mDistance;
}
}
/**
* Returns the approximate initial bearing in degrees East of true
* North when traveling along the shortest path between this
* location and the given location. The shortest path is defined
* using the WGS84 ellipsoid. Locations that are (nearly)
* antipodal may produce meaningless results.
*
* @param dest the destination location
* @return the initial bearing in degrees
*/
public float bearingTo(Location dest) {
synchronized (mResults) {
// See if we already have the result
if (mLatitude != mLat1 || mLongitude != mLon1 ||
dest.mLatitude != mLat2 || dest.mLongitude != mLon2) {
computeDistanceAndBearing(mLatitude, mLongitude,
dest.mLatitude, dest.mLongitude, mResults);
mLat1 = mLatitude;
mLon1 = mLongitude;
mLat2 = dest.mLatitude;
mLon2 = dest.mLongitude;
mDistance = mResults[0];
mInitialBearing = mResults[1];
}
return mInitialBearing;
}
}
/**
* Returns the name of the provider that generated this fix,
* or null if it is not associated with a provider.
*/
public String getProvider() {
return mProvider;
}
/**
* Sets the name of the provider that generated this fix.
*/
public void setProvider(String provider) {
mProvider = provider;
}
/**
* Returns the UTC time of this fix, in milliseconds since January 1,
* 1970.
*/
public long getTime() {
return mTime;
}
/**
* Sets the UTC time of this fix, in milliseconds since January 1,
* 1970.
*/
public void setTime(long time) {
mTime = time;
}
/**
* Returns the latitude of this fix.
*/
public double getLatitude() {
return mLatitude;
}
/**
* Sets the latitude of this fix.
*/
public void setLatitude(double latitude) {
mLatitude = latitude;
}
/**
* Returns the longitude of this fix.
*/
public double getLongitude() {
return mLongitude;
}
/**
* Sets the longitude of this fix.
*/
public void setLongitude(double longitude) {
mLongitude = longitude;
}
/**
* Returns true if this fix contains altitude information, false
* otherwise.
*/
public boolean hasAltitude() {
return mHasAltitude;
}
/**
* Returns the altitude of this fix. If {@link #hasAltitude} is false,
* 0.0f is returned.
*/
public double getAltitude() {
return mAltitude;
}
/**
* Sets the altitude of this fix. Following this call,
* hasAltitude() will return true.
*/
public void setAltitude(double altitude) {
mAltitude = altitude;
mHasAltitude = true;
}
/**
* Clears the altitude of this fix. Following this call,
* hasAltitude() will return false.
*/
public void removeAltitude() {
mAltitude = 0.0f;
mHasAltitude = false;
}
/**
* Returns true if this fix contains speed information, false
* otherwise. The default implementation returns false.
*/
public boolean hasSpeed() {
return mHasSpeed;
}
/**
* Returns the speed of the device over ground in meters/second.
* If hasSpeed() is false, 0.0f is returned.
*/
public float getSpeed() {
return mSpeed;
}
/**
* Sets the speed of this fix, in meters/second. Following this
* call, hasSpeed() will return true.
*/
public void setSpeed(float speed) {
mSpeed = speed;
mHasSpeed = true;
}
/**
* Clears the speed of this fix. Following this call, hasSpeed()
* will return false.
*/
public void removeSpeed() {
mSpeed = 0.0f;
mHasSpeed = false;
}
/**
* Returns true if the provider is able to report bearing information,
* false otherwise. The default implementation returns false.
*/
public boolean hasBearing() {
return mHasBearing;
}
/**
* Returns the direction of travel in degrees East of true
* North. If hasBearing() is false, 0.0 is returned.
*/
public float getBearing() {
return mBearing;
}
/**
* Sets the bearing of this fix. Following this call, hasBearing()
* will return true.
*/
public void setBearing(float bearing) {
while (bearing < 0.0f) {
bearing += 360.0f;
}
while (bearing >= 360.0f) {
bearing -= 360.0f;
}
mBearing = bearing;
mHasBearing = true;
}
/**
* Clears the bearing of this fix. Following this call, hasBearing()
* will return false.
*/
public void removeBearing() {
mBearing = 0.0f;
mHasBearing = false;
}
/**
* Returns true if the provider is able to report accuracy information,
* false otherwise. The default implementation returns false.
*/
public boolean hasAccuracy() {
return mHasAccuracy;
}
/**
* Returns the accuracy of the fix in meters. If hasAccuracy() is false,
* 0.0 is returned.
*/
public float getAccuracy() {
return mAccuracy;
}
/**
* Sets the accuracy of this fix. Following this call, hasAccuracy()
* will return true.
*/
public void setAccuracy(float accuracy) {
mAccuracy = accuracy;
mHasAccuracy = true;
}
/**
* Clears the accuracy of this fix. Following this call, hasAccuracy()
* will return false.
*/
public void removeAccuracy() {
mAccuracy = 0.0f;
mHasAccuracy = false;
}
/**
* Returns additional provider-specific information about the
* location fix as a Bundle. The keys and values are determined
* by the provider. If no additional information is available,
* null is returned.
*
* <p> A number of common key/value pairs are listed
* below. Providers that use any of the keys on this list must
* provide the corresponding value as described below.
*
* <ul>
* <li> satellites - the number of satellites used to derive the fix
* </ul>
*/
public Bundle getExtras() {
return mExtras;
}
/**
* Sets the extra information associated with this fix to the
* given Bundle.
*/
public void setExtras(Bundle extras) {
mExtras = (extras == null) ? null : new Bundle(extras);
}
@Override public String toString() {
return "Location[mProvider=" + mProvider +
",mTime=" + mTime +
",mLatitude=" + mLatitude +
",mLongitude=" + mLongitude +
",mHasAltitude=" + mHasAltitude +
",mAltitude=" + mAltitude +
",mHasSpeed=" + mHasSpeed +
",mSpeed=" + mSpeed +
",mHasBearing=" + mHasBearing +
",mBearing=" + mBearing +
",mHasAccuracy=" + mHasAccuracy +
",mAccuracy=" + mAccuracy +
",mExtras=" + mExtras + "]";
}
public static final Parcelable.Creator<Location> CREATOR =
new Parcelable.Creator<Location>() {
public Location createFromParcel(Parcel in) {
String provider = in.readString();
Location l = new Location(provider);
l.mTime = in.readLong();
l.mLatitude = in.readDouble();
l.mLongitude = in.readDouble();
l.mHasAltitude = in.readInt() != 0;
l.mAltitude = in.readDouble();
l.mHasSpeed = in.readInt() != 0;
l.mSpeed = in.readFloat();
l.mHasBearing = in.readInt() != 0;
l.mBearing = in.readFloat();
l.mHasAccuracy = in.readInt() != 0;
l.mAccuracy = in.readFloat();
l.mExtras = in.readBundle();
return l;
}
public Location[] newArray(int size) {
return new Location[size];
}
};
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeString(mProvider);
parcel.writeLong(mTime);
parcel.writeDouble(mLatitude);
parcel.writeDouble(mLongitude);
parcel.writeInt(mHasAltitude ? 1 : 0);
parcel.writeDouble(mAltitude);
parcel.writeInt(mHasSpeed ? 1 : 0);
parcel.writeFloat(mSpeed);
parcel.writeInt(mHasBearing ? 1 : 0);
parcel.writeFloat(mBearing);
parcel.writeInt(mHasAccuracy ? 1 : 0);
parcel.writeFloat(mAccuracy);
parcel.writeBundle(mExtras);
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.os.Bundle;
/**
* Used for receiving notifications from the LocationManager when
* the location has changed. These methods are called if the
* LocationListener has been registered with the location manager service
* using the {@link LocationManager#requestLocationUpdates(String, long, float, LocationListener)}
* method.
*/
public interface LocationListener {
/**
* Called when the location has changed.
*
* <p> There are no restrictions on the use of the supplied Location object.
*
* @param location The new location, as a Location object.
*/
void onLocationChanged(Location location);
/**
* Called when the provider status changes. This method is called when
* a provider is unable to fetch a location or if the provider has recently
* become available after a period of unavailability.
*
* @param provider the name of the location provider associated with this
* update.
* @param status {@link LocationProvider#OUT_OF_SERVICE} if the
* provider is out of service, and this is not expected to change in the
* near future; {@link LocationProvider#TEMPORARILY_UNAVAILABLE} if
* the provider is temporarily unavailable but is expected to be available
* shortly; and {@link LocationProvider#AVAILABLE} if the
* provider is currently available.
* @param extras an optional Bundle which will contain provider specific
* status variables.
*
* <p> A number of common key/value pairs for the extras Bundle are listed
* below. Providers that use any of the keys on this list must
* provide the corresponding value as described below.
*
* <ul>
* <li> satellites - the number of satellites used to derive the fix
* </ul>
*/
void onStatusChanged(String provider, int status, Bundle extras);
/**
* Called when the provider is enabled by the user.
*
* @param provider the name of the location provider associated with this
* update.
*/
void onProviderEnabled(String provider);
/**
* Called when the provider is disabled by the user. If requestLocationUpdates
* is called on an already disabled provider, this method is called
* immediately.
*
* @param provider the name of the location provider associated with this
* update.
*/
void onProviderDisabled(String provider);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,153 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package android.location;
import android.os.RemoteException;
import android.util.Log;
/**
* An abstract superclass for location providers. A location provider
* provides periodic reports on the geographical location of the
* device.
*
* <p> Each provider has a set of criteria under which it may be used;
* for example, some providers require GPS hardware and visibility to
* a number of satellites; others require the use of the cellular
* radio, or access to a specific carrier's network, or to the
* internet. They may also have different battery consumption
* characteristics or monetary costs to the user. The {@link
* Criteria} class allows providers to be selected based on
* user-specified criteria.
*/
public abstract class LocationProvider {
private static final String TAG = "LocationProvider";
// A regular expression matching characters that may not appear
// in the name of a LocationProvider.
static final String BAD_CHARS_REGEX = "[^a-zA-Z0-9]";
private final String mName;
private final ILocationManager mService;
public static final int OUT_OF_SERVICE = 0;
public static final int TEMPORARILY_UNAVAILABLE = 1;
public static final int AVAILABLE = 2;
/**
* Constructs a LocationProvider with the given name. Provider names must
* consist only of the characters [a-zA-Z0-9].
*
* @throws IllegalArgumentException if name contains an illegal character
*
* {@hide}
*/
public LocationProvider(String name, ILocationManager service) {
if (name.matches(BAD_CHARS_REGEX)) {
throw new IllegalArgumentException("name " + name +
" contains an illegal character");
}
mName = name;
mService = service;
}
/**
* Returns the name of this provider.
*/
public String getName() {
return mName;
}
/**
* Returns true if this provider meets the given criteria,
* false otherwise.
*/
public boolean meetsCriteria(Criteria criteria) {
try {
return mService.providerMeetsCriteria(mName, criteria);
} catch (RemoteException e) {
Log.e(TAG, "meetsCriteria: RemoteException", e);
return false;
}
}
/**
* Returns true if the provider requires access to a
* data network (e.g., the Internet), false otherwise.
*/
public abstract boolean requiresNetwork();
/**
* Returns true if the provider requires access to a
* satellite-based positioning system (e.g., GPS), false
* otherwise.
*/
public abstract boolean requiresSatellite();
/**
* Returns true if the provider requires access to an appropriate
* cellular network (e.g., to make use of cell tower IDs), false
* otherwise.
*/
public abstract boolean requiresCell();
/**
* 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.
*/
public abstract boolean hasMonetaryCost();
/**
* 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.
*/
public abstract boolean supportsAltitude();
/**
* 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.
*/
public abstract boolean supportsSpeed();
/**
* 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.
*/
public abstract boolean supportsBearing();
/**
* Returns the power requirement for this provider.
*
* @return the power requirement for this provider, as one of the
* constants Criteria.POWER_REQUIREMENT_*.
*/
public abstract int getPowerRequirement();
/**
* Returns a constant describing horizontal accuracy of this provider.
* If the provider returns finer grain or exact location,
* {@link Criteria#ACCURACY_FINE} is returned, otherwise if the
* location is only approximate then {@link Criteria#ACCURACY_COARSE}
* is returned.
*/
public abstract int getAccuracy();
}

View File

@ -0,0 +1,12 @@
<html>
<head>
<script type="text/javascript" src="http://www.corp.google.com/style/prettify.js"></script>
<script src="http://www.corp.google.com/eng/techpubs/include/navbar.js" type="text/javascript"></script>
</head>
<body>
<p>Classes defining Android location-based and related services.</p>
</body>
</html>

View File

@ -0,0 +1,171 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* 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.
*/
package com.android.internal.location;
import android.location.ILocationManager;
import android.location.LocationProvider;
/**
* A stub implementation of LocationProvider used by LocationManager.
* A DummyLocationProvider may be queried to determine the properties
* of the provider whcih it shadows, but does not actually provide location
* data.
*
* {@hide}
*/
public class DummyLocationProvider extends LocationProvider {
private static final String TAG = "DummyLocationProvider";
String mName;
boolean mRequiresNetwork;
boolean mRequiresSatellite;
boolean mRequiresCell;
boolean mHasMonetaryCost;
boolean mSupportsAltitude;
boolean mSupportsSpeed;
boolean mSupportsBearing;
int mPowerRequirement;
int mAccuracy;
public DummyLocationProvider(String name, ILocationManager service) {
super(name, service);
}
public void setRequiresNetwork(boolean requiresNetwork) {
mRequiresNetwork = requiresNetwork;
}
public void setRequiresSatellite(boolean requiresSatellite) {
mRequiresSatellite = requiresSatellite;
}
public void setRequiresCell(boolean requiresCell) {
mRequiresCell = requiresCell;
}
public void setHasMonetaryCost(boolean hasMonetaryCost) {
mHasMonetaryCost = hasMonetaryCost;
}
public void setSupportsAltitude(boolean supportsAltitude) {
mSupportsAltitude = supportsAltitude;
}
public void setSupportsSpeed(boolean supportsSpeed) {
mSupportsSpeed = supportsSpeed;
}
public void setSupportsBearing(boolean supportsBearing) {
mSupportsBearing = supportsBearing;
}
public void setPowerRequirement(int powerRequirement) {
mPowerRequirement = powerRequirement;
}
public void setAccuracy(int accuracy) {
mAccuracy = accuracy;
}
/**
* Returns true if the provider requires access to a
* data network (e.g., the Internet), false otherwise.
*/
public boolean requiresNetwork() {
return mRequiresNetwork;
}
/**
* Returns true if the provider requires access to a
* satellite-based positioning system (e.g., GPS), false
* otherwise.
*/
public boolean requiresSatellite() {
return mRequiresSatellite;
}
/**
* Returns true if the provider requires access to an appropriate
* cellular network (e.g., to make use of cell tower IDs), false
* otherwise.
*/
public boolean requiresCell() {
return mRequiresCell;
}
/**
* 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.
*/
public boolean hasMonetaryCost() {
return mHasMonetaryCost;
}
/**
* 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.
*/
public boolean supportsAltitude() {
return mSupportsAltitude;
}
/**
* 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.
*/
public boolean supportsSpeed() {
return mSupportsSpeed;
}
/**
* 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.
*/
public boolean supportsBearing() {
return mSupportsBearing;
}
/**
* Returns the power requirement for this provider.
*
* @return the power requirement for this provider, as one of the
* constants Criteria.POWER_REQUIREMENT_*.
*/
public int getPowerRequirement() {
return mPowerRequirement;
}
/**
* Returns a constant describing the horizontal accuracy returned
* by this provider.
*
* @return the horizontal accuracy for this provider, as one of the
* constants Criteria.ACCURACY_*.
*/
public int getAccuracy() {
return mAccuracy;
}
}

View File

@ -0,0 +1,565 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.
*/
package com.android.internal.location;
import java.io.UnsupportedEncodingException;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
/**
* A GPS Network-initiated Handler class used by LocationManager.
*
* {@hide}
*/
public class GpsNetInitiatedHandler {
private static final String TAG = "GpsNetInitiatedHandler";
private static final boolean DEBUG = true;
private static final boolean VERBOSE = false;
// NI verify activity for bringing up UI (not used yet)
public static final String ACTION_NI_VERIFY = "android.intent.action.NETWORK_INITIATED_VERIFY";
// string constants for defining data fields in NI Intent
public static final String NI_INTENT_KEY_NOTIF_ID = "notif_id";
public static final String NI_INTENT_KEY_TITLE = "title";
public static final String NI_INTENT_KEY_MESSAGE = "message";
public static final String NI_INTENT_KEY_TIMEOUT = "timeout";
public static final String NI_INTENT_KEY_DEFAULT_RESPONSE = "default_resp";
// the extra command to send NI response to GpsLocationProvider
public static final String NI_RESPONSE_EXTRA_CMD = "send_ni_response";
// the extra command parameter names in the Bundle
public static final String NI_EXTRA_CMD_NOTIF_ID = "notif_id";
public static final String NI_EXTRA_CMD_RESPONSE = "response";
// the extra fields to be displayed
public static final String NI_NOTIFY_ADDR_KEY = "Address";
// these need to match GpsNiType constants in gps_ni.h
public static final int GPS_NI_TYPE_VOICE = 1;
public static final int GPS_NI_TYPE_UMTS_SUPL = 2;
public static final int GPS_NI_TYPE_UMTS_CTRL_PLANE = 3;
// these need to match GpsUserResponseType constants in gps_ni.h
public static final int GPS_NI_RESPONSE_ACCEPT = 1;
public static final int GPS_NI_RESPONSE_DENY = 2;
public static final int GPS_NI_RESPONSE_NORESP = 3;
// these need to match GpsNiNotifyFlags constants in gps_ni.h
public static final int GPS_NI_NEED_NOTIFY = 0x0001;
public static final int GPS_NI_NEED_VERIFY = 0x0002;
public static final int GPS_NI_PRIVACY_OVERRIDE = 0x0004;
// these need to match GpsNiEncodingType in gps_ni.h
public static final int GPS_ENC_NONE = 0;
public static final int GPS_ENC_SUPL_GSM_DEFAULT = 1;
public static final int GPS_ENC_SUPL_UTF8 = 2;
public static final int GPS_ENC_SUPL_UCS2 = 3;
public static final int GPS_ENC_UNKNOWN = -1;
// This is a lookup table implemented from GSM 7 bit default alphabet and
// extension table of 3GPP TS 23.038 / GSM 03.38 standard
private static final int lookupForGsmAsciii[] =
{64, 163, 36, 165, 232, 233, 249, 236, 242, 199, 10, 216, 248,
13, 197, 229, 63, 95, 63, 63, 63, 63, 63, 63, 63, 63,
63, 27, 198, 230, 223, 201, 32, 33, 34, 35, 164, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 161,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
196, 214, 209, 220, 167, 191, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 228, 246, 241, 252, 224 };
private final Context mContext;
// parent gps location provider
private final LocationManager mLocationManager;
// configuration of notificaiton behavior
private boolean mPlaySounds = false;
private boolean visible = true;
private boolean mPopupImmediately = true;
// Set to true if string from HAL is encoded as Hex, e.g., "3F0039"
static private boolean mIsHexInput = true;
public static class GpsNiNotification
{
public int notificationId;
public int niType;
public boolean needNotify;
public boolean needVerify;
public boolean privacyOverride;
public int timeout;
public int defaultResponse;
public String requestorId;
public String text;
public int requestorIdEncoding;
public int textEncoding;
public Bundle extras;
};
public static class GpsNiResponse {
/* User reponse, one of the values in GpsUserResponseType */
int userResponse;
/* Optional extra data to pass with the user response */
Bundle extras;
};
/**
* The notification that is shown when a network-initiated notification
* (and verification) event is received.
* <p>
* This is lazily created, so use {@link #setNINotification()}.
*/
private Notification mNiNotification;
public GpsNetInitiatedHandler(Context context) {
mContext = context;
mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
}
// Handles NI events from HAL
public void handleNiNotification(GpsNiNotification notif)
{
if (DEBUG) Log.d(TAG, "handleNiNotification" + " notificationId: " + notif.notificationId
+ " requestorId: " + notif.requestorId + " text: " + notif.text);
// Notify and verify with immediate pop-up
if (notif.needNotify && notif.needVerify && mPopupImmediately)
{
// Popup the dialog box now
openNiDialog(notif);
}
// Notify only, or delayed pop-up (change mPopupImmediately to FALSE)
if (notif.needNotify && !notif.needVerify ||
notif.needNotify && notif.needVerify && !mPopupImmediately)
{
// Show the notification
// if mPopupImmediately == FALSE and needVerify == TRUE, a dialog will be opened
// when the user opens the notification message
setNiNotification(notif);
}
// ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; 3. privacy override.
if ( notif.needNotify && !notif.needVerify ||
!notif.needNotify && !notif.needVerify ||
notif.privacyOverride)
{
mLocationManager.sendNiResponse(notif.notificationId, GPS_NI_RESPONSE_ACCEPT);
}
//////////////////////////////////////////////////////////////////////////
// A note about timeout
// According to the protocol, in the need_notify and need_verify case,
// a default response should be sent when time out.
//
// In some GPS hardware, the GPS driver (under HAL) can handle the timeout case
// and this class GpsNetInitiatedHandler does not need to do anything.
//
// However, the UI should at least close the dialog when timeout. Further,
// for more general handling, timeout response should be added to the Handler here.
//
}
// Sets the NI notification.
private synchronized void setNiNotification(GpsNiNotification notif) {
NotificationManager notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) {
return;
}
String title = getNotifTitle(notif);
String message = getNotifMessage(notif);
if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
", title: " + title +
", message: " + message);
// Construct Notification
if (mNiNotification == null) {
mNiNotification = new Notification();
mNiNotification.icon = com.android.internal.R.drawable.stat_sys_gps_on; /* Change notification icon here */
mNiNotification.when = 0;
}
if (mPlaySounds) {
mNiNotification.defaults |= Notification.DEFAULT_SOUND;
} else {
mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
}
mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
mNiNotification.tickerText = getNotifTicker(notif);
// if not to popup dialog immediately, pending intent will open the dialog
Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
mNiNotification.setLatestEventInfo(mContext, title, message, pi);
if (visible) {
notificationManager.notify(notif.notificationId, mNiNotification);
} else {
notificationManager.cancel(notif.notificationId);
}
}
// Opens the notification dialog and waits for user input
private void openNiDialog(GpsNiNotification notif)
{
Intent intent = getDlgIntent(notif);
if (DEBUG) Log.d(TAG, "openNiDialog, notifyId: " + notif.notificationId +
", requestorId: " + notif.requestorId +
", text: " + notif.text);
mContext.startActivity(intent);
}
// Construct the intent for bringing up the dialog activity, which shows the
// notification and takes user input
private Intent getDlgIntent(GpsNiNotification notif)
{
Intent intent = new Intent();
String title = getDialogTitle(notif);
String message = getDialogMessage(notif);
// directly bring up the NI activity
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class);
// put data in the intent
intent.putExtra(NI_INTENT_KEY_NOTIF_ID, notif.notificationId);
intent.putExtra(NI_INTENT_KEY_TITLE, title);
intent.putExtra(NI_INTENT_KEY_MESSAGE, message);
intent.putExtra(NI_INTENT_KEY_TIMEOUT, notif.timeout);
intent.putExtra(NI_INTENT_KEY_DEFAULT_RESPONSE, notif.defaultResponse);
if (DEBUG) Log.d(TAG, "generateIntent, title: " + title + ", message: " + message +
", timeout: " + notif.timeout);
return intent;
}
// Converts a string (or Hex string) to a char array
static byte[] stringToByteArray(String original, boolean isHex)
{
int length = isHex ? original.length() / 2 : original.length();
byte[] output = new byte[length];
int i;
if (isHex)
{
for (i = 0; i < length; i++)
{
output[i] = (byte) Integer.parseInt(original.substring(i*2, i*2+2), 16);
}
}
else {
for (i = 0; i < length; i++)
{
output[i] = (byte) original.charAt(i);
}
}
return output;
}
/**
* Unpacks an byte array containing 7-bit packed characters into a String.
*
* @param input a 7-bit packed char array
* @return the unpacked String
*/
static String decodeGSMPackedString(byte[] input)
{
final char CHAR_CR = 0x0D;
int nStridx = 0;
int nPckidx = 0;
int num_bytes = input.length;
int cPrev = 0;
int cCurr = 0;
byte nShift;
byte nextChar;
byte[] stringBuf = new byte[input.length * 2];
String result = "";
int numOfEscapeChars = 0;
while(nPckidx < num_bytes)
{
nShift = (byte) (nStridx & 0x07);
cCurr = input[nPckidx++];
if (cCurr < 0) cCurr += 256;
/* A 7-bit character can be split at the most between two bytes of packed
** data.
*/
nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
stringBuf[nStridx++] = nextChar;
/* Need to count the number of escape characters here in order to properly
* format the output string
*/
if(nextChar == 0x1b)
numOfEscapeChars++;
/* Special case where the whole of the next 7-bit character fits inside
** the current byte of packed data.
*/
if(nShift == 6)
{
/* If the next 7-bit character is a CR (0x0D) and it is the last
** character, then it indicates a padding character. Drop it.
*/
if (nPckidx == num_bytes && (cCurr >> 1) == CHAR_CR)
{
break;
}
nextChar = (byte) (cCurr >> 1);
stringBuf[nStridx++] = nextChar;
}
cPrev = cCurr;
}
/* We need to convert the data in unpacked 7 bit format into normal ASCII
* using a lookup table
*/
byte[] resultIntermediate = convertGsmIntoAscii(stringBuf) ;
try {
result = new String(resultIntermediate, 0, (nStridx - numOfEscapeChars), "US-ASCII");
}
catch (UnsupportedEncodingException e)
{
Log.e(TAG, e.getMessage());
}
return result;
}
/**
* Converts a byte array containing 7-bit GSM characters into
* the equivalent ASCII format as specified in the GSM 7 bit
* default alphabet and extension table of 3GPP TS 23.038 / GSM
* 03.38 standard
*
* @param input a 7-bit unpacked byte array
* @return equivalent 8-bit ASCII byte array
*/
static byte[] convertGsmIntoAscii(byte input[])
{
if(input == null)
{
Log.e(TAG, "Received null input for convertGsmIntoAscii() function");
return input;
}
byte[] stringBuf = new byte[input.length];
int nStringIndex = 0;
int nInputIndex = 0;
while(nInputIndex < input.length)
{
stringBuf[nStringIndex] = (byte) lookupForGsmAsciii[input[nInputIndex++]];
if(stringBuf[nStringIndex] == 0x1b)
{
if(nInputIndex >= input.length)
{
Log.e(TAG, "The input is malformed with ESC as last char. Aborting");
return stringBuf;
}
//We got the escape charchater so we will have to use the extension table
//for the character coversion here. Need to get the next byte for processing
switch (input[nInputIndex]) {
case 10:
stringBuf[nStringIndex]=12;
break;
case 20:
stringBuf[nStringIndex]='^';
break;
case 40:
stringBuf[nStringIndex]='{';
break;
case 41:
stringBuf[nStringIndex]='}';
break;
case 47:
stringBuf[nStringIndex]='\\';
break;
case 60:
stringBuf[nStringIndex]='[';
break;
case 61:
stringBuf[nStringIndex]='~';
break;
case 62:
stringBuf[nStringIndex]=']';
break;
case 64:
stringBuf[nStringIndex]='|';
break;
default:
stringBuf[nStringIndex]=0;
break;
}
}
nStringIndex++;
}
return stringBuf;
}
static String decodeUTF8String(byte[] input)
{
String decoded = "";
try {
decoded = new String(input, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
Log.e(TAG, e.getMessage());
}
return decoded;
}
static String decodeUCS2String(byte[] input)
{
String decoded = "";
try {
decoded = new String(input, "UTF-16");
}
catch (UnsupportedEncodingException e)
{
Log.e(TAG, e.getMessage());
}
return decoded;
}
/** Decode NI string
*
* @param original The text string to be decoded
* @param isHex Specifies whether the content of the string has been encoded as a Hex string. Encoding
* a string as Hex can allow zeros inside the coded text.
* @param coding Specifies the coding scheme of the string, such as GSM, UTF8, UCS2, etc. This coding scheme
* needs to match those used passed to HAL from the native GPS driver. Decoding is done according
* to the <code> coding </code>, after a Hex string is decoded. Generally, if the
* notification strings don't need further decoding, <code> coding </code> encoding can be
* set to -1, and <code> isHex </code> can be false.
* @return the decoded string
*/
static private String decodeString(String original, boolean isHex, int coding)
{
String decoded = original;
byte[] input = stringToByteArray(original, isHex);
switch (coding) {
case GPS_ENC_NONE:
decoded = original;
break;
case GPS_ENC_SUPL_GSM_DEFAULT:
decoded = decodeGSMPackedString(input);
break;
case GPS_ENC_SUPL_UTF8:
decoded = decodeUTF8String(input);
break;
case GPS_ENC_SUPL_UCS2:
decoded = decodeUCS2String(input);
break;
case GPS_ENC_UNKNOWN:
decoded = original;
break;
default:
Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
break;
}
return decoded;
}
// change this to configure notification display
static private String getNotifTicker(GpsNiNotification notif)
{
String ticker = String.format("Position request! ReqId: [%s] ClientName: [%s]",
decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
decodeString(notif.text, mIsHexInput, notif.textEncoding));
return ticker;
}
// change this to configure notification display
static private String getNotifTitle(GpsNiNotification notif)
{
String title = String.format("Position Request");
return title;
}
// change this to configure notification display
static private String getNotifMessage(GpsNiNotification notif)
{
String message = String.format(
"NI Request received from [%s] for client [%s]",
decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
decodeString(notif.text, mIsHexInput, notif.textEncoding));
// Extra fields to be displayed
StringBuffer extraBuf = new StringBuffer();
String addrString = notif.extras.getString(NI_NOTIFY_ADDR_KEY);
if (addrString != null)
{
extraBuf.append(" ");
extraBuf.append(NI_NOTIFY_ADDR_KEY);
extraBuf.append(": [");
extraBuf.append(addrString); // no decoding needed for the address
extraBuf.append("]");
}
message += extraBuf.toString();
return message;
}
// change this to configure dialog display (for verification)
static public String getDialogTitle(GpsNiNotification notif)
{
return getNotifTitle(notif);
}
// change this to configure dialog display (for verification)
static private String getDialogMessage(GpsNiNotification notif)
{
return getNotifMessage(notif);
}
}