Android Open Source - GreenerGasPedal Display Readings Activity






From Project

Back to project page GreenerGasPedal.

License

The source code is released under:

GNU General Public License

If you think the Android project GreenerGasPedal listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package name.nanek.greenerpedal.activity;
/*from www. ja  v a  2 s.c o  m*/
import name.nanek.greenerpedal.R;
import name.nanek.greenerpedal.activity.support.BitmapUtil;
import name.nanek.greenerpedal.activity.support.LogLine;
import name.nanek.greenerpedal.activity.support.LowPassFilter;
import name.nanek.greenerpedal.activity.support.Prefs;
import name.nanek.greenerpedal.activity.support.ScreenLock;
import name.nanek.greenerpedal.activity.support.Sensors;
import name.nanek.greenerpedal.activity.support.ShareUtil;
import name.nanek.greenerpedal.activity.support.Trigger;
import name.nanek.greenerpedal.activity.support.TriggersResult;
import name.nanek.greenerpedal.activity.support.Views;
import name.nanek.greenerpedal.db.model.Reading;
import name.nanek.greenerpedal.db.model.dao.DataHelper;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;

public class DisplayReadingsActivity extends Activity implements SensorEventListener {
  
  //TODO more accessibility
  
  //TODO voice overs so don't have to look so closely

  private static final int TIME_BETWEEN_DATABASE_INSERTS_MILLIS = 1000;

  private static final String LOG_TAG = "DisplayActivity";
  
  private Views views;
  
  private Sensors sensors;

  private Prefs prefs;
  
  private ScreenLock lock;
    
  private float currentScore;
  
  private Float lastOrientationSensorTilt;
  
  private long lastUptimeMillisWhenShowedNonIdleImage;

  private boolean calibrationRequested;
  
  private LowPassFilter filter;
  
  private LogLine logLine;
  
  private DataHelper data;
  
  private int driveNumber;
  
  private float lastScoreRate;
  
  private long lastUpdateDisplayTimeMillis;
  
  private String currentlyShownUrl;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    data = new DataHelper(this);        
    if ( null == savedInstanceState ) {
      driveNumber = data.readings.startNewDrive();
    } else {
      final Reading reading = data.readings.getLastReading();
      driveNumber = reading.getDriveNumber();
      currentScore = reading.getMoneySaved();
    }
    
