summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--navit/android/src/org/navitproject/navit/NavitVehicle.java70
-rw-r--r--navit/vehicle/android/vehicle_android.c84
2 files changed, 131 insertions, 23 deletions
diff --git a/navit/android/src/org/navitproject/navit/NavitVehicle.java b/navit/android/src/org/navitproject/navit/NavitVehicle.java
index 5add7765e..e42a18470 100644
--- a/navit/android/src/org/navitproject/navit/NavitVehicle.java
+++ b/navit/android/src/org/navitproject/navit/NavitVehicle.java
@@ -19,8 +19,13 @@
package org.navitproject.navit;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.location.Criteria;
+import android.location.GpsSatellite;
+import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
@@ -28,11 +33,16 @@ import android.os.Bundle;
import android.util.Log;
public class NavitVehicle {
+
+ public static final String GPS_FIX_CHANGE = "android.location.GPS_FIX_CHANGE";
public static Location lastLocation = null;
private static LocationManager sLocationManager = null;
- private int vehicle_callbackid;
+ private static Context context = null;
+ private int vehicle_pcbid;
+ private int vehicle_scbid;
+ private int vehicle_fcbid;
private String preciseProvider;
private String fastProvider;
@@ -40,8 +50,10 @@ public class NavitVehicle {
private static NavitLocationListener fastLocationListener = null;
public native void VehicleCallback(int id, Location location);
+ public native void VehicleCallback(int id, int satsInView, int satsUsed);
+ public native void VehicleCallback(int id, int enabled);
- private class NavitLocationListener implements LocationListener {
+ private class NavitLocationListener extends BroadcastReceiver implements GpsStatus.Listener, LocationListener {
public boolean precise = false;
public void onLocationChanged(Location location) {
lastLocation = location;
@@ -51,14 +63,52 @@ public class NavitVehicle {
fastProvider = null;
}
- VehicleCallback(vehicle_callbackid, location);
+ VehicleCallback(vehicle_pcbid, location);
+ VehicleCallback(vehicle_fcbid, 1);
}
public void onProviderDisabled(String provider){}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
+
+ /**
+ * Called when the status of the GPS changes.
+ */
+ public void onGpsStatusChanged (int event) {
+ GpsStatus status = sLocationManager.getGpsStatus(null);
+ int satsInView = 0;
+ int satsUsed = 0;
+ Iterable<GpsSatellite> sats = status.getSatellites();
+ for (GpsSatellite sat : sats) {
+ satsInView++;
+ if (sat.usedInFix()) {
+ satsUsed++;
+ }
+ }
+ VehicleCallback(vehicle_scbid, satsInView, satsUsed);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(GPS_FIX_CHANGE)) {
+ if (intent.getBooleanExtra("enabled", false))
+ VehicleCallback(vehicle_fcbid, 1);
+ else if (!intent.getBooleanExtra("enabled", true))
+ VehicleCallback(vehicle_fcbid, 0);
+ }
+ }
}
- NavitVehicle (Context context, int callbackid) {
+ /**
+ * @brief Creates a new {@code NavitVehicle}
+ *
+ * @param context
+ * @param pcbid The address of the position callback function which will be called when a location update is received
+ * @param scbid The address of the status callback function which will be called when a status update is received
+ * @param fcbid The address of the fix callback function which will be called when a
+ * {@code android.location.GPS_FIX_CHANGE} is received, indicating a change in GPS fix status
+ */
+ NavitVehicle (Context context, int pcbid, int scbid, int fcbid) {
+ this.context = context;
sLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
preciseLocationListener = new NavitLocationListener();
preciseLocationListener.precise = true;
@@ -90,9 +140,13 @@ public class NavitVehicle {
Log.e("NavitVehicle", "Precise Provider " + preciseProvider);
fastProvider = sLocationManager.getBestProvider(lowCriteria, false);
Log.e("NavitVehicle", "Fast Provider " + fastProvider);
- vehicle_callbackid=callbackid;
+ vehicle_pcbid = pcbid;
+ vehicle_scbid = scbid;
+ vehicle_fcbid = fcbid;
+ context.registerReceiver(preciseLocationListener, new IntentFilter(GPS_FIX_CHANGE));
sLocationManager.requestLocationUpdates(preciseProvider, 0, 0, preciseLocationListener);
+ sLocationManager.addGpsStatusListener(preciseLocationListener);
// If the 2 providers are the same, only activate one listener
if (fastProvider == null || preciseProvider.compareTo(fastProvider) == 0) {
@@ -104,7 +158,11 @@ public class NavitVehicle {
public static void removeListener() {
if (sLocationManager != null) {
- if (preciseLocationListener != null) sLocationManager.removeUpdates(preciseLocationListener);
+ if (preciseLocationListener != null) {
+ sLocationManager.removeUpdates(preciseLocationListener);
+ sLocationManager.removeGpsStatusListener(preciseLocationListener);
+ context.unregisterReceiver(preciseLocationListener);
+ }
if (fastLocationListener != null) sLocationManager.removeUpdates(fastLocationListener);
}
diff --git a/navit/vehicle/android/vehicle_android.c b/navit/vehicle/android/vehicle_android.c
index 4a4d52480..8f1c3aa70 100644
--- a/navit/vehicle/android/vehicle_android.c
+++ b/navit/vehicle/android/vehicle_android.c
@@ -42,17 +42,19 @@ struct vehicle_priv {
double direction; /**< Bearing in degrees **/
double height; /**< Elevation in meters **/
double radius; /**< Position accuracy in meters **/
- int fix_type; /**< Type of last fix (not used) **/
+ int fix_type; /**< Type of last fix (1 = valid, 0 = invalid) **/
time_t fix_time; /**< Timestamp of last fix (not used) **/
char fixiso8601[128]; /**< Timestamp of last fix in ISO 8601 format **/
- int sats; /**< Number of satellites in view (currently not used) **/
- int sats_used; /**< Number of satellites used in fix (currently not used) **/
+ int sats; /**< Number of satellites in view **/
+ int sats_used; /**< Number of satellites used in fix **/
int have_coords; /**< Whether the vehicle coordinates in {@code geo} are valid **/
struct attr ** attrs;
- struct callback *cb;
- jclass NavitVehicleClass;
- jobject NavitVehicle;
- jclass LocationClass;
+ struct callback *pcb; /**< The callback function for position updates **/
+ struct callback *scb; /**< The callback function for status updates **/
+ struct callback *fcb; /**< The callback function for fix status updates **/
+ jclass NavitVehicleClass; /**< The {@code NavitVehicle} class **/
+ jobject NavitVehicle; /**< An instance of {@code NavitVehicle} **/
+ jclass LocationClass; /**< Android's {@code Location} class **/
jmethodID Location_getLatitude, Location_getLongitude, Location_getSpeed, Location_getBearing, Location_getAltitude, Location_getTime, Location_getAccuracy;
};
@@ -83,11 +85,9 @@ vehicle_android_position_attr_get(struct vehicle_priv *priv,
{
dbg(1,"enter %s\n",attr_to_name(type));
switch (type) {
-#if 0
case attr_position_fix_type:
attr->u.num = priv->fix_type;
break;
-#endif
case attr_position_height:
attr->u.numd = &priv->height;
break;
@@ -100,15 +100,12 @@ vehicle_android_position_attr_get(struct vehicle_priv *priv,
case attr_position_radius:
attr->u.numd = &priv->radius;
break;
-
-#if 0
case attr_position_qual:
attr->u.num = priv->sats;
break;
case attr_position_sats_used:
attr->u.num = priv->sats_used;
break;
-#endif
case attr_position_coord_geo:
attr->u.coord_geo = &priv->geo;
if (!priv->have_coords)
@@ -133,9 +130,16 @@ struct vehicle_methods vehicle_android_methods = {
vehicle_android_position_attr_get,
};
+/**
+ * @brief Called when a new position has been reported
+ *
+ * This function is called by {@code NavitLocationListener} upon receiving a new {@code Location}.
+ *
+ * @param v The {@code struct_vehicle_priv} for the vehicle
+ * @param location A {@code Location} object describing the new position
+ */
static void
-vehicle_android_callback(struct vehicle_priv *v, jobject location)
-{
+vehicle_android_position_callback(struct vehicle_priv *v, jobject location) {
time_t tnow;
struct tm *tm;
dbg(1,"enter\n");
@@ -157,6 +161,48 @@ vehicle_android_callback(struct vehicle_priv *v, jobject location)
callback_list_call_attr_0(v->cbl, attr_position_coord_geo);
}
+/**
+ * @brief Called when a new GPS status has been reported
+ *
+ * This function is called by {@code NavitLocationListener} upon receiving a new {@code GpsStatus}.
+ *
+ * @param v The {@code struct_vehicle_priv} for the vehicle
+ * @param sats_in_view The number of satellites in view
+ * @param sats_used The number of satellites currently used to determine the position
+ */
+static void
+vehicle_android_status_callback(struct vehicle_priv *v, int sats_in_view, int sats_used) {
+ if (v->sats != sats_in_view) {
+ v->sats = sats_in_view;
+ callback_list_call_attr_0(v->cbl, attr_position_qual);
+ }
+ if (v->sats_used != sats_used) {
+ v->sats_used = sats_used;
+ callback_list_call_attr_0(v->cbl, attr_position_sats_used);
+ }
+}
+
+/**
+ * @brief Called when a change in GPS fix status has been reported
+ *
+ * This function is called by {@code NavitLocationListener} upon receiving a new {@code android.location.GPS_FIX_CHANGE} broadcast.
+ *
+ * @param v The {@code struct_vehicle_priv} for the vehicle
+ * @param fix_type The fix type (1 = valid, 0 = invalid)
+ */
+static void
+vehicle_android_fix_callback(struct vehicle_priv *v, int fix_type) {
+ if (v->fix_type != fix_type) {
+ v->fix_type = fix_type;
+ callback_list_call_attr_0(v->cbl, attr_position_fix_type);
+ }
+}
+
+/**
+ * @brief Initializes an Android vehicle
+ *
+ * @return True on success, false on failure
+ */
static int
vehicle_android_init(struct vehicle_priv *ret)
{
@@ -181,13 +227,13 @@ vehicle_android_init(struct vehicle_priv *ret)
if (!android_find_class_global("org/navitproject/navit/NavitVehicle", &ret->NavitVehicleClass))
return 0;
dbg(0,"at 3\n");
- cid = (*jnienv)->GetMethodID(jnienv, ret->NavitVehicleClass, "<init>", "(Landroid/content/Context;I)V");
+ cid = (*jnienv)->GetMethodID(jnienv, ret->NavitVehicleClass, "<init>", "(Landroid/content/Context;III)V");
if (cid == NULL) {
dbg(0,"no method found\n");
return 0; /* exception thrown */
}
dbg(0,"at 4 android_activity=%p\n",android_activity);
- ret->NavitVehicle=(*jnienv)->NewObject(jnienv, ret->NavitVehicleClass, cid, android_activity, (int) ret->cb);
+ ret->NavitVehicle=(*jnienv)->NewObject(jnienv, ret->NavitVehicleClass, cid, android_activity, (int) ret->pcb, (int) ret->scb, (int) ret->fcb);
dbg(0,"result=%p\n",ret->NavitVehicle);
if (!ret->NavitVehicle)
return 0;
@@ -215,8 +261,12 @@ vehicle_android_new_android(struct vehicle_methods *meth,
dbg(0, "enter\n");
ret = g_new0(struct vehicle_priv, 1);
ret->cbl = cbl;
- ret->cb=callback_new_1(callback_cast(vehicle_android_callback), ret);
+ ret->pcb = callback_new_1(callback_cast(vehicle_android_position_callback), ret);
+ ret->scb = callback_new_1(callback_cast(vehicle_android_status_callback), ret);
+ ret->fcb = callback_new_1(callback_cast(vehicle_android_fix_callback), ret);
ret->have_coords = 0;
+ ret->sats = 0;
+ ret->sats_used = 0;
*meth = vehicle_android_methods;
vehicle_android_init(ret);
dbg(0, "return\n");