# Accelerometer ohne Activity



## guguli (1. Nov 2014)

Hallo zusammen,

ich möchte gerne eine Klasse Accelerometer schreiben die keine Activity ist.

Also so hab ich mir das vorgestellt.
Ich ab eine klasse MainActivity mit einem Start Button. wenn ich den Button betätige dann rufe ich die Klasse Accelerometer, wodrin ich dann für x,y,z Achsen die Beschleunigungen berechne. In der Klasse Accelerometer  werden noch andere Methoden sein, die jetzt keine Relevanz haben. 

Wieso ich das so machen möchte ist weil ich versuche meine App modular zu entwickeln. 
D.h. ich möchte noch zustätzlich nach dem ich den Start Button in MainActivity betätigt habe nicht nur den Accelerometer  starte sonder auch andere Messsensoren.  (Pulsmesssensor,....)

Könnt mir einen Tipp geben wie ch sowas am besten realisieren kann???

THX


----------



## dzim (3. Nov 2014)

Indem du eine Klasse erstellst, die in ihrem Konstruktor einen Context übergeben bekommt. Auch wenn es dann keine Activity ist, benötigt diese Klasse dennoch Zugriff auf einen Context (eine Activity erbt ja von Context), um sich beim Accelometer registrieren zu können.

Ich hab das mal für die Internet-Verbindung gemacht, so dass ich nur einen "Handler" (a.k.a. Listener) implementieren muss, um auf eine ganze Reihe von Daten Zugriff zu bekommen. Konkret brauche ich Zugriff auf ConnectivityManager, WifiManager, TelephonyManager und zusätzlich brauche noch einen Network-Receiver, sowie PhoneStateListener um auf eine grosse Bandbreite an Daten zurückgreifen zu können und meine Activity eben nicht mit sinnlosen Kram zu befüllen.

Ist alles keine Hexerei sondern stincknormale und -langweilige Modularisierung/Objektorientierung...


----------



## guguli (3. Nov 2014)

Also du meinst ich soll eine klasse ModuleHandler erstellen, die in ihrem Konstruktor einen Context übergeben bekommt ???
So :

```
public class ModuleHandler {

	public ModuleHandler(Context context){
		
	}
}
```

Also meine Idee ist erst nach dem ich start button betätigt habe, die sensoren anfangen daten zu ermitteln. 
so sieht meine MainActivity aus:

```
public class MainActivity extends Activity  {

	RelativeLayout layout;
	

	Button start = (Button) findViewById(R.id.btnStart);

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		
		
		start.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				start.getBackground().setColorFilter(
						new LightingColorFilter(0x0000FF00, 0x0000FF00));
				

			}
		});
}
```
wie komme ich von hier zu der Module klasse??? wie kann ich dieses klasse aufrufen???

THX


----------



## dzim (3. Nov 2014)

So wie du es immer in Android tun würdest? Z.B. in #onResume() instanziieren und so...?


----------



## guguli (3. Nov 2014)

Hallo,

ich hab das wie folgt gemacht:
MainActivity klasse:

```
protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mStartButton = (Button) findViewById(R.id.btnStart);
		mDebugButton = (Button) findViewById(R.id.changeToDebug);
		mModuleHandler = new ModuleHandler(this);

		initializeViewsAcc();

		mStartButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {

				mStartButton.getBackground().setColorFilter(
						new LightingColorFilter(0x0000FF00, 0x0000FF00));
				mModuleHandler.start();

			}
		});

		changeToDebugView();

	}
public void initializeViewsAcc() {
		Accelerometer.currentX = (TextView) findViewById(R.id.currentX);
		Accelerometer.currentY = (TextView) findViewById(R.id.currentY);
		Accelerometer.currentZ = (TextView) findViewById(R.id.currentZ);
	}

	public static void displayCleanValues() {
		Accelerometer.currentX.setText("0.0");
		Accelerometer.currentY.setText("0.0");
		Accelerometer.currentZ.setText("0.0");
	}

	// display the current x,y,z accelerometer values
	public static void displayCurrentValues() {
		Accelerometer.currentX
				.setText(Float.toString(Accelerometer.getDeltaX()));
		Accelerometer.currentY
				.setText(Float.toString(Accelerometer.getDeltaY()));
		Accelerometer.currentZ
				.setText(Float.toString(Accelerometer.getDeltaZ()));
	}
```
Modulehandler Klasse:

