Unregister SensorListener funktioniert nicht?

Z

Zentis

Neues Mitglied
0
Hallo,

ich habe folgendes Problem:
Obwohl ich den Sensorlistener abmelde, wird die onSensorChanged-Methode aufgerufen.

Code:
public class InitActivity extends Activity implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mSensor;

    private List<Float> xWerte = new ArrayList<Float>();
    private List<Float> yWerte = new ArrayList<Float>();
    private List<Float> zWerte = new ArrayList<Float>();

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

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        mSensorManager.registerListener(this, mSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        xWerte.add(event.values[0] * 100);
        yWerte.add(event.values[1] * 100);
        zWerte.add(event.values[2] * 100);

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        if(this.xWerte.size()>=10){
            stopSensor();
            System.out.println("ich war fertig: "+event.values[0]);
        }
        
    }

    private void stopSensor() {
        mSensorManager.unregisterListener(this,mSensor);
        System.out.println("fertig");
    }
Ziel ist es, eine Liste mit 10 Sensorwerten zu erhalten.
Allerdings stoppt die ganze Geschichte nicht...immer wieder erhalte ich
die Ausgabe "ich war fertig" mit neuen Sensorwerten.
(Und natürlich auch die Ausgabe "fertig")

Wie erreiche ich es, dass die onSensorChanged-Methode
nicht mehr aufgerufen wird?

Vielen Dank für die Hilfe im Voraus!
 
Sers,
auch hier bin ich mir nicht sicher, ob der Thread so die beste Lösung ist.
Die Messung sollte sich wie folgt anhalten lassen:

"stopIt" halt noch irgendwo mit false initialisieren.

Code:
 @Override public void onSensorChanged(SensorEvent event)
{
    if (!stopIt)
    {
        xWerte.add(event.values[0] * 100);
        yWerte.add(event.values[1] * 100);
        zWerte.add(event.values[2] * 100);
    }

    try
    {
        Thread.sleep(1000);
    }
    catch (InterruptedException e)
    { // TODO Auto-generated catch block             e.printStackTrace();         }          if(this.xWerte.size()>=10){
        stopIt = true;
        stopSensor();
        System.out.println("ich war fertig: " + event.values[0]);
    }
}
 
Thread.sleep(1000) im HauptThread ist keine gute Lösung. Damit schickst du die gesamte App für 1s schlafen.

Löse das lieber mit einem Timer, der periodisch ein Schalter auf true setzt setzt.
Timer | Android Developers Dieser wird von deinen Methode onSensorChanged auf false gesetzt, wenn sie ausgeführt wird. Dein Code in der Methode onSensorChanged wird nur ausgeführt, wenn der Schalter true ist. Den Listener wieder abzumelden, dürfte dann auch kein Problem sein.
 
Zuletzt bearbeitet:
Es könnte sein, dass Thread.Sleep dazu führt, dass die neuen Sensorwerte nicht verarbeitet werden, sich aber in die Reihe der zu verarbeiteten ANfragen einreihen.
Wenn du also Thread.sleep machst werden in der Zeit alle alle Sensor Events zwischengespeichert und deswegen bekommst du diese auch noch nachdem du den Listener entfernt hast, weil die neuen Werte noch in der Warteschlange liegen.

Was passiert denn wenn du Thread.sleep weglässt?
Funktioniert es dann?
Oder hört es irgendwann von alleine auf?
 
Hallo,

vielen Dank für die Hinweise, haben sehr geholfen.
Gelöst habe ich es jetzt folgendermaßen:

Das Interface wurde erweitert:

Code:
public interface SensorWertListener {
    
    public float getXvalue();
    public float getYvalue();
    public float getZvalue();
    public void stopSensor();
    public void startSensor();

}
Die onCreate-Methode hat weniger zu tun:

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

        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        mSensorManager.registerListener(this, mSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
        
    }
Die onSensorChanged angepasst (und überwacht, damit sie auch ja aus ist ;) )

Code:
@Override
    public void onSensorChanged(SensorEvent event) {
        
        x = event.values[0] * 100;
        y = event.values[1] * 100;
        z = event.values[2] * 100;
        
        System.out.println("onSensorChanged");

    }
Starten und Stoppen des Sensors:

Code:
@Override
    public void stopSensor() {
        // TODO Auto-generated method stub
        mSensorManager.unregisterListener(this);
    }

    @Override
    public void startSensor() {
        // TODO Auto-generated method stub
        mSensorManager.registerListener(this, mSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }
Die anderen Methoden aus dem Interface spare ich mir mal.
Hier noch der Weg, wie die Klasse, die ja mit den Werten arbeiten soll,
an ihre Sensorwerte kommt:

Code:
public Konstruktor(SensorWertListener listener) {
        this.listener = listener;
    }

    public void initialisiere() {

        final List<Float> xWerte = new ArrayList<Float>();
        final List<Float> yWerte = new ArrayList<Float>();
        final List<Float> zWerte = new ArrayList<Float>();

        new CountDownTimer(10000, 1000) {

            @Override
            public void onTick(long millisUntilFinished) {
                // TODO Auto-generated method stub
                xWerte.add(listener.getXvalue());
                yWerte.add(listener.getYvalue());
                zWerte.add(listener.getZvalue());

                System.out.println("timer");
            }

            @Override
            public void onFinish() {
                listener.stopSensor();
            }
        }.start();

    }

Das Problem scheint damit gelöst zu sein, Thread.sleep war der Übeltäter.

Vielen Dank nochmals!
 

Ähnliche Themen

SaniMatthias
Antworten
19
Aufrufe
960
swa00
swa00
O
Antworten
15
Aufrufe
2.971
ORHUX
O
K
Antworten
3
Aufrufe
1.168
Kapikalaani
K
Zurück
Oben Unten