Czujniki pozycji

Platforma Android ma 2 czujniki, które umożliwiają określenie pozycji urządzenia: czujnik pola geomagnetycznego i akcelerometr. Platforma Android ma też czujnik, który pozwala określić, jak blisko obiektu znajduje się twarz urządzenia (tzw. czujnik zbliżeniowy). Czujnik pola geomagnetycznego i czujnik zbliżeniowy działają sprzętowo. Większość producentów telefonów i tabletów jest wyposażona w czujnik pola geomagnetycznego. Producenci telefonów zwykle uwzględniają też czujnik zbliżeniowy, który pozwala określić, kiedy użytkownik jest zbliżony do twarzy (na przykład podczas rozmowy telefonicznej). Aby określić orientację urządzenia, możesz skorzystać z odczytów z akcelerometru urządzenia i czujnika pola geomagnetycznego.

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

Czujniki pozycji są przydatne do określania fizycznego położenia urządzenia w światowym układzie odniesienia. Możesz na przykład użyć czujnika pola geomagnetycznego w połączeniu z akcelerometrem, aby określić położenie urządzenia względem magnetycznego bieguna północnego. Możesz również używać tych czujników do określenia orientacji urządzenia w układzie odniesienia aplikacji. Czujniki pozycji nie są zwykle używane do monitorowania ruchu lub ruchu urządzenia, np. drżenia, przechylenia lub ciągu (więcej informacji znajdziesz w sekcji Czujniki ruchu).

Czujnik pola geomagnetycznego i akcelerometr zwraca wielowymiarowe tablice wartości z czujników dla każdego elementu SensorEvent. Na przykład w trakcie pojedynczego zdarzenia czujnika czujnik pola geomagnetycznego podaje wartości siły pola geomagnetycznego dla każdej z 3 osi współrzędnych. Podobnie czujnik akcelerometru mierzy przyspieszenie stosowane do urządzenia podczas jego zdarzenia. Więcej informacji o układach współrzędnych używanych przez czujniki znajdziesz w artykule Układy współrzędnych czujników. Czujnik zbliżeniowy dostarcza 1 wartość dla każdego zdarzenia. W tabeli 1 znajdziesz podsumowanie czujników pozycji obsługiwanych przez platformę Android.

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

Czujnik Dane zdarzenia z czujnika Opis Jednostki miary
TYPE_GAME_ROTATION_VECTOR SensorEvent.values[0] Składnik wektora obrotu na osi x (x * sin(Możliwość)). Wielkości bezwymiarowe
SensorEvent.values[1] Składowa wektora obrotu wzdłuż osi y (y * sin(Możliwość kliknięcia/2)).
SensorEvent.values[2] Składowa wektora obrotu wzdłuż osi z (z * sin(Place/2)).
TYPE_GEOMAGNETIC_ROTATION_VECTOR SensorEvent.values[0] Składnik wektora obrotu na osi x (x * sin(Możliwość)). Wielkości bezwymiarowe
SensorEvent.values[1] Składowa wektora obrotu wzdłuż osi y (y * sin(Możliwość kliknięcia/2)).
SensorEvent.values[2] Składowa wektora obrotu wzdłuż osi z (z * sin(Place/2)).
TYPE_MAGNETIC_FIELD SensorEvent.values[0] Siła pola geomagnetycznego na osi x. μT
SensorEvent.values[1] Siła pola geomagnetycznego na osi Y.
SensorEvent.values[2] Siła pola geomagnetycznego na osi Z.
TYPE_MAGNETIC_FIELD_UNCALIBRATED SensorEvent.values[0] Siła pola geomagnetycznego (bez kalibracji twardego żelaza) wzdłuż osi X. μT
SensorEvent.values[1] Siła pola geomagnetycznego (bez kalibracji twardego żelaza) wzdłuż osi Y.
SensorEvent.values[2] Siła pola geomagnetycznego (bez kalibracji twardego ż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] Wysokość (kąt wokół osi X).
SensorEvent.values[2] Przesunięcie (kąt wokół osi Y).
TYPE_PROXIMITY SensorEvent.values[0] Odległość od obiektu2. cm

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

2 Niektóre czujniki zbliżeniowe podają tylko wartości binarne reprezentujące obszary z bliska i daleka.

Użyj czujnika wektorów obrotu gry

