Czujniki pozycji

Platforma Android ma 2 czujniki, które pozwalają określić położenie urządzenia: czujnik pola geomagnetycznego i akcelerometr. Platforma Androida udostępnia też czujnik, który pozwala określić, jak blisko obiektu znajduje się tarcza urządzenia (tzw. czujnik zbliżeniowy). Czujnik pola geomagnetycznego i czujnik zbliżeniowy są sprzętowe. Większość producentów telefonów i tabletów wyposażona jest w czujnik pola geomagnetycznego. Producenci telefonów zwykle wyposażone są w czujnik zbliżeniowy, który określa, kiedy telefon znajduje się blisko twarzy użytkownika (np. podczas rozmowy telefonicznej). Do określenia orientacji urządzenia możesz używać odczytów z akcelerometru i czujnika pola geomagnetycznego.

Uwaga: czujnik orientacji został wycofany w Androidzie 2.2 (poziom interfejsu API 8), a ten typ czujnika został wycofany w Androidzie 4.4W (poziom interfejsu API 20).

Czujniki pozycji przydają się do określania fizycznej pozycji urządzenia w odniesieniu do świata. Na przykład w połączeniu z akcelerometrem można użyć czujnika pola geomagnetycznego, aby określić położenie urządzenia względem magnetycznego bieguna północnego. Możesz ich też używać do określania orientacji urządzenia w odniesieniu do aplikacji. Czujniki pozycji zwykle nie są używane do monitorowania ruchu urządzenia, takiego jak drżenie, pochylenie czy ruch (więcej informacji znajdziesz w sekcji Czujniki ruchu).

Czujnik pola geomagnetycznego i akcelerometr zwraca wielowymiarowe macierze wartości z czujników dla każdej wartości w kolumnie SensorEvent. Na przykład czujnik pola geomagnetycznego podaje wartości natężenia pola geomagnetycznego dla każdej z 3 osi współrzędnych podczas pojedynczego zdarzenia z czujnika. Podobnie czujnik akcelerometru mierzy przyspieszenie stosowane do urządzenia podczas zdarzenia związanego z czujnikiem. Więcej informacji o układach współrzędnych używanych przez czujniki znajdziesz w artykule Układy współrzędnych czujnika. Czujnik zbliżeniowy podaje jedną wartość dla każdego zdarzenia z czujnika. W tabeli 1 zestawiamy czujniki pozycji obsługiwane przez platformę Androida.

Tabela 1. Czujniki pozycji obsługiwane przez platformę Android.

Czujnik Dane zdarzeń z czujnika Opis Jednostki miary
TYPE_GAME_ROTATION_VECTOR SensorEvent.values[0] Składnik wektora obrotu wzdłuż osi x (x * sin(≠s/2)). Bezsznurkowe
SensorEvent.values[1] Składnik wektora obrotu wzdłuż osi y (y * sin(kolejnej)).
SensorEvent.values[2] Składnik wektora obrotu wzdłuż osi z (z * sin(≠s/2)).
TYPE_GEOMAGNETIC_ROTATION_VECTOR SensorEvent.values[0] Składnik wektora obrotu wzdłuż osi x (x * sin(≠s/2)). Bezsznurkowe
SensorEvent.values[1] Składnik wektora obrotu wzdłuż osi y (y * sin(kolejnej)).
SensorEvent.values[2] Składnik wektora obrotu wzdłuż osi z (z * sin(≠s/2)).
TYPE_MAGNETIC_FIELD SensorEvent.values[0] Siła pola geomagnetycznego wzdłuż osi X. μT
SensorEvent.values[1] Siła pola geomagnetycznego na osi Y.
SensorEvent.values[2] Siła pola geomagnetycznego wzdłuż osi Z.
TYPE_MAGNETIC_FIELD_UNCALIBRATED SensorEvent.values[0] Natężenie pola geomagnetycznego (bez kalibracji żelaza) wzdłuż osi x. μT
SensorEvent.values[1] Natężenie pola geomagnetycznego (bez kalibracji żelaza) wzdłuż osi Y.
SensorEvent.values[2] Natężenie pola geomagnetycznego (bez kalibracji żelaza) wzdłuż osi Z.
SensorEvent.values[3] Szacowane odchylenie żelaza na osi X.
SensorEvent.values[4] Szacowane odchylenie żelaza na osi Y.
SensorEvent.values[5] Szacowane odchylenie żelaza na osi Z.
TYPE_ORIENTATION1 SensorEvent.values[0] Azymut (kąt wokół osi Z). Stopnie
SensorEvent.values[1] Ton (kąt wokół osi X).
SensorEvent.values[2] Obróć (kąt wokół osi Y).
TYPE_PROXIMITY SensorEvent.values[0] Odległość od obiektu2. cm