```
public class ModuleHandler {
	private Context mContext;
	private final Accelerometer mAccelerometer;
	private boolean mRunning = false;

	public ModuleHandler(Context context) {
		mContext = context;
		mAccelerometer = new Accelerometer(mContext);
	}

	public void start() {
		if (!mRunning) {
			mAccelerometer.start();
			mRunning = true;
		}
	}

	public void stop() {
		if(mRunning) {
			mAccelerometer.stop();
			mRunning = false;
		}
	}
}
```
und accelerometer klasse:

```
public class Accelerometer implements SensorEventListener {

	public static TextView currentX;
	public static TextView currentY;
	public static TextView currentZ;

	private float lastX, lastY, lastZ;

	private SensorManager sensorManager;
	private Sensor accelerometer;

	private static float deltaX = 0;
	private static float deltaY = 0;
	private static float deltaZ = 0;

	static float vibrateThreshold = 0;

	public static Vibrator v;
	private Context mContext;

	public Accelerometer(Context context) {
		mContext = context;

		sensorManager = (SensorManager) mContext
				.getSystemService(Context.SENSOR_SERVICE);
		if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
			// success! we have an accelerometer

			accelerometer = sensorManager
					.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
			sensorManager.registerListener(this, accelerometer,
					SensorManager.SENSOR_DELAY_NORMAL);
			vibrateThreshold = accelerometer.getMaximumRange() / 2;
		} else {
			// fai! we dont have an accelerometer!
		}

		// initialize vibration
		v = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		// clean current values
		MainActivity.displayCleanValues();
		// display the current x,y,z accelerometer values
		MainActivity.displayCurrentValues();
		// display the max x,y,z accelerometer values
		// displayMaxValues();

		// get the change of the x,y,z values of the accelerometer
		deltaX = Math.abs(lastX - event.values[0]);
		deltaY = Math.abs(lastY - event.values[1]);
		deltaZ = Math.abs(lastZ - event.values[2]);

		// if the change is below 2, it is just plain noise
		if (deltaX < 2)
			deltaX = 0;
		if (deltaY < 2)
			deltaY = 0;
		if (deltaZ < 2)
			deltaZ = 0;

		// set the last know values of x,y,z
		lastX = event.values[0];
		lastY = event.values[1];
		lastZ = event.values[2];

		vibrate();

	}

	// if the change in the accelerometer value is big enough, then vibrate!
	// our threshold is MaxValue/2
	public void vibrate() {
		if ((deltaX > vibrateThreshold) || (deltaY > vibrateThreshold)
				|| (deltaZ > vibrateThreshold)) {
			v.vibrate(50);
		}
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {

	}

	protected void stop() {
		sensorManager.unregisterListener(this);
	}

	protected void start() {
		sensorManager.registerListener(this, accelerometer,
				SensorManager.SENSOR_DELAY_NORMAL);
	}

	public static float getDeltaX() {
		return deltaX;
	}

	public static float getDeltaY() {
		return deltaY;
	}

	public static float getDeltaZ() {
		return deltaZ;
	}
}
```

Wie gesagt ich will das Acc erst dann startet wenn ich den button gedruckt habe, aber auch ohne dasss ich den button gedruckt habe, wenn ich das handy bewege kriege ich für X,Y und Z achsen werte angezeigt. kann einer bitte mir sagen wo mein Fehler ist.

THX


----------



## dzim (4. Nov 2014)

Ich würde spontan mal sagen, du startest ihn zwar mit dem Button, stoppst ihn aber nirgens. Dann wird er wohl munter weiter Daten empfangen...


----------



## guguli (5. Nov 2014)

Eigentlich schon. Ich meine wen ich die App neu starte dann soll die werte von X Y Z alle 0 sein, aber bevor ich den startbutton betätige ändern sich die werte trotzdem. also anders gesagt, ich starte die App und wenn ich das Gerät bewege dann ändern sich die werte, obwohl man davon ausgeht, dass der Accelerometer nicht aktive ist und erst mit der Betätigung der Start button soll er aktiviert/startet werden.

Ich stehe aufm Schlauch


----------



## dzim (6. Nov 2014)

Wenn ich den Code (beim überfliegen) richtig verstehe, registrierst du den Sensor-Listener schon im Konstruktor. Da könnte dein Problem bereits begründet sein.


----------



## guguli (7. Nov 2014)

Du hast vollkommen Recht ...  Es funktioniert jetzt so wie erwartet (Y).


----------