    prefs = new Prefs(this);
    lock = new ScreenLock(this, "GreenerPedal " + getClass().getSimpleName());    
    views = new Views(this);
  }
  
  @Override
  protected void onStart() {
    super.onStart();
    
    //Keep screen on even if we're paused.
    lock.update(prefs);
  }

  @Override
  protected void onResume() {
    super.onResume();
    
    prefs = new Prefs(this);
    lock.update(prefs);
    views.mainRawValuesArea.setVisibility(prefs.showRawValues ? View.VISIBLE : View.GONE);
    views.mainScore.setVisibility(prefs.longTermRating ? View.VISIBLE : View.GONE);
    filter = new LowPassFilter(prefs);
    lastOrientationSensorTilt = null;    
    sensors = new Sensors(this, prefs);
  }
  
  @Override
  protected void onPause() {
    super.onPause();

    sensors.unregister(this);
  }

  @Override
  protected void onStop() {
    super.onStop();
    lock.release();
  }

  @Override
    public boolean onCreateOptionsMenu(Menu menu) {
      super.onCreateOptionsMenu(menu);
      
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.display_menu, menu);
        return true;
    } 
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {

      switch (item.getItemId()) {
          case R.id.menuItemSettings:
            final Intent prefsIntent = new Intent(this, EditPrefsActivity.class);
            startActivity(prefsIntent);
            return true;

          case R.id.menuItemGraphAndShare:
            final Intent graphIntent = new Intent(this, GraphAndShareActivity.class);
            startActivity(graphIntent);
            return true;

          case R.id.menuItemCalibrate:
            calibrationRequested = true;
            return true;
            
          case R.id.menuItemShare:
            ShareUtil.share(this, BitmapUtil.drawToBitmap(findViewById(R.id.content)), 0);
            return true;

          default:
              return super.onOptionsItemSelected(item);
      }
  }  
  
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
  
  //Long lastAccelOnSensorChanged;

    public void onSensorChanged(SensorEvent event) {
      
       if ( Sensor.TYPE_ORIENTATION == event.sensor.getType() ) {

          //Log.i(LOG_TAG, "azimuth, pitch, roll: " + event.values[0] + ", " + event.values[1] + ", " + event.values[2]);
          // 45, -90, 0 is straight up and down, portrait mode.
          // 45, -45, 0 is tilted back so screen half faces the sky

        Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
            int orientation = display.getOrientation();
            if ( Surface.ROTATION_90 == orientation ) {
              lastOrientationSensorTilt = (90 - event.values[2]);
           } else if ( Surface.ROTATION_270 == orientation ) {
               lastOrientationSensorTilt = (90 + event.values[2]);
           } else {
              lastOrientationSensorTilt = (90 + event.values[1]);              
            }

          
          //Log.i(LOG_TAG, "orientation sensor tiltDegrees: " + lastOrientationSensorTilt);
          
            return;
        }
        
        if ( Sensor.TYPE_ACCELEROMETER != event.sensor.getType() ) {
          return;
        }
        
        /*
        long now = SystemClock.uptimeMillis();
        if ( null != lastAccelOnSensorChanged ) {
          long timeElapsed = now - lastAccelOnSensorChanged;
          Log.i(LOG_TAG, "time elapsed: " + timeElapsed);
        }
        lastAccelOnSensorChanged = now;
        */

      float[] roatatedAccelValues = event.values.clone();;        
        views.updateRawXYZ(roatatedAccelValues);

        logLine = new LogLine();        
        logLine.updateRawXYZ(roatatedAccelValues);
        
        // Adjust for landscape orientations
      adjustForOrientation(roatatedAccelValues);
      
        if ( calibrationRequested ) {
          prefs.updateCalibration(getCalibration(roatatedAccelValues[2]));
          calibrationRequested = false;
        }
        
        // Correct for tilt.
        float tiltDegrees;
        if ( prefs.automaticTiltCorrection ) {
          if ( null == lastOrientationSensorTilt ) {
            return;
          }
          // TODO maybe allow calibration while using auto too? would be added/subtracted to sensor value
          tiltDegrees = lastOrientationSensorTilt;
        } else {
          tiltDegrees = prefs.manualTiltCorrection;          
        }
                
        //Adjust for tilt
        //Log.i(LOG_TAG, "tiltDegrees: " + tiltDegrees);
        
        tiltDegrees = tiltDegrees < 0 ? 0 : tiltDegrees > 89 ? 89 : tiltDegrees;          
        float measuredForce = roatatedAccelValues[2];
      float gravityOnMeasuredAxis = getGravityOnMeasuredAxis(tiltDegrees);
        float tiltRadians = toRadians(tiltDegrees);
      float measuredAccelerationForceToRealForce = (float) Math.cos(tiltRadians);                
      float measuredAcceleration = measuredForce - gravityOnMeasuredAxis;
      float actualAcceleration = measuredAcceleration / measuredAccelerationForceToRealForce;

      roatatedAccelValues[2] = actualAcceleration;

          
        // Convert X, Y, Z to acceleration, breaking, and cornering
      float acceleration = -roatatedAccelValues[2];
      float breaking = roatatedAccelValues[2];
      float cornering = Math.abs(roatatedAccelValues[0]);
      // roatatedValues[1] is gravity when the phone isn't tilted, so isn't used.
      
      if ( prefs.swapAccelBreak ) {
        acceleration = -acceleration;
        breaking = - breaking;
      }

      acceleration = Math.max(acceleration, 0);
       breaking = Math.max(breaking, 0);
      
      filter.updateRawMeasurements(acceleration, breaking, cornering);
      views.updateRawMeasurements(acceleration, breaking, cornering, tiltDegrees);
        logLine.updateRawMeasurements(acceleration, breaking, cornering, tiltDegrees);
            
        
              
    long currentUpTimeMillis = SystemClock.uptimeMillis();
    long timeSinceLastShowedNonIdleMillis = currentUpTimeMillis - lastUptimeMillisWhenShowedNonIdleImage;
    
    // Ignore if we just showed something, give the user time to see it.    
    if ( timeSinceLastShowedNonIdleMillis < prefs.updateRateMillis ) {
      logLine.log();
      logLine = null;
      return;
    }
          
      int priority = Integer.MAX_VALUE;
      TriggersResult result = new TriggersResult(prefs.idleImageUrl, priority, 1.5f, "Good");
    for ( Trigger trigger : prefs.triggers ) {
      if ( trigger.updateResult(result, filter.getAcceleration(), filter.getBreaking(), filter.getCornering()) ) {
        lastUptimeMillisWhenShowedNonIdleImage = SystemClock.uptimeMillis();
      }
    }      

    long timeSinceLastUpdateDisplayFullyRanMillis = currentUpTimeMillis - lastUpdateDisplayTimeMillis;
    currentScore += timeSinceLastUpdateDisplayFullyRanMillis * lastScoreRate / ( 1000 * 60 * 60 );        
    lastScoreRate = result.scoreChange;
      views.showScore(currentScore);

    if ( null == currentlyShownUrl || !currentlyShownUrl.equals(result.url) ) {
      showImage(result.url);
        currentlyShownUrl = result.url;
        views.webView.setContentDescription(result.contentDescription);
    }
    
      logLine.updateCalculatedMeasurements(filter.getAcceleration(), filter.getBreaking(), filter.getCornering());
      logLine.updateScreen(result.url);
    logLine.log();
    logLine = null;    
    
    if ( timeSinceLastUpdateDisplayFullyRanMillis > TIME_BETWEEN_DATABASE_INSERTS_MILLIS ) {
      float breakUse = Math.max(cornering, breaking);        
           final Reading reading = new Reading(null, acceleration, breakUse, currentScore, driveNumber, currentUpTimeMillis);
           data.readings.insert(reading);
    }
         
    lastUpdateDisplayTimeMillis = currentUpTimeMillis;
    }
    
  private void adjustForOrientation(float[] roatatedAccelValues) {
    Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        int orientation = display.getOrientation();
        if ( Surface.ROTATION_90 == orientation ) {
          float swapTemp = roatatedAccelValues[0];
          roatatedAccelValues[0] = roatatedAccelValues[1];// Correct
          roatatedAccelValues[1] = swapTemp;
          roatatedAccelValues[2] = roatatedAccelValues[2];          
        } else if ( Surface.ROTATION_270 == orientation ) {
          float swapTemp = roatatedAccelValues[0];
          //Two stays 2.
          roatatedAccelValues[0] = roatatedAccelValues[1];
          roatatedAccelValues[1] = swapTemp;
        }
  }
    
    private float getGravityOnMeasuredAxis(float tiltDegrees) {
        float tiltRadians = toRadians(tiltDegrees);
        float measuredGravityForceToRealForce = (float) Math.sin(tiltRadians);          
      float gravityOnMeasuredAxis = SensorManager.GRAVITY_EARTH * measuredGravityForceToRealForce;
      return gravityOnMeasuredAxis;
    }

  private float toRadians(float tiltDegrees) {
    return (float) (tiltDegrees * Math.PI / 180.0f);
  }

  private Float getCalibration(float measured) {
    Float closestMatch = null;
    Float absoluteDifference = null;
    for( int tiltDegrees = 0; tiltDegrees < 90; tiltDegrees++) {

        float gravityOnMeasuredAxis = getGravityOnMeasuredAxis(tiltDegrees);
        
        float newDifference = Math.abs(gravityOnMeasuredAxis - measured);
        if ( null == closestMatch || newDifference < absoluteDifference ) {
          closestMatch = (float) tiltDegrees;
          absoluteDifference = newDifference;
        }
    }
    return closestMatch;
  }
  
  private void showImage(String imageUrl) {
    String summary = "<html><link href=\"style.css\" rel=\"stylesheet\" type=\"text/css\" /><body><img src=\"" + imageUrl + "\"  /></body></html>";
    //Log.i("DisplayActivity", summary);
    views.webView.loadDataWithBaseURL("file:///android_asset/", summary, "text/html", "utf-8", null);    
  }
    
}