1Ten czujnik został wycofany w Androidzie 2.2 (poziom interfejsu API 8), a w Androidzie 4.4W (poziom interfejsu API 20) został wycofany. Struktura czujników udostępnia alternatywne metody uzyskiwania orientacji urządzenia, które zostały omówione w sekcji Obliczanie orientacji urządzenia.

2 Niektóre czujniki zbliżeniowe podają tylko wartości binarne reprezentujące najbliższe i dalej.

Użyj czujnika wektorów obrotu gry

Czujnik obrotu gry jest taki sam jak czujnik wektora obrotu z tą różnicą, że nie korzysta z pola geomagnetycznego. Dlatego oś Y nie jest kierowana na północ, tylko w inne miejsce. To odwołanie może poruszać się o tym samym rzędzie wielkości co dryf żyroskopu wokół osi Z.

Czujnik obrotu gry nie korzysta z pola magnetycznego, dlatego obroty względne są dokładniejsze i nie mają wpływu na zmiany pola magnetycznego. Możesz użyć tego czujnika w grze, jeśli nie interesuje Cię, gdzie jest północ, a normalny wektor obrotu nie zaspokaja Twoich potrzeb ze względu na zależność od pola magnetycznego.

Ten kod pokazuje, jak uzyskać wystąpienie domyślnego czujnika obrotu gry:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);

Użyj czujnika wektorów obrotu geomagnetycznego

Czujnik obrotu geomagnetycznego jest podobny do czujnika wektorów obrotu, ale nie używa żyroskopu. Dokładność tego czujnika jest mniejsza niż w przypadku normalnego czujnika obrotu, ale zużycie energii jest mniejsze. Używaj tego czujnika tylko wtedy, gdy chcesz zbierać informacje o obrotach w tle bez nadmiernego zużywania baterii. Czujnik jest najbardziej przydatny w połączeniu z grupowaniem.

Poniższy kod pokazuje, jak pobrać wystąpienie domyślnego czujnika wektorów obrotu geomagnetycznego:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);

Obliczanie orientacji urządzenia

Obliczając orientację urządzenia, możesz monitorować jego położenie względem względem Ziemi (w szczególności magnetycznego bieguna północnego). Ten kod pokazuje, jak obliczyć orientację urządzenia:

Kotlin

private lateinit var sensorManager: SensorManager
...
// Rotation matrix based on current readings from accelerometer and magnetometer.
val rotationMatrix = FloatArray(9)
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading)

// Express the updated rotation matrix as three orientation angles.
val orientationAngles = FloatArray(3)
SensorManager.getOrientation(rotationMatrix, orientationAngles)

Java

private SensorManager sensorManager;
...
// Rotation matrix based on current readings from accelerometer and magnetometer.
final float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrix(rotationMatrix, null,
    accelerometerReading, magnetometerReading);

// Express the updated rotation matrix as three orientation angles.
final float[] orientationAngles = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationAngles);

