Neigungssensor ansprechen und wert ausgeben in App

S

SmartPhone91

Neues Mitglied
Threadstarter
Hallo zusammen,

ich habe gerade begonnen eine App zu programmieren mit Android Studio.
Nun möchte ich gerne den Neigungssensor-Wert in der App anzeigen lassen.
Das heißt, sobald das Smartphone nach links oder rechts gedreht wird soll im TextView der Wert des Sensors ausgegeben werden.

Leider funktioniert die App beim start nicht. Sie wird sofort wieder gestoppt.

Folgendes habe ich nun mal programmiert:

TextView test;
SensorManager sensormanager;

Als erstes benötige ich den SensorEventListener, diesen implementiere ich in die Klasse:
implements SensorEventListener

Was hier passiert, weiß ich leider nicht?
Scheint einen "Sensor-Service" zu starten?
sensormanager = (SensorManager) getSystemService(SENSOR_SERVICE);

Hier melde ich den SensorListener an und sage welchen Sensor ich verwenden möchte:

sensormanager.registerListener(this, sensormanager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_NORMAL);

Nun frage ich den Sensor wert ab:
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
test.setText(SensorManager.AXIS_Y); // Hier schreibe ich den Wert in das TextView.
}
}

Da ich gerade erst mit der App programmierung gestartet habe, seid mir bitte nicht Böse wenn ich etwas falsch erklärt habe.

Darf ich euch bitten, das ihr mir die einzelnen Codezeilen mal genauer erklärt, damit ich verstehe was hier passiert?

Vielen Dank!
SG
 
S

SmartPhone91

Neues Mitglied
Threadstarter
Etwas habe ich noch vergessen, hier Übergebe ich den Text an die TextView:
test =(TextView) findViewById(R.id.textfeld);
 
J

jogimuc

Erfahrenes Mitglied
Hallo
bitte Poste mal den Code in dem dafür vorgeshenen Code Block, ist unter dem Plus versteckt.
Vorallen im zusammenhang so kann ich mir da wenig rausnehmen .
Am besten die gesamte Klasse.
 
Zuletzt bearbeitet:
1

123thomas

Fortgeschrittenes Mitglied
Hallo,

SmartPhone91 schrieb:
Etwas habe ich noch vergessen, hier Übergebe ich den Text an die TextView:
Code:
test =(TextView) findViewById(R.id.textfeld);
In dem Code Schnipsel wird nur das TextView initalisiert. Die Übergabe des Textes erfolgt bei :
Code:
test.setText(SensorManager.AXIS_Y);

Das sofortige stoppen der App bedeutet, dass ein Fehler vorliegt. Du müsstest mal den LogCat posten, damit wir den Fehler analysieren können.
 
J

jogimuc

Erfahrenes Mitglied
test.setText(SensorManager.AXIS_Y);
Wird auch keinen String zurückgeben.

aber um wirklich eine aussage treffen zu können wäre Fehler Meldung und Code Sinnvoll.

PS.
Im Übrigen ist es so das dir nicht der Manager die Werte gibt, sondern die musst du dir aus dem SensorEvent holen. Wozu wird es dir denn sonnst übergeben.

Die Werte sind in dem SensorEvent unter anderen in einem float []-Arrayfeld gespeichert.

Bei deinem gewünschten TYPE_ROTATION_VECTOR
Bedeutet

Values[0] x*sin(winkel/2)
Values[1] y*sin(winkel/2)
Values[2] z*sin(winkel/2)
Values[3] cos(winkel/2)

Somit ist deine Ausgabe mit test.setText(SensorManager.AXIS_Y);
Total falsch denn der Sensormanager gibt niemals einen String zurück.
setText erwartet aber einen String.

Versuche mal

Code:
public class MainActivity extends AppCompatActivity implements SensorEventListener
{
    TextView test;
    SensorManager sensormanager;

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

