Magnetic Sensor und Android 12 läuft nicht

  • Antworten:4
  • Bentwortet
  • Forum-Beiträge: 537

28.03.2022, 21:46:37 via Website

Hallo zusammen

Ich habe eine kleine App welche mir die Richtung nach Süden zeigt. Unter Android 11 läuft alles ohne Probleme.

package ch.robbisoft.kompass;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

private final static double pi = Math.PI;
private static final double FAKTOR = 180 / pi;

private SensorManager sensorManager;
private Sensor sensor_accels = null;
private Sensor sensor_magnet = null;
private Sensor magnetfeldSensor;
private KompassnadelView view;
private boolean hoch = true; //Ist der Bildschirm hoch oder quer

private float accels[] = new float[3];
private float mags[] = new float[3];
private float pool_accels[][] = new float[10][3];
private float pool_mags[][] = new float[10][3];
private int n_accels = 0;
private int n_mags = 0;

private float[] f_werte = new float[3];
private float azimuth = 0.0f;
private float polar = 0.0f;
private float roll = 0.0f;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    magnetfeldSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
    sensor_accels = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

// sensor_magnet = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
//test neu
// sensor_accels = sensorManager.getSensorList(Sensor.TYPE_ALL).get(Sensor.TYPE_ACCELEROMETER);
sensor_magnet = sensorManager.getSensorList(Sensor.TYPE_ALL).get(Sensor.TYPE_MAGNETIC_FIELD);
view = new KompassnadelView(this);
setContentView(view);
view.setPortrait(hoch);
}

public void onSensorChanged(SensorEvent event){

// if(view != null){
// view.setWinkel(event.values[0]);
// view.setWerty(event.values[1]);
// view.setWertz(event.values[2]);
// }
switch( event.sensor.getType() ){
case Sensor.TYPE_ACCELEROMETER : {
pool_accels[n_accels] = event.values.clone();
if( n_accels > 8 ){
accels = durchschnit( pool_accels );
n_accels = 0;
calc_pos();
}
n_accels++;
break;
}
case Sensor.TYPE_MAGNETIC_FIELD : {
pool_mags[n_mags] = event.values.clone();
if( n_mags > 8 ){
mags = durchschnit( pool_mags );
n_mags = 0;
calc_pos();
}
n_mags++;
}
}
}

public void onAccuracyChanged(Sensor sensor, int accuracy){

}

@Override
protected void onResume() {
    super.onResume();

// sensorManager.registerListener((SensorEventListener) this, magnetfeldSensor, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, sensor_accels, SensorManager.SENSOR_DELAY_NORMAL);
sensorManager.registerListener(this, sensor_magnet, SensorManager.SENSOR_DELAY_NORMAL);
}

@Override
protected void onPause() {
    sensorManager.unregisterListener(this);
    super.onPause();
}

private float[] durchschnit(float[][] pool) {
    float res[] = {0f, 0f, 0f};

    for(int i=0; i < 10 ;i++){
        res[0] += pool[i][0];
        res[1] += pool[i][1];
        res[2] += pool[i][2];
    }
    res[0] /= 10;
    res[1] /= 10;
    res[2] /= 10;

    return res;
}

private void calc_pos(){
    if (mags != null && accels != null) {
        float[] gravity = new float[9];
        float[] magnetic = new float[9];
        sensorManager.getRotationMatrix(gravity, magnetic, accels, mags);
        float[] outGravity = new float[9];
        sensorManager.remapCoordinateSystem(gravity, SensorManager.AXIS_X, SensorManager.AXIS_Z, outGravity);
        sensorManager.getOrientation(outGravity, f_werte);

        azimuth = (float) (f_werte[0] * FAKTOR);
        polar = (float) (f_werte[1] * -FAKTOR); //Was unter dem Horizont ist soll Negativ angezeigt werden
        roll = (float) (f_werte[2] * FAKTOR);

        //Berechnung von App Sonne

// if( azimuth < 0 ){
// azimuth = 180 - (azimuth * -1);
// }else{
// azimuth += 180;
// }

        mags = null;
        accels = null;
    }
    if(view != null){
        view.setWinkel(azimuth);
        view.setWerty(polar);
        view.setWertz(roll);
    }
}

@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    if(outState != null) {
        outState.putBoolean("format", hoch);
    }
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if(savedInstanceState != null) {
        hoch = !savedInstanceState.getBoolean("format");
        view.setPortrait(hoch);
    }
}

}

Unter Android 12 läuft die App nicht mehr. Denn der Zweig mit dem Magnetic Sensor

case Sensor.TYPE_MAGNETIC_FIELD : {
            pool_mags[n_mags] = event.values.clone();
            if( n_mags > 8 ){
                mags = durchschnit( pool_mags );
                n_mags = 0;
                calc_pos();
            }
            n_mags++;
        }

Wird nicht mehr durchlaufen. Unter Android 12 wird der Sensor nicht mehr gelesen. Hat sich zwischen 11 und 12 was geändert in diesem Bereich und ich habe es nicht mitgekriegt.

Was muss ich ändern, damit die App ebenfalls unter Android 12 läuft?

Gruss Renato

Kommentieren
Beste Antwort
  • Forum-Beiträge: 1.485

31.03.2022, 11:07:48 via Website

// sensor_magnet = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensor_magnet = sensorManager.getSensorList(Sensor.TYPE_ALL).get(Sensor.TYPE_MAGNETIC_FIELD);

benutze mal wieder die ausgeklammerte Zeile.

und setze vor
public void onSensorChanged(SensorEvent event){

auch das @overide damit es wirklich überschrieben wird.

ansonsten kann ich dir nur das geben.

https://developer.android.com/guide/topics/sensors/sensors_position#java

Note: If your app targets Android 12 (API level 31) or higher, this sensor is rate-limited.

https://developer.android.com/guide/topics/sensors/sensors_overview#sensors-rate-limiting

— geändert am 31.03.2022, 11:12:36

Hilfreich?
Kommentieren
  • Forum-Beiträge: 537

29.03.2022, 18:00:42 via Website

Ciao Jokel

Dann wird für die Rotation kein "event" mehr ausgelöst. Wie komme ich dann an diese Daten? Ich habe folgendes versucht :

@Override

public void onRotationUpdate(@NonNull float[] newMatrix) {

Das funktioniert aber auch nicht. Irgend wie will er diese Methode nicht kennen. Wie muss ich vorgehen? Hast du mir vielleicht ein Link auf ein Beispiel.

Gruss Renato

Hilfreich?
Kommentieren
Beste Antwort
  • Forum-Beiträge: 1.485

31.03.2022, 11:07:48 via Website

// sensor_magnet = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensor_magnet = sensorManager.getSensorList(Sensor.TYPE_ALL).get(Sensor.TYPE_MAGNETIC_FIELD);

benutze mal wieder die ausgeklammerte Zeile.

und setze vor
public void onSensorChanged(SensorEvent event){

auch das @overide damit es wirklich überschrieben wird.

ansonsten kann ich dir nur das geben.

https://developer.android.com/guide/topics/sensors/sensors_position#java

Note: If your app targets Android 12 (API level 31) or higher, this sensor is rate-limited.

https://developer.android.com/guide/topics/sensors/sensors_overview#sensors-rate-limiting

— geändert am 31.03.2022, 11:12:36

Hilfreich?
Kommentieren
  • Forum-Beiträge: 537

02.04.2022, 18:25:32 via Website

Danke Jokel. Genau und nun funktioniert es auch wieder unter Android 12.

Gruss Renato

Hilfreich?
Kommentieren