Java Source Code List

name.nanek.greenerpedal.GreenerPedalApp.java
name.nanek.greenerpedal.activity.DisplayReadingsActivity.java
name.nanek.greenerpedal.activity.EditPrefsActivity.java
name.nanek.greenerpedal.activity.GraphAndShareActivity.java
name.nanek.greenerpedal.activity.support.APISafeKeyguardHider.java
name.nanek.greenerpedal.activity.support.BitmapUtil.java
name.nanek.greenerpedal.activity.support.LogLine.java
name.nanek.greenerpedal.activity.support.LowPassFilter.java
name.nanek.greenerpedal.activity.support.MessageOnlyFormatter.java
name.nanek.greenerpedal.activity.support.Prefs.java
name.nanek.greenerpedal.activity.support.ScreenLock.java
name.nanek.greenerpedal.activity.support.Sensors.java
name.nanek.greenerpedal.activity.support.ShareUtil.java
name.nanek.greenerpedal.activity.support.Trigger.java
name.nanek.greenerpedal.activity.support.TriggersResult.java
name.nanek.greenerpedal.activity.support.Views.java
name.nanek.greenerpedal.db.model.Reading.java
name.nanek.greenerpedal.db.model.dao.DataHelper.java
name.nanek.greenerpedal.db.model.dao.ReadingDao.java
name.nanek.greenerpedal.db.model.dao.support.DateUtil.java
name.nanek.greenerpedal.db.model.dao.support.DbUtil.java