        test =(TextView) findViewById(R.id.textfeld);
        sensormanager = (SensorManager) getSystemService(SENSOR_SERVICE);
        sensormanager.registerListener(this, sensormanager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_NORMAL);
    }


    @Override
    public void onSensorChanged(SensorEvent event) {

        if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
            float[] werte  = event.values;
            test.setText(String.valueOf(werte[1]));
        }
    }

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

    }
}
PS. SensorManager.AXIS_Y ist eine konstante die einen int beinhaltet. Das erkennt man eigentlich schon an der gross Schreibung. Selbst wenn du den int in einen string wandelst wird immer der gleiche Wert ausgegeben und nicht der Bewegung entsprechende Wert.
 
Zuletzt bearbeitet:
S

SmartPhone91

Neues Mitglied
Threadstarter
Danke vielmals, es hat funktioniert.

Nun würde ich noch gerne den Sourcecode verstehen.
Bei ein paar Sachen bin ich mir nicht ganz sicher ob ich es Richtig verstanden habe.

Bitte bestätigen wenn es passt, oder mich einfach korrigieren. Vielen Dank!!

Code:
1.  sensormanager = (SensorManager) getSystemService(SENSOR_SERVICE);
Hier hole ich mir den SensorService um die Sensoren ansprechen zu können?

Code:
2.  sensormanager.registerListener(this, sensormanager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_NORMAL);
Hier melde ich als erstes mal den SensorLister an, danach hole ich mir den gewünschten Sensor.
Zuletzt kommt ein delay, wozu brauche ich das delay?
Werden sonst die Werte zu schnell abgefragt?

3. Warum wird hier ständig 'gecastet':

"sensormanager = (SensorManager)"
"test = (TextView)"

oder passiert hier was anderes?

Von Java kenne ich das als casting.

SG
 
J

jogimuc

Erfahrenes Mitglied
Hallo
ich habe eigentlich nur deinen Code benutzt und in eine Klasse gefast. bis auf die "onSensorChanged" Müsste das bei dir gleich aussehen.

sensormanager = (SensorManager) getSystemService(SENSOR_SERVICE);
Hiermit host du dir den Manager da es im System verschiedene Manager gibt und die Methode getSystemService als rückgabewert ein abstractes Object hat musst du es Casten ( TYPumwandlung).

Context | Android Developers


sensormanager.registerListener(this, sensormanager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR), SensorManager.SENSOR_DELAY_NORMAL);
SensorManager | Android Developers


Copy aus der Doku

registerListener
added in API level 3

public boolean registerListener (SensorEventListener listener,
Sensor sensor,
int samplingPeriodUs)
Registers a SensorEventListener for the given sensor at the given sampling frequency.

The events will be delivered to the provided SensorEventListener as soon as they are available. To reduce the power consumption, applications can use registerListener(SensorEventListener, Sensor, int, int) instead and specify a positive non-zero maximum reporting latency.

In the case of non-wake-up sensors, the events are only delivered while the Application Processor (AP) is not in suspend mode. See Sensor.isWakeUpSensor() for more details. To ensure delivery of events from non-wake-up sensors even when the screen is OFF, the application registering to the sensor must hold a partial wake-lock to keep the AP awake, otherwise some events might be lost while the AP is asleep. Note that although events might be lost while the AP is asleep, the sensor will still consume power if it is not explicitly deactivated by the application. Applications must unregister their SensorEventListeners in their activity's onPause() method to avoid consuming power while the device is inactive. See registerListener(SensorEventListener, Sensor, int, int) for more details on hardware FIFO (queueing) capabilities and when some sensor events might be lost.

In the case of wake-up sensors, each event generated by the sensor will cause the AP to wake-up, ensuring that each event can be delivered. Because of this, registering to a wake-up sensor has very significant power implications. Call Sensor.isWakeUpSensor() to check whether a sensor is a wake-up sensor. See registerListener(SensorEventListener, Sensor, int, int) for information on how to reduce the power impact of registering to wake-up sensors.

Note: Don't use this method with one-shot trigger sensors such as Sensor.TYPE_SIGNIFICANT_MOTION. Use requestTriggerSensor(TriggerEventListener, Sensor) instead. Use Sensor.getReportingMode() to obtain the reporting mode of a given sensor.

Parameters

listener

