# Java Klasse

## Sensor

Um auf einen Sensor zugreifen zu können muss ein `Sensor` und ein `SensorManager` wie folgt in der `MainActivity` Klasse deklariert werden.

```java
private SensorManager sensorManager;
private Sensor accelerometer;
```

Jetzt muss mit dem SensorManager auf einen Sensor zugegriffen werden. Zuerst muss dem SensorManager der SystemService `SENSOR_SERVICE` zugewiesen werden.

```java
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
```

Nun muss der Sensor vom SensorManager einen bestimmten Sensor zugeteilt bekommen. Accelerometer ist der Beschleunigungssensor.

```java
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
```

Um die Werte des Sensors abrufen zu können muss ein Listener registriert werden. `SENSOR_DELAY_*X*` gibt die Zeit zwischen den einzelnen Anfragen an den Sensor an.

```java
sensorManager.registerListener(this, accelerometer,SensorManager.SENSOR_DELAY_GAME);
```

Dies muss alles in der 'onCreate' Methode stattfinden.

Nun müssen wir auf eine Methode zugreifen, die etwas ausführt, wenn ein Sensor einen Wert zurückgibt. Diese bekommen wir, indem wir den 'SensorEventListener' in unsere 'MainActivity' implementieren.

```java
public class MainActivity extends Activity implements SensorEventListener {}
```

Jetzt klickt ihr auf den 'SensorEventListener' und drückt `ALT + ENTER` und wählt 'Implement Methods'. Dies erstellt die Methoden 'onAccuracyChanged' und 'onSensorChanged'. Wir werden nur die letzere benutzen.

In dieser Methode werden wir abfragen ob die Werte vom Beschleunigungssensor kommen.

```java
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER{
}
```

Mit `event.values[];` wird auf die Werte des Sensors zugegriffen. Hier sind `[0],[1],[2]` die Werte der `x,y,z` Achse des Handys.

## Zwischenaufgabe

Erstelle eine App, die die zugehörigen Sensor Werte für x,y und z in z.B. jeweils einer TextView darstellt. Dies hilft dir den Umgang mit dem Sensor zu verstehen und du siehst welche Werte der Sensor dir wann zurückgibt.

## Draw

Um in unserer App einen Gegenstand zeichnen zu können, muss eine eigene Klasse erstellt werden.

> Wie eine Klasse funktioniert ist für dieses Beispiel nicht relevant und wird hier daher nicht weiter erläutert.

```java
public class AnimatedView extends ImageView {
        static final int width = 50;
        static final int height = 50;

        public AnimatedView(Context context) {
            super(context);
            mDrawable = new ShapeDrawable(new RectShape());
            mDrawable.getPaint().setColor(0xffffAC23);
            mDrawable.setBounds(x-width, y-width, x + width, y + height);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            mDrawable.setBounds(x-width, y-height, x + width, y + height);
            mDrawable.draw(canvas);
            invalidate();
        }
    }
```

AnimatedView ist sozusagen ein erweitertes ImageView, das eine onDraw Methode hat, die wir so ändern, dass sie sich konstant neu zeichnet.

In der Methode AnimatedView wird einem neuem Drawable eine Form, eine Farbe und eine Größe und Position zugewiesen. Die Methode onDraw wird beim ersten Zeichnen des Gegenstands aufgerufen und wir dann durch `ivalidate();` neu aufgerufen wobei die alten Werte gelöscht werden.

In der `MainActivity` muss folgendes definiert werden:

```java
AnimatedView animatedView;
ShapeDrawable mDrawable = new ShapeDrawable();

public static int x;
public static int y;
```

In der onCreate Methode muss eine neue AnimatedView erzeugt werden und als Content festgelegt werden.

```java
animatedView = new AnimatedView(this); 
setContentView(animatedView);
```

## Sensor & Draw

Dies alles ermöglicht uns jetzt ein Gegenstand an den Koordinaten x und y konstant neu zu zeichnen. Außerdem haben wir die Werte unseres Beschleunigungssensors, mit dem wir die Positon des Gegenstands beinflussen können.

Innerhalb der bereits angelegten onSensorChanged Methode können wir die Position des Gegenstands wie folgt ändern.

```java
public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            x -= (int) event.values[0];
            y += (int) event.values[1];   
        }
    }
```

## Aufgabe

* Erstelle die App, mit Hilfe des Tutorials, die am Anfang dieses Projektes beschrieben wurde.

## Weiterführende Aufgaben

* Verhindere, dass der Gegenstand außerhalb des Bildschirms gezeichnet wird:
  * So kannst du die maximalen x oder y Werte eines Displays abrufen:&#x20;
    * ```java
      Display display = getWindowManager().getDefaultDisplay();
      Point size = new Point();
      display.getSize(size);
      int width_max = size.x;
      int height_max = size.y;
      ```
* Stoppe das Verschieben des Gegenstandes wenn die App minimiert wird
  * [Hilfe](http://www.javatpoint.com/images/androidimages/Android-Activity-Lifecycle.png)
  * `sensorManager.registerListener`/`sensorManager.unregisterListener`