Czujnik wektora obrotu gry jest taki sam jak czujnik wektorów obrotowych, ale nie korzysta z pola geomagnetycznego. Dlatego oś Y nie wskazuje północy, ale wskazuje inne źródło. To odniesienie może dryfować w tym samym rzędzie wielkości, co żyroskop przesuwa się wokół osi Z.

Czujnik wektora obrotu gry nie korzysta z pola magnetycznego, dlatego rotacje względne są dokładniejsze i nie wpływają na nie zmiany pola magnetycznego. Wykorzystaj ten czujnik w grze, jeśli nie ma dla Ciebie znaczenia, gdzie jest północ, a wektor obrotu normalnego nie odpowiada Twoim potrzebom, ponieważ zależy od pola magnetycznego.

Ten kod pokazuje, jak uzyskać wystąpienie domyślnego wektora 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 wektora obrotu geomagnetycznego

Geomagnetyczny czujnik wektorów obrotu jest podobny do czujnika wektora obrotowego, ale nie korzysta z żyroskopu. Dokładność czujnika jest mniejsza niż w przypadku normalnego wektora obrotu, ale zużycie energii jest niższe. Używaj tego czujnika tylko wtedy, gdy chcesz zbierać informacje o obróceniu w tle bez zużywania zbyt dużej baterii. Ten czujnik jest najbardziej przydatny w połączeniu z grupowaniem.

Poniższy kod pokazuje, jak pobrać instancję 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);

Oblicz orientację urządzenia

Obliczając orientację urządzenia, można monitorować jego położenie względem układu odniesienia Ziemi (a 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 za pomocą czujnika pola geomagnetycznego urządzenia w połączeniu z akcelerometrem urządzenia. Za pomocą tych 2 czujników sprzętowych system dostarcza dane dotyczące 3 kątów orientacji:

  • Azymut (stopnie obrotu wokół osi -z). To kąt między obecnym kierunkiem kompasu urządzenia a północną magnetyczną. Jeśli górna krawędź urządzenia jest skierowana na północ magnetyczną, azymut wynosi 0 stopni. Jeśli górna krawędź jest skierowana na południe, azymut wynosi 180 stopni. Podobnie, jeśli górna krawędź jest skierowana na wschód, azymut wynosi 90 stopni, a jeśli górna krawędź jest skierowana na zachód, azymut wynosi 270 stopni.
  • Pochylenie (stopnie obrotu wokół osi X). To kąt między płaszczyzną równoległą do ekranu urządzenia a płaszczyzną równoległą do powierzchni ziemi. Jeśli trzymasz urządzenie równolegle do ziemi, a dolna krawędź znajduje się najbliżej Ciebie, i przechylisz górną krawędź urządzenia w kierunku podłogi, kąt nachylenia będzie dodatni. Przechylanie urządzenia w przeciwną stronę (czyli odsunięcie górnej krawędzi urządzenia od ziemi) powoduje, że kąt nachylenia urządzenia staje się ujemny. Zakres wartości wynosi od –90 do 90 stopni.
  • Obróć (stopnie obrotu wokół osi Y). To kąt między płaszczyzną prostopadłą do ekranu urządzenia a płaszczyzną prostopadłą do ziemi. Jeśli trzymasz urządzenie równolegle do ziemi, a dolna krawędź znajduje się najbliżej Ciebie, i przechylisz lewą krawędź urządzenia w kierunku podłoża, kąt obrotu urządzenia stanie się dodatni. Przechylanie urządzenia w przeciwnym kierunku – przesuwanie prawej krawędzi urządzenia w kierunku podłogi – powoduje, że kąt obrotu urządzenia staje się ujemny. Zakres wartości wynosi od -180 do 180 stopni.

Uwaga: definicja obrócenia czujnika została zmieniona, aby odzwierciedlić większość implementacji w ekosystemie geoczujników.

Pamiętaj, że kąty te działają w innym układzie współrzędnych niż ten używany w lotnictwie (do odchylenia, przechylenia i obrócenia). W systemie lotniczym oś X jest wzdłuż dłuższej strony samolotu, od ogona do nosa.

Czujnik orientacji pobiera dane, przetwarzając nieprzetworzone dane z akcelerometru i czujnika pola geomagnetycznego. Z powodu dużego przetwarzania dokładność i precyzja czujnika orientacji jest niższa. Czujnik jest wiarygodny tylko wtedy, gdy kąt obrotu wynosi 0. W związku z tym czujnik orientacji został wycofany w Androidzie 2.2 (poziom interfejsu API 8), a typ czujnika orientacji został wycofany w Androidzie 4.4 W (poziom API 20). Zamiast używać nieprzetworzonych danych z czujnika orientacji, do obliczania wartości orientacji zalecamy użycie metody getRotationMatrix() w połączeniu z metodą getOrientation(), jak pokazano w poniższym przykładowym kodzie. W ramach tego procesu możesz użyć metody remapCoordinateSystem() do przetłumaczenia wartości orientacji na ramki odniesienia 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.
    }
}

