From c02ba9534dc705b02ceb8d669b6329922882f998 Mon Sep 17 00:00:00 2001 From: mvglasow Date: Sat, 22 Nov 2014 15:55:28 +0000 Subject: Add:port/android:Make gps_status OSD work on Android Signed-off-by: mvglasow git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5957 ffa7fe5e-494d-0410-b361-a75ebd5db220 --- .../src/org/navitproject/navit/NavitVehicle.java | 70 ++++++++++++++++-- navit/vehicle/android/vehicle_android.c | 84 +++++++++++++++++----- 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 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, "", "(Landroid/content/Context;I)V"); + cid = (*jnienv)->GetMethodID(jnienv, ret->NavitVehicleClass, "", "(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"); -- cgit v1.2.1