content: 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;
      }
  }
  