System oblicza kąty orientacji, korzystając z czujnika pola geomagnetycznego urządzenia w połączeniu z akcelerometrem. Dzięki tym 2 czujnikom sprzętowym system dostarcza dane dla tych 3 kątów orientacji:

  • Azymut (stopnie obrotu wokół osi -z). Jest to kąt między bieżącym kierunkiem kompasu na urządzeniu a północą magnetyczną. Jeśli górna krawędź urządzenia jest skierowana na północ magnetyczną, azymut wynosi 0 stopni, a górna krawędź urządzenia jest skierowana na południe, a azymut wynosi 180 stopni. I podobnie, jeśli górna krawędź jest skierowana na wschód, azymut wynosi 90 stopni, a jeśli górna krawędź jest ustawiona na zachód, azymut wynosi 270 stopni.
  • Pochylenie (stopnie obrotu wokół osi X). Jest to kąt między płaszczyzną równoległą do ekranu urządzenia a płaszczyzną równoległą do ziemi. Jeśli będziesz trzymać urządzenie równolegle do ziemi, tak aby jego dolna krawędź była najbliżej Ciebie, i przechylić górną krawędź urządzenia do ziemi, kąt nachylenia będzie dodatni. Pochylenie w przeciwnym kierunku, czyli odsunięcie górnej krawędzi urządzenia od ziemi powoduje, że kąt nachylenia urządzenia jest ujemny. Zakres wartości wynosi od -90 do 90 stopni.
  • Obrót (stopnie obrotu wokół osi Y). Jest to kąt między płaszczyzną prostopadłą do ekranu urządzenia a płaszczyzną prostopadłą do ziemi. Jeśli będziesz trzymać urządzenie równolegle do ziemi, tak aby jego dolna krawędź była najbliżej Ciebie, i przechylić lewą krawędź urządzenia w stronę ziemi, kąt obrotu będzie dodatni. Przechylenie urządzenia w przeciwnym kierunku, czyli przesunięcie prawej krawędzi urządzenia w kierunku ziemi, powoduje, że kąt obrotu staje się ujemny. Zakres wartości wynosi od -180 do 180 stopni.

Uwaga: definicja przesuwania czujnika zmieniła się, aby odzwierciedlić większość implementacji w ekosystemie geoczujników.

Zwróć uwagę, że te kąty działają w zależności od innego układu współrzędnych niż ten używany w lotnictwie (do odchylenia, nachylenia i obrotu). W systemie lotniczym oś X jest wzdłuż dłuższej krawędzi samolotu, od ogona do nosa.

Czujnik orientacji pobiera swoje dane, przetwarzając nieprzetworzone dane z czujnika akcelerometru i czujnika pola geomagnetycznego. Ze względu na intensywny proces przetwarzania dokładność i precyzja czujnika orientacji są zmniejszane. Ten czujnik działa niezawodnie tylko wtedy, gdy kąt obrócenia wynosi 0. Z tego powodu wycofaliśmy czujnik orientacji w Androidzie 2.2 (poziom interfejsu API 8), a ten typ czujnika został wycofany w Androidzie 4.4W (poziom interfejsu API 20). Zamiast nieprzetworzonych danych z czujnika orientacji zalecamy używanie metody getRotationMatrix() w połączeniu z metodą getOrientation() do obliczania wartości orientacji, jak pokazano w tym przykładowym kodzie. W ramach tego procesu możesz użyć metody remapCoordinateSystem(), aby przetłumaczyć wartości orientacji na wzorzec aplikacji.

Kotlin