SensorEventListener: A SensorEventListener object.

sensor

Sensor: The Sensor to register to.

samplingPeriodUs

int: The rate sensor events are delivered at. This is only a hint to the system. Events may be received faster or slower than the specified rate. Usually events are received faster. The value must be one of SENSOR_DELAY_NORMAL, SENSOR_DELAY_UI, SENSOR_DELAY_GAME, or SENSOR_DELAY_FASTEST or, the desired delay between events in microseconds. Specifying the delay in microseconds only works from Android 2.3 (API level 9) onwards. For earlier releases, you must use one of the SENSOR_DELAY_* constants.

Returns

boolean

true if the sensor is supported and successfully enabled.
 
Zuletzt bearbeitet:
S

SmartPhone91

Neues Mitglied
Threadstarter
Danke für die Erklärung.

Wenn ich jetzt meinen Integer an meinen Laptop senden will, dann kann ich ja den OutputStream verwenden?
Oder würdet ihr das anders machen?

SG
 
J

jogimuc

Erfahrenes Mitglied
Hallo also erstens ist das kein Integer Wert der dir zurückgegeben wird sondern ein Flies Komma (Float) Wert.

Zweitens über welchen Übertragungs Weg willst du was senden?

Nur ein OutputStream wird da wohl nicht reichen.
 
S

SmartPhone91

Neues Mitglied
Threadstarter
Stimmt, ist ein float.

Über Bluetooth.
 
J

jogimuc

Erfahrenes Mitglied
Ich dachte du hast Deine Bluetooth Kommunikation fertig.
Wenn du etwas willst dann währe es sinnvoll konkrete fragen zu stellen.
Wir haben leider keine kristallkugel in der wir sehen können wo dein Problem ist.
Ich gehe schon davon aus wenn du es mit Bluetooth übertragen willst das du dich damit einigermaßen auskennst. Und nicht von uns den kompletten Code haben willst.
Etwas mehr Infos könntest du uns schon geben , lass dir doch nicht alles aus der Nase ziehen.
 
S

SmartPhone91

Neues Mitglied
Threadstarter
Man merkt doch, das ich mich mit Bluetooth in Java nicht auskenne.
Deshalb habe ich auch am Anfang darum gebeten, das mir jemand meinen geposteten Code erklärt.
Google hat einige Beispiele auf Lager, doch die Erklärungen sind mehr als mager.

Google bringt mich zur Verzweiflung!
Wie soll ich etwas können und verstehen, wenn es nirgends eine richtige Erklärung gibt.

Leider weiß ich nicht was ich alles machen muss, damit eine Datenübertragung per Bluetooth statt finden kann.

Als erstes würde ich gerne Erfahren, wie ich die Daten in der App per Bluetooth versenden kann?
Zweitens müsste ich dann wissen, wie ich die Daten in meiner desktop application empfangen kann?

Im Netz heißt es, das ich UUID, Vector ..... benötige?

local und remote device adresse wird mir im programm schon angezeigt.

PS: Falls ihr den Sourcecode meiner desktop application braucht sagt mir kurz Bescheid.

Deshalb bitte ich euch um Hilfe.

Danke!

SG
 
Zuletzt bearbeitet:
S

SmartPhone91

Neues Mitglied
Threadstarter
Kann mir da keiner weiterhelfen?

MfG
 
J

jogimuc

Erfahrenes Mitglied
Ich würde dir emphen einen neuen thread auf zu machen. Bei dem es im titel um Bluetooth geht.
 
J

jogimuc

Erfahrenes Mitglied
Hallo ich möchte nicht auf deinem neuen Thread als erster schreiben.
Du hast da ja deinen Code für deinen Pc veröffentlicht.
So wie ich das sehe suchst du da nach Geräten in der nähe und speicherst sie in eine ArrayListe mehr eigentlich nicht. Du suchst zwar Geräte koppeln tust du sie nicht und Daten senden empfangen auch nicht. Da fehlt aus meiner sicht noch viel.

Glaube nicht das der Code richtig arbeitet.
 
Zuletzt bearbeitet:
Oben Unten