Bug 636344 - Android Geolocation provider does not provide geocoded civic addresses. r=blassey

This commit is contained in:
Doug Turner 2011-03-17 00:03:11 -07:00
parent 8fdd494594
commit 3a3e07ec3c
7 changed files with 157 additions and 7 deletions

View File

@ -68,8 +68,8 @@ public:
const nsAString &aCountryCode,
const nsAString &aPostalCode);
private:
~nsGeoPositionAddress();
private:
const nsString mStreetNumber;
const nsString mStreet;
const nsString mPremises;
@ -127,6 +127,10 @@ public:
nsIDOMGeoPositionAddress *aAddress,
DOMTimeStamp aTimestamp);
void SetAddress(nsIDOMGeoPositionAddress *address) {
mAddress = address;
}
private:
~nsGeoPosition();
long long mTimestamp;

View File

@ -571,7 +571,7 @@ public class GeckoAppShell
Location loc = lm.getLastKnownLocation(provider);
if (loc != null)
sendEventToGecko(new GeckoEvent(loc));
sendEventToGecko(new GeckoEvent(loc, null));
lm.requestLocationUpdates(provider, 100, (float).5, GeckoApp.surfaceView, Looper.getMainLooper());
} else {
lm.removeUpdates(GeckoApp.surfaceView);

View File

@ -67,7 +67,6 @@ public class GeckoEvent {
public static final int ACTIVITY_PAUSING = 9;
public static final int ACTIVITY_SHUTDOWN = 10;
public static final int LOAD_URI = 11;
public static final int SURFACE_CREATED = 12;
public static final int SURFACE_DESTROYED = 13;
public static final int GECKO_EVENT_SYNC = 14;
@ -105,6 +104,7 @@ public class GeckoEvent {
public int mRangeType, mRangeStyles;
public int mRangeForeColor, mRangeBackColor;
public Location mLocation;
public Address mAddress;
public int mNativeWindow;
@ -145,9 +145,10 @@ public class GeckoEvent {
mZ = s.values[2] / SensorManager.GRAVITY_EARTH;
}
public GeckoEvent(Location l) {
public GeckoEvent(Location l, Address a) {
mType = LOCATION_EVENT;
mLocation = l;
mAddress = a;
}
public GeckoEvent(int imeAction, int offset, int count) {

View File

@ -413,10 +413,46 @@ class GeckoSurfaceView
GeckoAppShell.sendEventToGecko(new GeckoEvent(event));
}
private class GeocoderTask extends AsyncTask<Location, Void, Void> {
protected Void doInBackground(Location... location) {
try {
List<Address> addresses = mGeocoder.getFromLocation(location[0].getLatitude(),
location[0].getLongitude(), 1);
// grab the first address. in the future,
// may want to expose multiple, or filter
// for best.
mLastGeoAddress = addresses.get(0);
} catch (Exception e) {
Log.w("GeckoSurfaceView", "GeocoderTask "+e);
}
return null;
}
}
// geolocation
public void onLocationChanged(Location location)
{
GeckoAppShell.sendEventToGecko(new GeckoEvent(location));
if (mGeocoder == null)
mGeocoder = new Geocoder(getContext());
if (mLastGeoAddress == null) {
new GeocoderTask().execute(location);
}
else {
float[] results = new float[1];
Location.distanceBetween(location.getLatitude(),
location.getLongitude(),
mLastGeoAddress.getLatitude(),
mLastGeoAddress.getLongitude(),
results);
// pfm value. don't want to slam the
// geocoder with very similar values, so
// only call after about 100m
if (results[0] > 100)
new GeocoderTask().execute(location);
}
GeckoAppShell.sendEventToGecko(new GeckoEvent(location, mLastGeoAddress));
}
public void onProviderDisabled(String provider)
@ -592,6 +628,9 @@ class GeckoSurfaceView
ByteBuffer mSoftwareBuffer;
Bitmap mSoftwareBitmap;
Geocoder mGeocoder;
Address mLastGeoAddress;
final SynchronousQueue<ByteBuffer> mSyncBuf = new SynchronousQueue<ByteBuffer>();
}

View File

@ -64,6 +64,7 @@ jfieldID AndroidGeckoEvent::jRangeStylesField = 0;
jfieldID AndroidGeckoEvent::jRangeForeColorField = 0;
jfieldID AndroidGeckoEvent::jRangeBackColorField = 0;
jfieldID AndroidGeckoEvent::jLocationField = 0;
jfieldID AndroidGeckoEvent::jAddressField = 0;
jclass AndroidPoint::jPointClass = 0;
jfieldID AndroidPoint::jXField = 0;
@ -84,6 +85,20 @@ jmethodID AndroidLocation::jGetBearingMethod = 0;
jmethodID AndroidLocation::jGetSpeedMethod = 0;
jmethodID AndroidLocation::jGetTimeMethod = 0;
jclass AndroidAddress::jAddressClass = 0;
jmethodID AndroidAddress::jGetAddressLineMethod;
jmethodID AndroidAddress::jGetAdminAreaMethod;
jmethodID AndroidAddress::jGetCountryCodeMethod;
jmethodID AndroidAddress::jGetCountryNameMethod;
jmethodID AndroidAddress::jGetFeatureNameMethod;
jmethodID AndroidAddress::jGetLocalityMethod;
jmethodID AndroidAddress::jGetPostalCodeMethod;
jmethodID AndroidAddress::jGetPremisesMethod;
jmethodID AndroidAddress::jGetSubAdminAreaMethod;
jmethodID AndroidAddress::jGetSubLocalityMethod;
jmethodID AndroidAddress::jGetSubThoroughfareMethod;
jmethodID AndroidAddress::jGetThoroughfareMethod;
jclass AndroidGeckoSurfaceView::jGeckoSurfaceViewClass = 0;
jmethodID AndroidGeckoSurfaceView::jBeginDrawingMethod = 0;
jmethodID AndroidGeckoSurfaceView::jEndDrawingMethod = 0;
@ -112,6 +127,7 @@ mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv)
AndroidGeckoSurfaceView::InitGeckoSurfaceViewClass(jEnv);
AndroidPoint::InitPointClass(jEnv);
AndroidLocation::InitLocationClass(jEnv);
AndroidAddress::InitAddressClass(jEnv);
}
void
@ -143,6 +159,7 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
jRangeForeColorField = getField("mRangeForeColor", "I");
jRangeBackColorField = getField("mRangeBackColor", "I");
jLocationField = getField("mLocation", "Landroid/location/Location;");
jAddressField = getField("mAddress", "Landroid/location/Address;");
}
void
@ -174,6 +191,62 @@ AndroidLocation::InitLocationClass(JNIEnv *jEnv)
jGetTimeMethod = getMethod("getTime", "()J");
}
void
AndroidAddress::InitAddressClass(JNIEnv *jEnv)
{
initInit();
jAddressClass = getClassGlobalRef("android/location/Address");
jGetAddressLineMethod = getMethod("getAddressLine", "(I)Ljava/lang/String;");
jGetAdminAreaMethod = getMethod("getAdminArea", "()Ljava/lang/String;");
jGetCountryCodeMethod = getMethod("getCountryCode", "()Ljava/lang/String;");
jGetCountryNameMethod = getMethod("getCountryName", "()Ljava/lang/String;");
jGetFeatureNameMethod = getMethod("getFeatureName", "()Ljava/lang/String;");
jGetLocalityMethod = getMethod("getLocality", "()Ljava/lang/String;");
jGetPostalCodeMethod = getMethod("getPostalCode", "()Ljava/lang/String;");
jGetPremisesMethod = getMethod("getPremises", "()Ljava/lang/String;");
jGetSubAdminAreaMethod = getMethod("getSubAdminArea", "()Ljava/lang/String;");
jGetSubLocalityMethod = getMethod("getSubLocality", "()Ljava/lang/String;");
jGetSubThoroughfareMethod = getMethod("getSubThoroughfare", "()Ljava/lang/String;");
jGetThoroughfareMethod = getMethod("getThoroughfare", "()Ljava/lang/String;");
}
nsGeoPositionAddress*
AndroidAddress::CreateGeoPositionAddress(JNIEnv *jenv, jobject jobj)
{
nsJNIString streetNumber(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetSubThoroughfareMethod)), jenv);
nsJNIString street(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetThoroughfareMethod)), jenv);
nsJNIString city(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetLocalityMethod)), jenv);
nsJNIString county(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetSubAdminAreaMethod)), jenv);
nsJNIString country(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetCountryNameMethod)), jenv);
nsJNIString countryCode(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetCountryCodeMethod)), jenv);
nsJNIString premises(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetPremisesMethod)), jenv);
nsJNIString postalCode(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetPostalCodeMethod)), jenv);
nsJNIString region(static_cast<jstring>(jenv->CallObjectMethod(jobj, jGetAdminAreaMethod, 0)), jenv);
printf_stderr("!!!!!!!!!!!!!! AndroidAddress::CreateGeoPositionAddress:\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n",
NS_LossyConvertUTF16toASCII(streetNumber).get(),
NS_LossyConvertUTF16toASCII(street).get(),
NS_LossyConvertUTF16toASCII(premises).get(),
NS_LossyConvertUTF16toASCII(city).get(),
NS_LossyConvertUTF16toASCII(county).get(),
NS_LossyConvertUTF16toASCII(region).get(),
NS_LossyConvertUTF16toASCII(country).get(),
NS_LossyConvertUTF16toASCII(countryCode).get(),
NS_LossyConvertUTF16toASCII(postalCode).get());
return new nsGeoPositionAddress(streetNumber,
street,
premises,
city,
county,
region,
country,
countryCode,
postalCode);
}
nsGeoPosition*
AndroidLocation::CreateGeoPosition(JNIEnv *jenv, jobject jobj)
{
@ -331,7 +404,11 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
case LOCATION_EVENT: {
jobject location = jenv->GetObjectField(jobj, jLocationField);
jobject address = jenv->GetObjectField(jobj, jAddressField);
mGeoPosition = AndroidLocation::CreateGeoPosition(jenv, location);
if (address)
mGeoAddress = AndroidAddress::CreateGeoPositionAddress(jenv, address);
break;
}

View File

@ -347,6 +347,26 @@ public:
static jmethodID jGetTimeMethod;
};
class AndroidAddress : public WrappedJavaObject
{
public:
static void InitAddressClass(JNIEnv *jEnv);
static nsGeoPositionAddress* CreateGeoPositionAddress(JNIEnv *jenv, jobject jobj);
static jclass jAddressClass;
static jmethodID jGetAddressLineMethod;
static jmethodID jGetAdminAreaMethod;
static jmethodID jGetCountryCodeMethod;
static jmethodID jGetCountryNameMethod;
static jmethodID jGetFeatureNameMethod;
static jmethodID jGetLocalityMethod;
static jmethodID jGetPostalCodeMethod;
static jmethodID jGetPremisesMethod;
static jmethodID jGetSubAdminAreaMethod;
static jmethodID jGetSubLocalityMethod;
static jmethodID jGetSubThoroughfareMethod;
static jmethodID jGetThoroughfareMethod;
};
class AndroidGeckoEvent : public WrappedJavaObject
{
public:
@ -388,6 +408,7 @@ public:
int RangeForeColor() { return mRangeForeColor; }
int RangeBackColor() { return mRangeBackColor; }
nsGeoPosition* GeoPosition() { return mGeoPosition; }
nsGeoPositionAddress* GeoAddress() { return mGeoAddress; }
protected:
int mAction;
@ -404,6 +425,7 @@ protected:
float mX, mY, mZ;
nsString mCharacters;
nsRefPtr<nsGeoPosition> mGeoPosition;
nsRefPtr<nsGeoPositionAddress> mGeoAddress;
void ReadP0Field(JNIEnv *jenv);
void ReadP1Field(JNIEnv *jenv);
@ -434,6 +456,7 @@ protected:
static jfieldID jRangeForeColorField;
static jfieldID jRangeBackColorField;
static jfieldID jLocationField;
static jfieldID jAddressField;
public:
enum {

View File

@ -324,15 +324,21 @@ nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
gAccel->AccelerationChanged(-curEvent->X(), curEvent->Y(), curEvent->Z());
break;
case AndroidGeckoEvent::LOCATION_EVENT:
case AndroidGeckoEvent::LOCATION_EVENT: {
if (!gLocationCallback)
break;
if (curEvent->GeoPosition())
nsGeoPosition* p = curEvent->GeoPosition();
nsGeoPositionAddress* a = curEvent->GeoAddress();
if (p) {
p->SetAddress(a);
gLocationCallback->Update(curEvent->GeoPosition());
}
else
NS_WARNING("Received location event without geoposition!");
break;
}
case AndroidGeckoEvent::ACTIVITY_STOPPING: {
nsCOMPtr<nsIObserverService> obsServ =