class SensorActivity : Activity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private val accelerometerReading = FloatArray(3)
    private val magnetometerReading = FloatArray(3)

    private val rotationMatrix = FloatArray(9)
    private val orientationAngles = FloatArray(3)

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
        // You must implement this callback in your code.
    }

    override fun onResume() {
        super.onResume()

        // Get updates from the accelerometer and magnetometer at a constant rate.
        // To make batch operations more efficient and reduce power consumption,
        // provide support for delaying updates to the application.
        //
        // In this example, the sensor reporting delay is small enough such that
        // the application receives an update before the system checks the sensor
        // readings again.
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also { accelerometer ->
            sensorManager.registerListener(
                    this,
                    accelerometer,
                    SensorManager.SENSOR_DELAY_NORMAL,
                    SensorManager.SENSOR_DELAY_UI
            )
        }
        sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also { magneticField ->
            sensorManager.registerListener(
                    this,
                    magneticField,
                    SensorManager.SENSOR_DELAY_NORMAL,
                    SensorManager.SENSOR_DELAY_UI
            )
        }
    }

    override fun onPause() {
        super.onPause()

        // Don't receive any more updates from either sensor.
        sensorManager.unregisterListener(this)
    }

    // Get readings from accelerometer and magnetometer. To simplify calculations,
    // consider storing these readings as unit vectors.
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
        } else if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
        }
    }

    // Compute the three orientation angles based on the most recent readings from
    // the device's accelerometer and magnetometer.
    fun updateOrientationAngles() {
        // Update rotation matrix, which is needed to update orientation angles.
        SensorManager.getRotationMatrix(
                rotationMatrix,
                null,
                accelerometerReading,
                magnetometerReading
        )

        // "rotationMatrix" now has up-to-date information.

        SensorManager.getOrientation(rotationMatrix, orientationAngles)

        // "orientationAngles" now has up-to-date information.
    }
}

Java

public class SensorActivity extends Activity implements SensorEventListener {

    private SensorManager sensorManager;
    private final float[] accelerometerReading = new float[3];
    private final float[] magnetometerReading = new float[3];

    private final float[] rotationMatrix = new float[9];
    private final float[] orientationAngles = new float[3];

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
        // You must implement this callback in your code.
    }

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

        // Get updates from the accelerometer and magnetometer at a constant rate.
        // To make batch operations more efficient and reduce power consumption,
        // provide support for delaying updates to the application.
        //
        // In this example, the sensor reporting delay is small enough such that
        // the application receives an update before the system checks the sensor
        // readings again.
        Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometer != null) {
            sensorManager.registerListener(this, accelerometer,
                SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        }
        Sensor magneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        if (magneticField != null) {
            sensorManager.registerListener(this, magneticField,
                SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        }
    }

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

        // Don't receive any more updates from either sensor.
        sensorManager.unregisterListener(this);
    }

    // Get readings from accelerometer and magnetometer. To simplify calculations,
    // consider storing these readings as unit vectors.
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
          System.arraycopy(event.values, 0, accelerometerReading,
              0, accelerometerReading.length);
        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, magnetometerReading,
                0, magnetometerReading.length);
        }
    }

    // Compute the three orientation angles based on the most recent readings from
    // the device's accelerometer and magnetometer.
    public void updateOrientationAngles() {
        // Update rotation matrix, which is needed to update orientation angles.
        SensorManager.getRotationMatrix(rotationMatrix, null,
            accelerometerReading, magnetometerReading);

        // "rotationMatrix" now has up-to-date information.

        SensorManager.getOrientation(rotationMatrix, orientationAngles);

        // "orientationAngles" now has up-to-date information.
    }
}

Zwykle nie ma potrzeby przetwarzania ani filtrowania surowej orientacji urządzenia z wyjątkiem przekształcenia układu współrzędnych czujnika w punkt odniesienia aplikacji.

Użyj czujnika pola geomagnetycznego

Czujnik pola magnetycznego umożliwia monitorowanie zmian w polu magnetycznym Ziemi. Ten kod pokazuje, jak uzyskać wystąpienie domyślnego czujnika pola geomagnetycznego:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

Uwaga: jeśli aplikacja jest kierowana na Androida 12 (poziom interfejsu API 31) lub wyższe, czujnik ma ograniczoną częstotliwość.

