package edu.berkeley.cs.amplab.carat.android.sampling;
import java.util.List;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.BatteryManager;
import android.os.Bundle;
import android.support.v4.content.WakefulBroadcastReceiver;
import edu.berkeley.cs.amplab.carat.android.Constants;
public class Sampler extends WakefulBroadcastReceiver implements
LocationListener {
public static final int MAX_SAMPLES = 250;
private static Sampler instance = null;
private Context context = null;
private Location lastKnownLocation = null;
private double distance = 0.0;
private long lastNotify;
public static Sampler getInstance() {
if (instance == null)
Sampler.instance = new Sampler();
return instance;
}
private void requestLocationUpdates() {
LocationManager lm = (LocationManager) context
.getSystemService(Context.LOCATION_SERVICE);
lm.removeUpdates(this);
List<String> providers = SamplingLibrary
.getEnabledLocationProviders(context);
if (providers != null) {
for (String provider : providers) {
lm.requestLocationUpdates(provider,
Constants.FRESHNESS_TIMEOUT, 0, this);
// Log.v(TAG, "Location updates requested for " + provider);
}
}
}
@Override
public void onReceive(Context context, Intent intent) {
/* Some phones receive the batteryChanged very very often. We are interested
* only in changes of the battery level */
int currentLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
/*
* IMPORTANT: Android doesn't necessarily broadcast battery level info
* EVERY TIME a battery_changed action action happens. Sometimes these
* info (EXTRA_LEVEL & EXTRA_SCALE) ARE broadcasted, sometimes NOT. So
* it's important to make sure and check whether these extras are
* broadcasted and thus our variables are non-zero. Also whenever
* Android broadcasts these extras, it doens't necessarily mean
* that a battery percentage/level change has happened. So we have to
* check that too, to avoid overwriting our variables unnecessarily
* (extra memory operation). Check SamplingLibrary.setCurrentBatteryLevel().
*/
/* On some phones, scale is always 0. */
if (scale == 0)
scale = 100;
if (currentLevel > 0) {
SamplingLibrary.setCurrentBatteryLevel(currentLevel, scale);
if (this.context == null) {
this.context = context;
requestLocationUpdates();
}
// Update last known location...
if (lastKnownLocation == null)
lastKnownLocation = SamplingLibrary.getLastKnownLocation(context);
Intent service = new Intent(context, SamplerService.class);
service.putExtra("OriginalAction", intent.getAction());
service.fillIn(intent, 0);
service.putExtra("distance", distance);
startWakefulService(context, service);
}
}
@Override
public void onLocationChanged(Location location) {
if (lastKnownLocation != null && location != null) {
distance = lastKnownLocation.distanceTo(location);
/*
* HashMap<String, Double> m = new HashMap<String, Double>();
* m.put("distanceTraveled", distance);
*/
// FlurryAgent.logEvent("LocationChanged", m);
/*
* CharSequence text = "Location change with distance = " +
* distance; Toast.makeText(context, text,
* Toast.LENGTH_LONG).show();
*/
}
lastKnownLocation = location;
}
@Override
public void onProviderDisabled(String provider) {
requestLocationUpdates();
}
@Override
public void onProviderEnabled(String provider) {
requestLocationUpdates();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
requestLocationUpdates();
}
public long getLastNotify() {
return lastNotify;
}
public void setLastNotify(long now) {
this.lastNotify = now;
}
}