diff options
| -rw-r--r-- | app/src/main/java/com/softwarefools/nik/spiritlevel/LevelActivity.java | 299 | ||||
| -rw-r--r-- | app/src/main/java/com/softwarefools/nik/spiritlevel/LevelView.java | 496 | ||||
| -rw-r--r-- | app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorListener.java | 25 | ||||
| -rw-r--r-- | app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorManager.java | 490 | ||||
| -rw-r--r-- | app/src/main/res/menu/level.xml | 22 | ||||
| -rw-r--r-- | app/src/main/res/values-de/strings.xml | 18 | ||||
| -rw-r--r-- | app/src/main/res/values-en/strings.xml | 18 | ||||
| -rw-r--r-- | app/src/main/res/values/strings.xml | 12 |
8 files changed, 1380 insertions, 0 deletions
diff --git a/app/src/main/java/com/softwarefools/nik/spiritlevel/LevelActivity.java b/app/src/main/java/com/softwarefools/nik/spiritlevel/LevelActivity.java new file mode 100644 index 0000000..6086f31 --- /dev/null +++ b/app/src/main/java/com/softwarefools/nik/spiritlevel/LevelActivity.java @@ -0,0 +1,299 @@ +package com.softwarefools.nik.spiritlevel; + +import java.text.DecimalFormat; +import java.util.Locale; + + +import java.util.Locale; +import android.os.Bundle; +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.util.DisplayMetrics; +// +// +//import com.softwarefools.nik.spiritlevel.R; +//import com.softwarefools.nik.spiritlevel.R.layout; +//import com.softwarefools.nik.spiritlevel.R.menu; +import com.example.spiritlevel.R; +import com.softwarefools.nik.spiritlevel.MySensorListener; +import com.softwarefools.nik.spiritlevel.MySensorManager; + +import android.hardware.Sensor; +import android.hardware.SensorManager; +import android.os.Build; +import android.os.Bundle; +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.pm.ActivityInfo; +import android.speech.tts.TextToSpeech; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.Surface; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +public class LevelActivity extends Activity implements MySensorListener{ + + public static DecimalFormat f = new DecimalFormat("#0.000"); + private SensorManager mSensorManager; + private Sensor mySensor; + private Sensor aSensor,gSensor; + private LevelView levelView; + + private TextView accelField; + private TextView gravityField; + + private Locale myLocale; + + + TextToSpeech t1; + + + private int orientation; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + levelView = new LevelView(this); + setContentView(levelView); + + + t1=new TextToSpeech(getApplicationContext(), new TextToSpeech.OnInitListener() { + @Override + public void onInit(int status) { + if(status != TextToSpeech.ERROR) { + + t1.setLanguage(getResources().getConfiguration().locale); + } + } }); + + // + // + //t1.speak(Locale.getDefault().getLanguage(), TextToSpeech.QUEUE_FLUSH, null); + //Toast.makeText(getBaseContext(), "|"+Locale.getDefault().getLanguage()+"|",Toast.LENGTH_SHORT).show(); + //langname="de"; + + setupActionBar(); + + //setContentView(R.layout.activity_level); + + // !TfT -- Show the Up button in the action bar. + + + //accelField = (TextView) findViewById(R.id.TextView_accelerometer); + //gravityField = (TextView) findViewById(R.id.TextView_gravity); + + //! + } + @Override + public void onResume() { + super.onResume(); + Toast.makeText(getBaseContext(), "onResume Sensors Started", + Toast.LENGTH_SHORT).show(); + + orientation=getScreenOrientation(); + // orientation= getResources().getConfiguration().orientation; + //Check device supported Accelerometer senssor or not + if (MySensorManager.isSupported(this)) { + + //Start Accelerometer Listening + MySensorManager.startListening(this); + } + } + + @Override + public void onStop() { + super.onStop(); + + //Check device supported Accelerometer senssor or not + if (MySensorManager.isListening()) { + + //Start Accelerometer Listening + MySensorManager.stopListening(); + + Toast.makeText(getBaseContext(), "onStop Sensors Stoped", + Toast.LENGTH_SHORT).show(); + } + + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.i("Sensor", "Service distroy"); + + //Check device supported Accelerometer senssor or not + if (MySensorManager.isListening()) { + + //Start Accelerometer Listening + MySensorManager.stopListening(); + + Toast.makeText(getBaseContext(), "onDestroy Sensors Stoped", + Toast.LENGTH_SHORT).show(); + } + + } + + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.level, menu); + return true; + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle item selection + switch (item.getItemId()) { + case R.id.action_settings: + t1.speak(this.getString(R.string.action_settings), TextToSpeech.QUEUE_FLUSH, null); + + return true; + case R.id.action_exit: + t1.speak(this.getString(R.string.goodby), TextToSpeech.QUEUE_FLUSH, null); + + System.exit(0); + return true; + + case R.id.action_changelang: + String comp=getResources().getConfiguration().locale.getLanguage(); + if (comp.contains("en")) { + + t1.speak(this.getString(R.string.change_text)+this.getString(R.string.change_german), TextToSpeech.QUEUE_FLUSH, null); + //t1.setLanguage(getResources().getConfiguration().locale); + setLocale("de"); + + }else if (comp.contains("de")) { + t1.speak(this.getString(R.string.change_text)+this.getString(R.string.change_english), TextToSpeech.QUEUE_FLUSH, null); + //t1.setLanguage(Locale.ENGLISH); + setLocale("en"); + }else t1.speak(this.getString(R.string.fuckoff), TextToSpeech.QUEUE_FLUSH, null); + + + + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + @Override + public void onGravityChanged(float x, float y, float z) { + // TODO Auto-generated method stub + float sq= (float)x*x+y*y+z*z; + float sum=(float)Math.sqrt(sq); + levelView.updateData(x/sum, y/sum, z/sum,orientation); + } + + @Override + public void onAccelerationChanged(float x, float y, float z) { + // TODO Auto-generated method stub + float sq= (float)x*x+y*y+z*z; + float sum=(float)Math.sqrt(sq); + levelView.updateAccelData(x/sum, y/sum, z/sum,orientation); + + } + + @Override + public void onShake(float force) { + // TODO Auto-generated method stub + String maketext= this.getString(R.string.alert)+(int)force+this.getString(R.string.newton); + //Toast.makeText(getApplicationContext(), toSpeak,Toast.LENGTH_SHORT).show(); + t1.speak(maketext, TextToSpeech.QUEUE_FLUSH, null); + Toast.makeText(getBaseContext(), this.getString(R.string.toast_force)+force+this.getString(R.string.newton_short),Toast.LENGTH_SHORT).show(); + } + + /** + * Set up the {@link android.app.ActionBar}, if the API is available. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private void setupActionBar() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + getActionBar().setDisplayHomeAsUpEnabled(true); + } + } + private int getScreenOrientation() { + int rotation = getWindowManager().getDefaultDisplay().getRotation(); + DisplayMetrics dm = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(dm); + int width = dm.widthPixels; + int height = dm.heightPixels; + int orientation; + // if the device's natural orientation is portrait: + if ((rotation == Surface.ROTATION_0 + || rotation == Surface.ROTATION_180) && height > width || + (rotation == Surface.ROTATION_90 + || rotation == Surface.ROTATION_270) && width > height) { + switch(rotation) { + case Surface.ROTATION_0: + orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + break; + case Surface.ROTATION_90: + orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + break; + case Surface.ROTATION_180: + orientation = + ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + break; + case Surface.ROTATION_270: + orientation = + ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + break; + default: + Toast.makeText(getBaseContext(), "Unknown screen orientation. Defaulting to " + "landscape.",Toast.LENGTH_SHORT).show(); + + orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + break; + } + } + // if the device's natural orientation is landscape or if the device + // is square: + else { + switch(rotation) { + case Surface.ROTATION_0: + orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + break; + case Surface.ROTATION_90: + orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; + break; + case Surface.ROTATION_180: + orientation = + ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; + break; + case Surface.ROTATION_270: + orientation = + ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; + break; + default: + Toast.makeText(getBaseContext(), "Unknown screen orientation. Defaulting to " + "landscape.",Toast.LENGTH_SHORT).show(); + + orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; + break; + } + } + + return orientation; + } + public void setLocale(String lang) { + myLocale = new Locale(lang); + //langname=lang; + Resources res = getResources(); + DisplayMetrics dm = res.getDisplayMetrics(); + Configuration conf = res.getConfiguration(); + conf.locale = myLocale; + res.updateConfiguration(conf, dm); + Intent refresh = new Intent(this, LevelActivity.class); + startActivity(refresh); + setupActionBar(); + finish(); + t1.setLanguage(getResources().getConfiguration().locale); + } +} diff --git a/app/src/main/java/com/softwarefools/nik/spiritlevel/LevelView.java b/app/src/main/java/com/softwarefools/nik/spiritlevel/LevelView.java new file mode 100644 index 0000000..0ee160e --- /dev/null +++ b/app/src/main/java/com/softwarefools/nik/spiritlevel/LevelView.java @@ -0,0 +1,496 @@ +package com.softwarefools.nik.spiritlevel; + +import java.text.DecimalFormat; + +import com.softwarefools.nik.spiritlevel.*; + +import java.util.Locale; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.RectF; +import android.hardware.Sensor; +import android.hardware.SensorManager; +import android.util.DisplayMetrics; +import android.view.Display; +import android.view.Menu; +import android.view.View; +import android.view.WindowManager; +import android.widget.Toast; + +public class LevelView extends View{ + + public static DecimalFormat f = new DecimalFormat("#0.000"); + + /*DisplayMetrics dm = new DisplayMetrics(); + //getWindowManager().getDefaultDisplay().getMetrics(dm); + int width = dm.widthPixels; + int height = dm.heightPixels;*/ + + + public double precition=0.002; //(%) + + public float x_gravSense=0; + public float y_gravSense=0; + public float z_gravSense=0; + + public float x_accSense=0; + public float y_accSense=0; + public float z_accSense=0; + + public float x_gravSense_min=10; + public float y_gravSense_min=10; + public float z_gravSense_min=10; + + public float x_accSense_max=0; + public float y_accSense_max=0; + public float z_accSense_max=0; + + private float xCenter = 0; // This displays center + private float yCenter = 0; + + + private float xAxisTag_x=0; + private float xAxisTag_y=0; + private float yAxisTag_x=0; + private float yAxisTag_y=0; + private float xAxisTagNeg_x=0; + private float xAxisTagNeg_y=0; + private float yAxisTagNeg_x=0; + private float yAxisTagNeg_y=0; + + private float x_horizon=0; + private float y_horizon=0; + private float x_horizon2=0; + private float y_horizon2=0; + + private float x_gravEnd=0; + private float y_gravEnd=0; + + private float x_accEnd=0; + private float y_accEnd=0; + + private float ballRadius = 320; // Circles and Axis props + private float ballWidth = 10; + private float lineWidth=5; + private float lineTextSize=50; + + private float maxdiameter=0; + + private float levelballRadius=50; + private float vectWidth =14; + private float vectTextSize=40; + private float vectTextDist=5; + + private float margin=20; + + private double alpha =0; // angle G from X + + private int orientation; + + int mActionBarSize=0; + int statusbarSize=0; + + private String langname=""; + + //private float ballX = ballRadius + 20; // Ball's center (x,y) + //private float ballY = ballRadius + 40; + + private RectF ballBounds; // Needed for Canvas.drawOval + private RectF helpBallBounds; + private RectF helpBallBounds2; + private RectF helpBallBounds3; + + private RectF levelballBounds; + private Paint paintCircle; + private Paint paintHelpCircle;// The paint (e.g. style, color) used for drawing + private Paint paintHelpCircle2; + + private Paint paintVector; + private Paint paintVectorHelp; + private Paint paintVector2; + private Paint paintVector2Help; + private Paint paintVector3Help; + + private Paint paintAxisLines; + private Paint paintAxisHelpLines; + + private Paint paintTexts; + + DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); + final int displaywidth = metrics.widthPixels; + final int displayheight = metrics.heightPixels; + + + + + //private Canvas myCanvas; + + + + // Constructor + public LevelView(Context context) { + + //registerForContextMenu(); + super(context); + init(); + + + } + private void init() { + + + ballBounds = new RectF(); + helpBallBounds = new RectF(); + helpBallBounds2 = new RectF(); + helpBallBounds3 = new RectF(); + + levelballBounds = new RectF(); + + paintCircle = new Paint(); + paintHelpCircle = new Paint(); + paintHelpCircle2 = new Paint(); + + paintVector = new Paint(); + paintVectorHelp = new Paint(); + + paintVector2 = new Paint(); + paintVector2Help = new Paint(); + paintVector3Help = new Paint(); + + paintAxisLines = new Paint(); + paintAxisHelpLines = new Paint(); + + paintTexts = new Paint(); + + + // ADJUST TO SCREEN + + ballRadius = displaywidth/4; + ballWidth =(int)displayheight/108; + lineWidth=displaywidth/200; + vectTextSize=(int)displayheight/27; + vectTextDist=(int)vectTextSize/4; + + levelballRadius=(int)displayheight/20; + + + // Circles and Axis props + x_gravEnd=xCenter; + y_gravEnd=yCenter+ballRadius; + x_accEnd=xCenter; + y_accEnd=yCenter; + + final TypedArray styledAttributes = getContext().getTheme().obtainStyledAttributes( new int[] { android.R.attr.actionBarSize }); + mActionBarSize = (int) styledAttributes.getDimension(0, 0); + styledAttributes.recycle(); + statusbarSize =getStatusBarHeight(); + + xCenter=displaywidth/2; + yCenter=displayheight/2 -mActionBarSize-statusbarSize; + double t=displaywidth*displaywidth+displayheight*displayheight; + maxdiameter=(float) Math.sqrt(t); + + ballBounds.set(xCenter-ballRadius, yCenter-ballRadius, xCenter+ballRadius, yCenter+ballRadius); + helpBallBounds.set(xCenter-ballRadius/2, yCenter-ballRadius/2, xCenter+ballRadius/2, yCenter+ballRadius/2); + helpBallBounds2.set(xCenter-(3*ballRadius/4), yCenter-(3*ballRadius/4), xCenter+(3*ballRadius/4), yCenter+(3*ballRadius/4)); + helpBallBounds3.set(xCenter-(ballRadius/4), yCenter-(ballRadius/4), xCenter+(ballRadius/4), yCenter+(ballRadius/4)); + + + + /** + * Initial Colorsettings + * Derzeit + * Auslagerung in settings; + */ + paintCircle.setColor(Color.BLACK); + paintCircle.setStyle(Paint.Style.STROKE); + paintCircle.setStrokeWidth(ballWidth); + paintCircle.setAntiAlias(true); + paintHelpCircle.setColor(Color.DKGRAY); + paintHelpCircle.setStyle(Paint.Style.STROKE); + paintHelpCircle.setStrokeWidth(ballWidth/2); + paintHelpCircle.setAntiAlias(true); + paintHelpCircle2.setColor(Color.GRAY); + paintHelpCircle2.setStyle(Paint.Style.STROKE); + paintHelpCircle2.setStrokeWidth(ballWidth/3); + paintHelpCircle2.setAntiAlias(true); + + paintVector.setColor(Color.RED); + paintVector.setAntiAlias(true); + paintVector.setStrokeWidth(vectWidth); + paintVector.setTextSize(vectTextSize); + paintVectorHelp.setStrokeWidth(vectWidth/2); + paintVectorHelp.setColor(Color.RED); + paintVectorHelp.setAntiAlias(true); + + + paintVector2.setColor(Color.RED); + paintVector2.setAntiAlias(true); + paintVector2.setStrokeWidth(vectWidth); + paintVector2.setTextSize(vectTextSize); + paintVector2Help.setStrokeWidth(vectWidth/3); + paintVector2Help.setColor(Color.RED); + paintVector2Help.setAntiAlias(true); + paintVector3Help.setTextSize(vectTextSize); + paintVector3Help.setColor(Color.RED); + paintVector3Help.setAntiAlias(true); + + + paintAxisLines.setColor(Color.BLACK); + paintAxisLines.setStrokeWidth(lineWidth); + paintAxisLines.setTextSize(lineTextSize); + paintAxisHelpLines.setColor(Color.DKGRAY); + paintAxisHelpLines.setStrokeWidth(lineWidth/2); + paintAxisHelpLines.setTextSize(lineTextSize/3); + + paintTexts.setColor(Color.BLACK); + paintTexts.setTextSize(vectTextSize); + paintAxisHelpLines.setTextSize(lineTextSize/2); + + } + + @Override + protected void onDraw(Canvas canvas) { + // Calculate Gravity Vector AxisTitles onlyforLandscape + x_gravEnd=xCenter+y_gravSense*ballRadius; + y_gravEnd=yCenter+x_gravSense*ballRadius; + x_accEnd=xCenter+(y_accSense-y_gravSense)*ballRadius; + y_accEnd=yCenter+(x_accSense-x_gravSense)*ballRadius; + x_horizon=xCenter-x_gravSense*maxdiameter; + y_horizon=yCenter+y_gravSense*maxdiameter; + x_horizon2=xCenter+x_gravSense*maxdiameter; + y_horizon2=yCenter-y_gravSense*maxdiameter; + yAxisTag_x=xCenter+ballRadius-lineTextSize+5; + yAxisTag_y=yCenter-5; + xAxisTag_x=xCenter+2; + xAxisTag_y=yCenter+ballRadius-8; + yAxisTagNeg_x=xCenter-ballRadius+7; + yAxisTagNeg_y=yCenter+1+lineTextSize; + xAxisTagNeg_x=xCenter-lineTextSize+4; + xAxisTagNeg_y=yCenter-ballRadius+lineTextSize+2; + + + alpha = getAngle(x_gravSense,y_gravSense); + //alpha = Math.atan((y_gravSense/x_gravSense)); + + + // Orientation stuff activate and edit when needed (Fawlty) + + /*if(orientation==1){ //Vertical -- portrait + x_gravEnd=xCenter-x_gravSense*ballRadius; + y_gravEnd=yCenter+y_gravSense*ballRadius; + xAxisTag_x=xCenter+ballRadius-lineTextSize; + xAxisTag_y=yCenter-10; + yAxisTag_x=xCenter-lineTextSize+4; + yAxisTag_y=yCenter-ballRadius+lineTextSize+2; + }else if(orientation==0){ //Horizontal left + + x_gravEnd=xCenter+y_gravSense*ballRadius; + y_gravEnd=yCenter+x_gravSense*ballRadius; + yAxisTag_x=xCenter-ballRadius+5; + yAxisTag_y=yCenter+1+lineTextSize; + xAxisTag_x=xCenter-lineTextSize+4; + xAxisTag_y=yCenter-ballRadius+lineTextSize+2; + + }else if(orientation==8){ + x_gravEnd=xCenter-y_gravSense*ballRadius; + y_gravEnd=yCenter-x_gravSense*ballRadius; + yAxisTag_x=xCenter+ballRadius-lineTextSize; + yAxisTag_y=yCenter+1+lineTextSize; + xAxisTag_x=xCenter-lineTextSize+4; + xAxisTag_y=yCenter+ballRadius-4; + }*/ + + //Circle and HelpCircle + canvas.drawOval(ballBounds, paintCircle); + canvas.drawOval(helpBallBounds, paintHelpCircle); + canvas.drawOval(helpBallBounds2, paintHelpCircle2); + canvas.drawOval(helpBallBounds3, paintHelpCircle2); + + //Draw Axis and TitlesxC + canvas.drawLine(xCenter-maxdiameter,yCenter-maxdiameter,xCenter+maxdiameter,yCenter+maxdiameter,paintAxisHelpLines); + canvas.drawLine(xCenter+maxdiameter,yCenter-maxdiameter,xCenter-maxdiameter,yCenter+maxdiameter,paintAxisHelpLines); + + canvas.drawLine(0,yCenter,displaywidth,yCenter,paintAxisLines); + canvas.drawLine(xCenter,0,xCenter,displayheight,paintAxisLines); + canvas.drawText("X",xAxisTag_x,xAxisTag_y,paintAxisLines); + canvas.drawText("Y",yAxisTag_x,yAxisTag_y,paintAxisLines); + canvas.drawText("-X",xAxisTagNeg_x,xAxisTagNeg_y,paintAxisLines); + canvas.drawText("-Y",yAxisTagNeg_x,yAxisTagNeg_y,paintAxisLines); + + //Draw Vector/Ball and Text + + setVectorColor(); + if(inHorizontalMode()){ + canvas.drawLine(xCenter, yCenter, x_gravEnd ,y_gravEnd , paintVector); + levelballRadius=(int) (displayheight/20*(1-Math.sqrt(x_gravSense*x_gravSense+y_gravSense*y_gravSense))); + levelballBounds.set(x_gravEnd-levelballRadius,y_gravEnd-levelballRadius,x_gravEnd+levelballRadius,y_gravEnd+levelballRadius); + canvas.drawOval(levelballBounds, paintVector); + canvas.drawLine(x_gravEnd-levelballRadius,y_gravEnd,x_gravEnd+levelballRadius,y_gravEnd,paintAxisHelpLines); + canvas.drawLine(x_gravEnd,y_gravEnd-levelballRadius,x_gravEnd,y_gravEnd+levelballRadius,paintAxisHelpLines); + canvas.drawLine(xCenter, yCenter, x_accEnd ,y_accEnd , paintVector2); + + }else{ + //levelballRadius=0; + levelballRadius=(int) (displayheight/20*(1-Math.sqrt(x_gravSense*x_gravSense+y_gravSense*y_gravSense))); + levelballBounds.set(x_gravEnd-levelballRadius,y_gravEnd-levelballRadius,x_gravEnd+levelballRadius,y_gravEnd+levelballRadius); + canvas.drawLine(xCenter, yCenter, x_gravEnd ,y_gravEnd , paintVector); + canvas.drawLine(xCenter, yCenter, x_accEnd ,y_accEnd , paintVector2); + canvas.drawLine(xCenter, yCenter, x_horizon, y_horizon, paintVectorHelp); + canvas.drawLine(xCenter, yCenter, x_horizon2, y_horizon2, paintVectorHelp); + + } + canvas.save(); + //canvas.rotate((float) (180*getAngle(y_gravSense, x_gravSense)/Math.PI)); + float sum_g=(float)Math.sqrt(x_gravSense*x_gravSense+y_gravSense*y_gravSense+z_gravSense*z_gravSense); + float sum_gmin=(float)getLength(x_gravSense_min,y_gravSense_min,z_gravSense_min); + float sum_amax=(float)getLength(x_accSense_max,y_accSense_max,z_accSense_max); + float sum_na =(float) getLength(x_accSense-x_gravSense,y_accSense-y_gravSense,z_accSense-z_gravSense); + + canvas.drawText("G [m\u00B2/s]", x_gravEnd+levelballRadius+margin, y_gravEnd+margin, paintVector); + canvas.drawText("\u01A9 "+niceValue(sum_g), x_gravEnd+levelballRadius+margin, y_gravEnd+margin+vectTextSize+vectTextDist, paintVector); + canvas.drawText("x "+niceValue(x_gravSense), x_gravEnd+levelballRadius+margin, y_gravEnd+margin+2*vectTextSize+vectTextDist, paintVector); + canvas.drawText("y "+niceValue(y_gravSense), x_gravEnd+levelballRadius+margin, y_gravEnd+margin+3*vectTextSize+vectTextDist, paintVector); + canvas.drawText("z "+niceValue(z_gravSense), x_gravEnd+levelballRadius+margin, y_gravEnd+margin+4*vectTextSize+vectTextDist, paintVector); + canvas.restore(); + + // Acceleration Sumup + + canvas.drawText("A [m\u00B2/s]", displaywidth-displaywidth/10, margin+vectTextSize, paintVector2); + canvas.drawText("\u01A9 "+niceValue(sum_na), displaywidth-displaywidth/10, margin+2*vectTextSize+vectTextDist, paintVector2); + canvas.drawLine(displaywidth-displaywidth/10,margin+2*vectTextSize+2*vectTextDist,displaywidth-2*margin,margin+2*vectTextSize+2*vectTextDist,paintVector2Help); + canvas.drawText("x "+niceValue(x_accSense-x_gravSense), displaywidth-displaywidth/10, margin+3*vectTextSize+2*vectTextDist, paintVector2); + canvas.drawText("y "+niceValue(y_accSense-y_gravSense), displaywidth-displaywidth/10, margin+4*vectTextSize+2*vectTextDist, paintVector2); + canvas.drawText("z "+niceValue(z_accSense-z_gravSense), displaywidth-displaywidth/10, margin+5*vectTextSize+2*vectTextDist, paintVector2); + + canvas.drawText("G min [m\u00B2/s]", displaywidth-displaywidth/8, displayheight-margin-4*vectTextSize-2*vectTextDist-mActionBarSize-statusbarSize, paintVector3Help); + canvas.drawText("\u01A9 "+niceValue(sum_gmin), displaywidth-displaywidth/9, displayheight-margin-3*vectTextSize-2*vectTextDist-mActionBarSize-statusbarSize, paintVector3Help); + + + canvas.drawText("A max [m\u00B2/s]", displaywidth-displaywidth/8, displayheight-margin-2*vectTextSize-vectTextDist-mActionBarSize-statusbarSize, paintVector3Help); + canvas.drawText("\u01A9 "+niceValue(sum_amax), displaywidth-displaywidth/9, displayheight-margin-1*vectTextSize-mActionBarSize-statusbarSize, paintVector3Help); + + //Draw Debug + + String current = getResources().getConfiguration().locale.getLanguage(); + String screeninfo = "Width: "+ displaywidth+ "Height: "+ displayheight + " Orientation :" + String.valueOf(orientation); + canvas.drawText(screeninfo, margin, margin+vectTextSize, paintTexts); + canvas.drawText(String.valueOf(inHorizontalMode()), margin, margin+2*vectTextSize+vectTextDist, paintTexts); + canvas.drawText(String.valueOf(alpha), margin, margin+3*vectTextSize+vectTextDist, paintTexts); + canvas.drawText(makeDegAngle(alpha), margin, margin+4*vectTextSize+vectTextDist, paintTexts); + canvas.drawText(niceValue(sum_na), margin, margin+5*vectTextSize+vectTextDist, paintTexts); + canvas.drawText(current, margin, margin+6*vectTextSize+vectTextDist, paintTexts); + } + public String niceValue(float x){ + double g= 9.80665; + return f.format(x*g); + } + public String makeDegAngle(double grad){ + double alphadeg = 180*grad/Math.PI; + return f.format(alphadeg)+"\u00B0"; + } + public double getAngle(float x, float y){ + double res = Math.atan((x/y)); + if(y<0 && x>0)res=Math.PI+res; + else if(y<0 && x<0)res=res-Math.PI; + + return res; + } + public double getLength(float x, float y, float z){ + double res = Math.sqrt(x*x+y*y+z*z); + return res; + } + public int getStatusBarHeight() { + int result = 0; + int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (resourceId > 0) { + result = getResources().getDimensionPixelSize(resourceId); + } + return result; + } + + public void updateData(float x,float y,float z,int orientation) { + if (getLength(x_gravSense_min,y_gravSense_min,z_gravSense_min)>getLength(x,y,z)){ + this.x_gravSense_min=x; + this.y_gravSense_min=y; + this.z_gravSense_min=z; + } + this.x_gravSense = x; + this.y_gravSense = y; + this.z_gravSense = z; + this.orientation = orientation; + invalidate(); + } + public void updateAccelData(float x,float y,float z,int orientation) { + if (getLength(x_accSense_max,y_accSense_max,z_accSense_max)<getLength(x-x_gravSense,y-y_gravSense,z-z_gravSense)){ + this.x_accSense_max=x-x_gravSense; + this.y_accSense_max=y-y_gravSense; + this.z_accSense_max=z-z_gravSense; + } + this.x_accSense = x; + this.y_accSense = y; + this.z_accSense = z; + this.orientation = orientation; + invalidate(); + } + public Boolean inHorizontalMode(){ + double sum=x_gravSense*x_gravSense+y_gravSense*y_gravSense; + double sqs=Math.sqrt(sum); + if(sqs<0.5) return true; + else return false; + } + public void setVectorColor(){ + //Color GRavity Vector + double prec=0; + if (inHorizontalMode())prec=precition/4; + else prec=precition; + double sum=x_gravSense*x_gravSense+y_gravSense*y_gravSense+z_gravSense*z_gravSense; + double suma=x_gravSense*x_gravSense+y_gravSense*y_gravSense; + double sumb=y_gravSense*y_gravSense+z_gravSense*z_gravSense; + double sumc=x_gravSense*x_gravSense+z_gravSense*z_gravSense; + double sqs=Math.sqrt(sum); + double sqsa=Math.sqrt(suma); + double sqsb=Math.sqrt(sumb); + double sqsc=Math.sqrt(sumc); + if (x_gravSense > sqs*(1-prec) || y_gravSense > sqs*(1-prec) || z_gravSense > sqs*(1-prec) ){ + paintVector.setColor(Color.GREEN); + paintVectorHelp.setColor(Color.GREEN); + }else + if (sqsa > sqs*(1-prec) || sqsb > sqs*(1-prec) || sqsc > sqs*(1-prec) ){ + paintVector.setColor(Color.BLUE); + paintVectorHelp.setColor(Color.BLUE); + } + else{ + paintVector.setColor(Color.RED); + paintVectorHelp.setColor(Color.RED); + } + //Color Accel Vector + + double acc= getLength(x_accSense-x_gravSense,y_accSense-y_gravSense,z_accSense-z_gravSense); + + if (acc<0.01){ + paintVector2.setColor(Color.GREEN); + paintVector2Help.setColor(Color.GREEN); + }else if (acc<=0.694){ + paintVector2.setColor(Color.BLUE); + paintVector2Help.setColor(Color.BLUE); + }else{ + paintVector2.setColor(Color.RED); + paintVector2Help.setColor(Color.RED); + } + double acc_max= getLength(x_accSense_max,y_accSense_max,z_accSense_max); + if (acc_max<0.01){ + + paintVector3Help.setColor(Color.GREEN); + }else if (acc_max<=0.694){ + paintVector3Help.setColor(Color.BLUE); + }else{ + paintVector3Help.setColor(Color.RED); + } + + } +} diff --git a/app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorListener.java b/app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorListener.java new file mode 100644 index 0000000..8c98b2c --- /dev/null +++ b/app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorListener.java @@ -0,0 +1,25 @@ +package com.softwarefools.nik.spiritlevel; + +public interface MySensorListener { + + //public void onTemperatureChanged(float t); + + //public void onHumidityChanged(float h); + + //public void onDistChanged(float d); + + //public void onLightChanged(float l); + + //public void onPressureChanged(float p); + + //public void onMagneticFieldChanged(float x, float y, float z); + + //public void onGyroChanged(float x, float y, float z); + + public void onGravityChanged(float x, float y, float z); + + public void onAccelerationChanged(float x, float y, float z); + + public void onShake(float force); + +} diff --git a/app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorManager.java b/app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorManager.java new file mode 100644 index 0000000..aca416f --- /dev/null +++ b/app/src/main/java/com/softwarefools/nik/spiritlevel/MySensorManager.java @@ -0,0 +1,490 @@ +package com.softwarefools.nik.spiritlevel; + +import java.text.DecimalFormat; +import java.util.List; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.widget.Toast; + +public class MySensorManager { + private static Context aContext=null; + + + /** Accuracy configuration */ + private static float threshold = 15.0f; + private static int interval = 200; + + private static Sensor sensorgravity; + + private static Sensor sensoracell; + /* + private static Sensor sensormagneticfield; + private static Sensor sensorgyro; + + private static Sensor sensorlight; + private static Sensor sensordistance; + private static Sensor sensorpressure; + private static Sensor sensortemp; + private static Sensor sensorhumid;*/ + + private static SensorManager sensorManager; + // you could use an OrientationListener array instead + // if you plans to use more than one listener + private static MySensorListener listener; + + /** indicates whether or not Accelerometer Sensor is supported */ + private static Boolean gravitysupported; + + private static Boolean accelsupported; + /* + private static Boolean magneticsupported; + private static Boolean gyrosupported; + + private static Boolean lightsupported; + private static Boolean distancesupported; + private static Boolean pressuresupported; + private static Boolean humidsupported; + private static Boolean tempsupported; + */ + /** indicates whether or not Accelerometer Sensor is running */ + private static boolean running = false; + + /** + * Returns true if the manager is listening to orientation changes + */ + public static boolean isListening() { + return running; + } + + /** + * Unregisters listeners + */ + public static void stopListening() { + running = false; + try { + if (sensorManager != null && gravityEventListener != null) { + sensorManager.unregisterListener(gravityEventListener); + } + } catch (Exception e) {} + } + + /** + * Returns true if at least one Accelerometer sensor is available + */ + public static boolean isSupported(Context context) { + aContext = context; + if (gravitysupported == null) { + if (aContext != null) { + + + sensorManager = (SensorManager) aContext. + getSystemService(Context.SENSOR_SERVICE); + + // Get all sensors in device + List<Sensor> sensorsgrv = sensorManager.getSensorList(Sensor.TYPE_GRAVITY); + + List<Sensor> sensorsacc = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); + + /* + List<Sensor> sensorsgyr = sensorManager.getSensorList(Sensor.TYPE_GYROSCOPE); + List<Sensor> sensorspres = sensorManager.getSensorList(Sensor.TYPE_PRESSURE); + List<Sensor> sensormagn = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD); + List<Sensor> sensorlgt = sensorManager.getSensorList(Sensor.TYPE_LIGHT); + List<Sensor> sensordst = sensorManager.getSensorList(Sensor.TYPE_PROXIMITY); + List<Sensor> sensorhum = sensorManager.getSensorList(Sensor.TYPE_RELATIVE_HUMIDITY); + List<Sensor> sensortmp = sensorManager.getSensorList(Sensor.TYPE_AMBIENT_TEMPERATURE); + */ + if(sensorsgrv.size() > 0) gravitysupported=true; + if(sensorsacc.size() > 0)accelsupported=true; + /* + if(sensorsgyr.size()>0) gyrosupported=true; + if(sensorspres.size() > 0) pressuresupported=true; + if(sensormagn.size() > 0) magneticsupported = true; + if(sensorlgt.size() > 0) lightsupported = true; + if(sensordst.size()>0) distancesupported = true; + if(sensorhum.size()>0 ) humidsupported =true; + if(sensortmp.size()>0 ) tempsupported = true; + */ + } else { + return false; + } + } + return true; + } + + /** + * Configure the listener for shaking + * @param threshold + * minimum acceleration variation for considering shaking + * @param interval + * minimum interval between to shake events + */ + public static void configure(int threshold, int interval) { + MySensorManager.threshold = threshold; + MySensorManager.interval = interval; + } + + /** + * Registers a listener and start listening + * @param accelerometerListener + * callback for accelerometer events + */ + public static void startListening( MySensorListener sensorListener ) + { + + sensorManager = (SensorManager) aContext. + getSystemService(Context.SENSOR_SERVICE); + + // Take all sensors in device + + if(gravitysupported){ + List<Sensor> sensorsg = sensorManager.getSensorList(Sensor.TYPE_GRAVITY); + sensorgravity = sensorsg.get(0); + sensorManager.registerListener( + gravityEventListener, sensorgravity, + SensorManager.SENSOR_DELAY_GAME); + running=true; + } + + if(accelsupported){ + List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER); + sensoracell = sensors.get(0); + running = sensorManager.registerListener( + sensorEventListener, sensoracell, + SensorManager.SENSOR_DELAY_GAME); + } + /* + if(gyrosupported){ + List<Sensor> sensorsgyr = sensorManager.getSensorList(Sensor.TYPE_GYROSCOPE); + sensorgyro = sensorsgyr.get(0); + sensorManager.registerListener( + gyroEventListener, sensorgyro, + SensorManager.SENSOR_DELAY_GAME); + } + if(pressuresupported){ + List<Sensor> sensorsp = sensorManager.getSensorList(Sensor.TYPE_PRESSURE); + sensorpressure = sensorsp.get(0); + sensorManager.registerListener( + presEventListener, sensorpressure, + SensorManager.SENSOR_DELAY_GAME); + } + if(magneticsupported){ + List<Sensor> sensorsp = sensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD); + sensormagneticfield = sensorsp.get(0); + sensorManager.registerListener( + magnetEventListener, sensormagneticfield, + SensorManager.SENSOR_DELAY_GAME); + } + if(lightsupported){ + List<Sensor> sensorsp = sensorManager.getSensorList(Sensor.TYPE_LIGHT); + sensorlight = sensorsp.get(0); + sensorManager.registerListener( + lightEventListener, sensorlight, + SensorManager.SENSOR_DELAY_GAME); + } + if(distancesupported){ + List<Sensor> sensords = sensorManager.getSensorList(Sensor.TYPE_PROXIMITY); + sensordistance = sensords.get(0); + sensorManager.registerListener( + distEventListener, sensordistance, + SensorManager.SENSOR_DELAY_GAME); + } + if(humidsupported){ + List<Sensor> sensorhm = sensorManager.getSensorList(Sensor.TYPE_RELATIVE_HUMIDITY); + sensorhumid = sensorhm.get(0); + sensorManager.registerListener( + humidEventListener, sensorhumid, + SensorManager.SENSOR_DELAY_GAME); + } + if(tempsupported){ + List<Sensor> sensortp = sensorManager.getSensorList(Sensor.TYPE_AMBIENT_TEMPERATURE); + sensortemp = sensortp.get(0); + sensorManager.registerListener( + tempEventListener, sensortemp, + SensorManager.SENSOR_DELAY_GAME); + } + */ + listener = sensorListener; + + + + } + + /** + * Configures threshold and interval + * And registers a listener and start listening + * @param accelerometerListener + * callback for accelerometer events + * @param threshold + * minimum acceleration variation for considering shaking + * @param interval + * minimum interval between to shake events + */ + public static void startListening( + MySensorListener myListener, + int threshold, int interval) { + configure(threshold, interval); + startListening(myListener); + } + + /** + * The listener that listen to events from the accelerometer listener + */ + + private static SensorEventListener sensorEventListener = + new SensorEventListener() { + + private long now = 0; + private long timeDiff = 0; + private long lastUpdate = 0; + private long lastShake = 0; + + private float x = 0; + private float y = 0; + private float z = 0; + private float lastX = 0; + private float lastY = 0; + private float lastZ = 0; + private float force = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + // use the event timestamp as reference + // so the manager precision won't depends + // on the AccelerometerListener implementation + // processing time + now = event.timestamp; + + x = event.values[0]; + y = event.values[1]; + z = event.values[2]; + + // if not interesting in shake events + // just remove the whole if then else block + if (lastUpdate == 0) { + lastUpdate = now; + lastShake = now; + lastX = x; + lastY = y; + lastZ = z; + //Toast.makeText(aContext,"No Motion detected",Toast.LENGTH_SHORT).show(); + + } else { + timeDiff = now - lastUpdate; + + if (timeDiff > 0) { + + /*force = Math.abs(x + y + z - lastX - lastY - lastZ) + / timeDiff; */ + force = Math.abs(x + y + z - lastX - lastY - lastZ); + + if (Float.compare(force, threshold) >0 ) { + //Toast.makeText(Accelerometer.getContext(), + //(now-lastShake)+" >= "+interval, 1000).show(); + + if (now - lastShake >= interval) { + + // trigger shake event + listener.onShake(force); + } + else + { + // Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show(); + + } + lastShake = now; + } + lastX = x; + lastY = y; + lastZ = z; + lastUpdate = now; + } + else + { + //Toast.makeText(aContext,"No Motion detected", Toast.LENGTH_SHORT).show(); + + } + } + // trigger change event + listener.onAccelerationChanged(x, y, z); + } + + }; + private static SensorEventListener gravityEventListener = + new SensorEventListener() { + + private float x = 0; + private float y = 0; + private float z = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + // use the event timestamp as reference + // so the manager precision won't depends + // on the AccelerometerListener implementation + // processing time + + + x = event.values[0]; + y = event.values[1]; + z = event.values[2]; + + + // trigger change event + listener.onGravityChanged(x, y, z); + } + + }; + /* + private static SensorEventListener gyroEventListener = + new SensorEventListener() { + + private float x = 0; + private float y = 0; + private float z = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + // use the event timestamp as reference + // so the manager precision won't depends + // on the AccelerometerListener implementation + // processing time + + + x = event.values[0]; + y = event.values[1]; + z = event.values[2]; + + + // trigger change event + listener.onGyroChanged(x, y, z); + } + + }; + + private static SensorEventListener magnetEventListener = + new SensorEventListener() { + + private float x = 0; + private float y = 0; + private float z = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + x = event.values[0]; + y = event.values[1]; + z = event.values[2]; + + + // trigger change event + listener.onMagneticFieldChanged(x, y, z); + } + + }; + private static SensorEventListener lightEventListener = + new SensorEventListener() { + + private float l = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + + l = event.values[0]; + + listener.onLightChanged(l); + } + + }; + private static SensorEventListener distEventListener = + new SensorEventListener() { + + private float d = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + + d = event.values[0]; + + listener.onDistChanged(d); + } + + }; + private static SensorEventListener humidEventListener = + new SensorEventListener() { + + private float h = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + + h = event.values[0]; + + listener.onHumidityChanged(h); + } + + }; + private static SensorEventListener tempEventListener = + new SensorEventListener() { + + private float t = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + + t = event.values[0]; + + listener.onTemperatureChanged(t); + } + + }; + private static SensorEventListener presEventListener = + new SensorEventListener() { + + private float p = 0; + //private float x = 0; + // private float y = 0; + // private float z = 0; + + public void onAccuracyChanged(Sensor sensor, int accuracy) {} + + @Override + public void onSensorChanged(SensorEvent event) { + // use the event timestamp as reference + // so the manager precision won't depends + // on the AccelerometerListener implementation + // processing time + + + p = event.values[0]; + // y = event.values[1]; + // z = event.values[2]; + + + // trigger change event + listener.onPressureChanged(p); + } + + }; + */ +} + diff --git a/app/src/main/res/menu/level.xml b/app/src/main/res/menu/level.xml new file mode 100644 index 0000000..76cfed8 --- /dev/null +++ b/app/src/main/res/menu/level.xml @@ -0,0 +1,22 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + + <item + android:id="@+id/action_exit" + android:orderInCategory="101" + android:showAsAction="collapseActionView" + android:title="@string/action_exit"/> + <item + android:id="@+id/action_settings" + android:orderInCategory="100" + android:showAsAction="collapseActionView" + android:title="@string/action_settings"/> + + <item android:id="@+id/action_changelang" + android:title="@string/action_lang" + android:orderInCategory="1" + android:showAsAction="collapseActionView" + + + + /> +</menu> diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml new file mode 100644 index 0000000..ce9ca0c --- /dev/null +++ b/app/src/main/res/values-de/strings.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + + <string name="action_settings">Einstellungen</string> + + <string name="alert">Achtung! Das waren </string> + + <string name="action_lang">Sprachwechsel</string> + <string name="action_exit">Beenden</string> + + <string name="change_text">Wechsele Sprache zu </string> + <string name="change_german">Deutsch</string> + <string name="change_english">Englisch</string> + <string name="goodby">Danke dass sie Software Fools Software Verwenden!</string> + + <string name="toast_force">Kraft detektiert! \n Kraft:</string> +</resources> diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml new file mode 100644 index 0000000..9704ddd --- /dev/null +++ b/app/src/main/res/values-en/strings.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + + <string name="action_settings">Settings</string> + + <string name="alert">Attention! Thats about </string> + + <string name="action_lang">Flip Language</string> + <string name="action_exit">Exit</string> + + <string name="change_text">Changing Language to </string> + <string name="change_german">German</string> + <string name="change_english">English</string> + <string name="goodby">Thank You for Using Software Fools Software!</string> + + <string name="toast_force">Motion detected \n Force:</string> +</resources> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..17288e8 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="app_name">SpiritLevel</string> + + <string name="hello_world">Hello world!</string> + + <string name="newton">Newton!</string> + <string name="newton_short">N</string> + <string name="fuckoff">Fuck Off!</string> + +</resources> |
