/** * * Funf: Open Sensing Framework * Copyright (C) 2010-2011 Nadav Aharony, Wei Pan, Alex Pentland. * Acknowledgments: Alan Gardner * Contact: nadav@media.mit.edu * * This file is part of Funf. * * Funf is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * Funf is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with Funf. If not, see <http://www.gnu.org/licenses/>. * */ package edu.mit.media.funf.probe.builtin; import java.lang.reflect.Field; import android.content.Context; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import com.google.gson.Gson; import com.google.gson.JsonObject; import edu.mit.media.funf.Schedule; import edu.mit.media.funf.Schedule.DefaultSchedule; import edu.mit.media.funf.config.Configurable; import edu.mit.media.funf.probe.Probe.Base; import edu.mit.media.funf.probe.Probe.ContinuousProbe; import edu.mit.media.funf.probe.Probe.PassiveProbe; import edu.mit.media.funf.probe.Probe.RequiredFeatures; import edu.mit.media.funf.probe.Probe.RequiredPermissions; import edu.mit.media.funf.probe.builtin.ProbeKeys.LocationKeys; import edu.mit.media.funf.time.DecimalTimeUnit; /** * Sends all location points gathered by system. * @author alangardner * */ @RequiredPermissions({android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) @RequiredFeatures("android.hardware.location") @Schedule.DefaultSchedule(interval=1800) public class LocationProbe extends Base implements ContinuousProbe, PassiveProbe, LocationKeys { @Configurable private boolean useGps = true; @Configurable private boolean useNetwork = true; @Configurable private boolean useCache = true; private Gson gson; private LocationManager mLocationManager; private LocationListener listener = new ProbeLocationListener(); private LocationListener passiveListener = new ProbeLocationListener(); @Override protected void onEnable() { super.onEnable(); gson = getGson(); mLocationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE); String passiveProvider = getPassiveProvider(); if (passiveProvider != null) { mLocationManager.requestLocationUpdates(getPassiveProvider(), 0, 0, passiveListener); } } @Override protected void onStart() { super.onStart(); if (useGps) { mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener); } if (useNetwork) { mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, listener); } if (useCache) { listener.onLocationChanged(mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)); listener.onLocationChanged(mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)); } if (!useGps && ! useNetwork) { stop(); } } @Override protected void onStop() { super.onStop(); mLocationManager.removeUpdates(listener); } @Override protected void onDisable() { super.onDisable(); mLocationManager.removeUpdates(passiveListener); } private class ProbeLocationListener implements LocationListener{ @Override public void onLocationChanged(Location location) { if (location != null) { String provider = location.getProvider(); if (provider == null || (useGps && LocationManager.GPS_PROVIDER.equals(provider)) || (useNetwork && LocationManager.NETWORK_PROVIDER.equals(provider))) { JsonObject data = gson.toJsonTree(location).getAsJsonObject(); data.addProperty(TIMESTAMP, DecimalTimeUnit.MILLISECONDS.toSeconds(data.get("mTime").getAsBigDecimal())); sendData(gson.toJsonTree(location).getAsJsonObject()); } } } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } } /** * Supporting API level 7 which does not have PASSIVE provider * @return */ private String getPassiveProvider() { try { Field passiveProviderField = LocationManager.class.getDeclaredField("PASSIVE_PROVIDER"); return (String)passiveProviderField.get(null); } catch (SecurityException e) { } catch (NoSuchFieldException e) { } catch (IllegalArgumentException e) { } catch (IllegalAccessException e) { } return null; } }