Dostarcza on nieprzetworzone dane o natężeniu pola (w μT) dla każdej z 3 osi współrzędnych. Zwykle nie trzeba używać tego czujnika bezpośrednio. Zamiast tego możesz użyć czujnika wektora obrotowego, aby określić nieprzetworzony ruch obrotowy, lub czujnika akcelerometru i pola geomagnetycznego w połączeniu z metodą getRotationMatrix(), aby uzyskać macierz obracania i macierz nachylenia. Możesz następnie używać tych macierzy w połączeniu z metodami getOrientation() i getInclination(), aby uzyskać dane dotyczące azymutu i pochylenia geomagnetycznego.

Uwaga: podczas testowania aplikacji możesz poprawić dokładność czujnika, pomachając urządzeniem w wzór 8-8.

Używanie nieskalibrowanego magnetometru

Nieskalibrowany magnetometr jest podobny do czujnika pola geomagnetycznego, z tym że do pola magnetycznego nie stosuje się kalibracji twardego żelaza. Pole magnetyczne korzysta z kalibracji fabrycznej i kompensacji temperatury. Nieskalibrowany magnetometr przydaje się do szacowania niewłaściwego poziomu twardego żelaza. Ogólnie geomagneticsensor_event.values[0] będzie zbliżony do uncalibrated_magnetometer_event.values[0] - uncalibrated_magnetometer_event.values[3]. Oznacza to, że

calibrated_x ~= uncalibrated_x - bias_estimate_x

Uwaga: nieskalibrowane czujniki dają więcej surowych wyników i mogą zawierać pewne odchylenia, ale ich pomiary zawierają mniej przeskoków spowodowanych korekcją za pomocą kalibracji. Niektóre aplikacje mogą preferować takie nieskalibrowane wyniki, ponieważ są one płynniejsze i bardziej wiarygodne. Jeśli na przykład aplikacja próbuje przeprowadzić własną fuzję czujników, wprowadzenie kalibracji może zniekształcać wyniki.

Oprócz pola magnetycznego nieskalibrowany magnetometr dostarcza też szacunkowe odchylenia twardego żelaza na każdej osi. Poniższy kod pokazuje, jak pobrać wystąpienie domyślnego nieskalibrowanego magnetometru:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);

Użyj czujnika zbliżeniowego

Czujnik zbliżeniowy pozwala określić, jak daleko od urządzenia znajduje się obiekt. Ten kod pokazuje, jak uzyskać wystąpienie domyślnego czujnika zbliżeniowego:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

Czujnik zbliżeniowy jest zwykle używany do określenia, jak daleko znajduje się głowa użytkownika od twarzy urządzenia (np. gdy użytkownik nawiązuje lub odbiera połączenie telefoniczne). Większość czujników zbliżeniowych zwraca odległość bezwzględną w cm, ale niektóre zwracają tylko wartości zbliżone i duże.

Uwaga: w niektórych modelach urządzeń czujnik zbliżeniowy znajduje się pod ekranem, co może powodować wyświetlanie na ekranie migającej kropki, gdy ekran jest włączony.

Ten kod pokazuje, jak korzystać z czujnika zbliżeniowego:

Kotlin

class SensorActivity : Activity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private var proximity: Sensor? = null

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
    }

    override fun onSensorChanged(event: SensorEvent) {
        val distance = event.values[0]
        // Do something with this sensor data.
    }

    override fun onResume() {
        // Register a listener for the sensor.
        super.onResume()

        proximity?.also { proximity ->
            sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}

Java

public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor proximity;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        float distance = event.values[0];
        // Do something with this sensor data.
    }

    @Override
    protected void onResume() {
        // Register a listener for the sensor.
        super.onResume();
        sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL);
      }

    @Override
    protected void onPause() {
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

Uwaga: niektóre czujniki zbliżeniowe zwracają wartości binarne, które reprezentują „bliską” lub „dużą odległość”. W takim przypadku czujnik zwykle przekazuje maksymalną wartość zakresu w stanie odległym, a mniejszą w stanie bliskim. Zazwyczaj odległa wartość wynosi więcej niż 5 cm, ale może być różna w zależności od czujnika. Maksymalny zasięg czujnika możesz określić, korzystając z metody getMaximumRange().

Przeczytaj też