Zazwyczaj nie trzeba przetwarzać ani filtrować nieprzetworzonych danych kątów orientacji urządzenia, poza przetłumaczeniem układu współrzędnych czujnika na układ odniesienia aplikacji.

Użyj czujnika pola geomagnetycznego

Czujnik pola geomagnetycznego umożliwia monitorowanie zmian w polu magnetycznym Ziemi. Poniższy kod pokazuje, jak pobrać instancję 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 Twoja aplikacja jest kierowana na Androida 12 (poziom interfejsu API 31) lub nowszego, czujnik jest ograniczony do szybkości.

Czujnik dostarcza nieprzetworzone dane o sile pola (μT) dla każdej z 3 osi współrzędnych. Zwykle nie trzeba bezpośrednio korzystać z czujnika. Zamiast tego możesz użyć czujnika wektorów obrotu, aby określić nieprzetworzony ruch obrotowy, lub akcelerometru i czujnika pola geomagnetycznego w połączeniu z metodą getRotationMatrix(), aby uzyskać macierz obrotu i macierzy pochylenia. Następnie możesz użyć tych macierzy wraz z metodami getOrientation() i getInclination(), aby uzyskać dane o azymucie i nachyleniu geomagnetycznym.

Uwaga: podczas testowania aplikacji możesz zwiększyć dokładność wykrywania przez pomachanie urządzeniem zgodnie z rysunkami 8 cyfr.

Użyj nieskalibrowanego magnetometru

Nieskalibrowany magnetometr jest podobny do czujnika pola magnetycznego z tą różnicą, że pole magnetyczne nie jest poddawane kalibracji twardego żelaza. Kalibracja fabryczna i kompensacja temperatury są nadal stosowane do pola magnetycznego. Nieskalibrowany magnetometr przydaje się do wykrywania złych szacunków żelaza. geomagneticsensor_event.values[0] będzie bliska uncalibrated_magnetometer_event.values[0] - uncalibrated_magnetometer_event.values[3]. To znaczy,

calibrated_x ~= uncalibrated_x - bias_estimate_x

Uwaga: nieskalibrowane czujniki dają więcej nieprzetworzonych wyników i mogą uwzględniać pewne odchylenia, ale ich pomiary zawierają mniej skoków po korekcie wprowadzonych przez kalibrację. Niektóre aplikacje mogą preferować te nieskalibrowane wyniki jako płynniejsze i bardziej wiarygodne. Jeśli na przykład aplikacja próbuje przeprowadzić własną fuzję czujników, wprowadzenie kalibracji może zniekształcić wyniki.

Oprócz pola magnetycznego nieskalibrowany magnetometr podaje również szacunkową wartość odchylenia twardego żelaza w każdej osi. Poniższy kod pokazuje, jak uzyskać instancję 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żywaj czujnika zbliżeniowego

Czujnik zbliżeniowy pozwala określić odległość obiektu od urządzenia. Poniższy kod pokazuje, jak uzyskać instancję 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 zwykle określa odległość głowy użytkownika od twarzy telefonu (na przykład, gdy użytkownik wykonuje 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 bliskie i dalekie.

Uwaga: w niektórych modelach urządzeń czujnik zbliżeniowy znajduje się pod ekranem, dlatego na ekranie może wtedy migać migająca kropka, jeśli jest włączony, 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 „w pobliżu” lub „duże”. W takim przypadku czujnik zwykle zgłasza swoją wartość maksymalnego zakresu w stanie „dalekim” i mniejszą wartość w stanie bliskim. Zwykle daleka wartość to wartość >5 cm, ale może się ona różnić w zależności od czujnika. Maksymalny zasięg czujnika można określić za pomocą metody getMaximumRange().

Warto też przeczytać