package org.witness.informacam.informa.suckers; import java.util.Arrays; import java.util.List; import java.util.TimerTask; import org.witness.informacam.models.j3m.ILogPack; import org.witness.informacam.utils.Constants.Logger; import org.witness.informacam.utils.Constants.Suckers; import org.witness.informacam.utils.Constants.Suckers.Geo; import android.content.Context; import android.location.Criteria; import android.location.GpsStatus.NmeaListener; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.util.Log; public class GeoHiResSucker extends GeoSucker implements LocationListener { LocationManager lm; Criteria criteria; long lastNmeaTime = 0L; String lastNmeaMessage = null; private Location mLastLocation = null; private final static String LOG = Suckers.LOG; @SuppressWarnings("unchecked") public GeoHiResSucker(Context context) { super(context); setSucker(this); lm = (LocationManager) context.getApplicationContext().getSystemService(Context.LOCATION_SERVICE); if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, this); } else { Log.d(LOG, "NETWORK PROVIDER is unavailable"); } if (lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) { lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); } else { Log.d(LOG, "GPS PROVIDER is unavailable"); } lm.addNmeaListener(new NmeaListener() { /** * 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 NMEA 0183 for more details. You can implement this interface and call addNmeaListener(GpsStatus.NmeaListener) to receive NMEA data from the GPS engine. */ @Override public void onNmeaReceived(long timestamp, String nmea) { lastNmeaTime = timestamp; lastNmeaMessage = nmea; } }); criteria = new Criteria(); try { criteria.setAccuracy(Criteria.ACCURACY_HIGH); } catch (IllegalArgumentException iae){} try { criteria.setPowerRequirement(Criteria.POWER_HIGH); } catch (IllegalArgumentException iae){} setTask(new TimerTask() { @Override public void run() throws NullPointerException { if(getIsRunning()) { try { double[] loc = updateLocation(); if (loc != null) sendToBuffer(new ILogPack(Geo.Keys.GPS_COORDS, "[" + loc[0] + "," + loc[1] + "]")); } catch(NullPointerException e) { Log.e(LOG, "location NPE", e); } } } }); getTimer().schedule(getTask(), 0, Geo.LOG_RATE); } public ILogPack forceReturn() { double[] loc = updateLocation(); if(loc == null) { Log.d(LOG, "location was null"); loc = new double[] {0d, 0d}; } ILogPack iLogPack = new ILogPack(Geo.Keys.GPS_COORDS, "[" + loc[0] + "," + loc[1] + "]"); if (mLastLocation != null){ try { if (mLastLocation.hasAccuracy()) iLogPack.put(Geo.Keys.GPS_ACCURACY, mLastLocation.getAccuracy()+""); if (mLastLocation.hasAltitude()) iLogPack.put(Geo.Keys.GPS_ALTITUDE, mLastLocation.getAltitude()+""); if (mLastLocation.hasSpeed()) iLogPack.put(Geo.Keys.GPS_SPEED, mLastLocation.getSpeed()+""); if (mLastLocation.hasBearing()) iLogPack.put(Geo.Keys.GPS_BEARING, mLastLocation.getBearing()+""); if (lastNmeaTime != 0L) iLogPack.put(Geo.Keys.NMEA_TIME, lastNmeaTime); if (lastNmeaMessage != null) iLogPack.put(Geo.Keys.NMEA_MESSAGE, lastNmeaMessage); } catch (Exception e) { Log.d(LOG,"json exception in location data",e); } } return iLogPack; } public long getTime() { return lastNmeaTime; } public double[] updateLocation() { double[] location = new double[] {0.0, 0.0}; double[] isNull = new double[] {0.0, 0.0}; try { List<String> providers = lm.getProviders(criteria, true); for(String provider : providers) { Logger.d(LOG, String.format("querying location provider %s", provider)); Location l = lm.getLastKnownLocation(provider); if(l == null) { Logger.d(LOG, String.format("Location at provider %s is returning null...", provider)); continue; } mLastLocation = l; location = new double[] {l.getLatitude(), l.getLongitude()}; Logger.d(LOG, String.format("new location: %f, %f", location[0], location[1])); if(Arrays.equals(location, isNull)) { continue; } else { break; } } } catch(NullPointerException e) { Logger.e(LOG, e); } catch(IllegalArgumentException e) { Logger.e(LOG, e); } if(location == isNull) { return null; } return location; } public void stopUpdates() { setIsRunning(false); lm.removeUpdates(this); //Log.d(LOG, "shutting down GeoSucker..."); } @Override public void onLocationChanged(Location location) { mLastLocation = location; if(mLastLocation != null) { ILogPack iLogPack = forceReturn(); sendToBuffer(iLogPack); } } @Override public void onProviderDisabled(String provider) {} @Override public void onProviderEnabled(String provider) {} @Override public void onStatusChanged(String provider, int status, Bundle extras) {} }