Czujniki pozycji

Platforma Android udostępnia 2 czujniki umożliwiające 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 są sprzętowe. Większość producentów telefonów i tabletów umieszcza w swoich urządzeniach czujnik pola geomagnetycznego. Podobnie producenci telefonów zwykle instalują czujnik zbliżeniowy, aby określić, czy telefon jest trzymany blisko twarzy użytkownika (np. podczas rozmowy telefonicznej). Do określenia orientacji urządzenia możesz użyć odczytów z akcelerometru 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 fizycznej pozycji urządzenia w układzie odniesienia świata. 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 też używać tych czujników do określania orientacji urządzenia w układ współrzędnych aplikacji. Czujniki położenia nie są zwykle używane do monitorowania ruchu urządzenia, takiego jak potrząsanie, przechylanie czy pchnięcie (więcej informacji znajdziesz w sekcji Czujniki ruchu).

Czujnik pola geomagnetycznego i akcelerometr zwracają wielowymiarowe tablice wartości czujnika dla każdego SensorEvent. Na przykład czujnik pola geomagnetycznego podaje wartości natężenia pola geomagnetycznego dla każdej z 3 osi współrzędnych w ramach pojedynczego zdarzenia czujnika. Podobnie czujnik akcelerometru mierzy przyspieszenie stosowane do urządzenia podczas zdarzenia czujnika. Więcej informacji o systemach współrzędnych używanych przez czujniki znajdziesz w artykule Systemy współrzędnych czujników. Czujnik zbliżeniowy dostarcza pojedynczą wartość dla każdego zdarzenia czujnika. Tabela 1 zawiera podsumowanie czujników pozycji obsługiwanych na platformie Android.

Tabela 1. Czujniki położenia obsługiwane na platformie 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ść kliknięcia/2)). bez jednostek
SensorEvent.values[1] Składowa wektora obrotu wzdłuż osi Y (y * sin(Możliwość kliknięcia/2)).
SensorEvent.values[2] Składnik wektora obrotu wzdłuż osi z (z * sin(θ/2)).
TYPE_GEOMAGNETIC_ROTATION_VECTOR SensorEvent.values[0] Składnik wektora obrotu wzdłuż osi X (x * sin(θ/2)). bez jednostek
SensorEvent.values[1] Składowa wektora obrotu wzdłuż osi Y (y * sin(Możliwość kliknięcia/2)).
SensorEvent.values[2] Składnik wektora obrotu wzdłuż osi z (z * sin(θ/2)).
TYPE_MAGNETIC_FIELD SensorEvent.values[0] Natężenie pola geomagnetycznego na osi X. μT
SensorEvent.values[1] Natężenie pola geomagnetycznego wzdłuż osi y.
SensorEvent.values[2] Natężenie 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] Natężenie pola geomagnetycznego (bez kalibracji na twardym żelazie) wzdłuż osi y.
SensorEvent.values[2] Natężenie pola geomagnetycznego (bez kalibracji na twardym żelazie) wzdłuż osi z.
SensorEvent.values[3] Oszacowanie przesunięcia żelaza wzdłuż osi x.
SensorEvent.values[4] Szacowanie przesunięcia żelaza wzdłuż osi y.
SensorEvent.values[5] Oszacowanie przesunięcia w głowicy na osi z.
TYPE_ORIENTATION1 SensorEvent.values[0] azymut (kąt na osi Z). Stopnie
SensorEvent.values[1] Pochylenie (kąt wokół osi X).
SensorEvent.values[2] Przesunięcie (kąt wokół osi Y).
TYPE_PROXIMITY SensorEvent.values[0] Odległość od obiektu.2 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). Framework czujników udostępnia alternatywne metody określania orientacji urządzenia, które są omawiane w sekcji Obliczanie orientacji urządzenia.

2 Niektóre czujniki zbliżeniowe podają tylko wartości binarne, które oznaczają „blisko” i „daleko”.

Korzystanie z czujnika wektora obrotu w grze

Czujnik wektorowy obrotu w grze jest identyczny z czujnikiem wektorowym obrotu, z tym że nie wykorzystuje pola geomagnetycznego. Dlatego oś Y nie wskazuje północy, ale wskazuje inne źródło. Ten punkt odniesienia może się przesuwać o ten sam rząd wielkości co żyroskop wokół osi Z.

Ponieważ czujnik wektorowy obrotu gry nie korzysta z pola magnetycznego, obroty względne są dokładniejsze i nie są zależne od zmian pola magnetycznego. Używaj tego czujnika w grze, jeśli nie zależy Ci na tym, gdzie jest północ, a zwykły wektor obrotu nie spełnia Twoich potrzeb z powodu zależności od pola magnetycznego.

Poniższy kod pokazuje, jak uzyskać instancję domyślnego czujnika 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);

Korzystanie z czujnika wektora obrotu geomagnetycznego

Czujnik wektora obrotu geomagnetycznego jest podobny do czujnika wektora obrotu, ale nie wykorzystuje żyroskopu. Dokładność tego czujnika jest niższa niż w przypadku zwykłego czujnika wektora obrotu, ale zużycie energii jest mniejsze. Używaj tego czujnika tylko wtedy, gdy chcesz zbierać informacje o obrocie w tle bez nadmiernego zużycia baterii. Ten czujnik jest najbardziej przydatny, gdy jest używany w połączeniu z przetwarzaniem zbiorczym.

Poniższy kod pokazuje, jak uzyskać instancję domyślnego czujnika wektora 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 śledzić jego pozycję względem układu odniesienia Ziemi (a w szczególności bieguna magnetycznego). Poniższy 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, używając czujnika pola geomagnetycznego w połączeniu z akcelerometrem urządzenia. Korzystając z tych dwóch czujników sprzętowych, system dostarcza dane dotyczące tych trzech 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. 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 skierowana 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 podłoża. Jeśli trzymasz urządzenie równolegle do ziemi, a jego dolna krawędź jest najbliżej Ciebie, i nachylasz górną krawędź urządzenia w kierunku ziemi, kąt pochylenia staje się 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 to -90 stopni do 90 stopni.
  • Obróć (stopnie obrotu wokół osi Y). Jest to kąt między płaszczyzną prostopadłą do ekranu urządzenia a płaszczyzną prostopadłą do podłoża. Jeśli trzymasz urządzenie równolegle do ziemi, z dolną krawędzią skierowaną w Twoją stronę, a lewą krawędzią nachyloną w kierunku ziemi, kąt przechylenia staje 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 to -180 do 180 stopni.

Uwaga: definicja roli czujnika została zmieniona, aby odzwierciedlić ogromną większość implementacji w ekosystemie geosensoró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 równoległa do dłuższego boku samolotu, od ogona do dziobu.

Czujnik orientacji uzyskuje dane przez przetworzenie nieprzetworzonych danych z czujnika przyspieszenia i czujnika pola geomagnetycznego. Ze względu na intensywne przetwarzanie danych dokładność i precyzja czujnika orientacji jest ograniczona. Ten czujnik jest niezawodny tylko wtedy, gdy kąt przechyłu jest równy 0. W związku z tym czujnik orientacji został wycofany w Androidzie 2.2 (poziom interfejsu API 8), a typ czujnika orientacji – w Androidzie 4.4W (poziom interfejsu API 20). Zamiast używać nieprzetworzonych danych z czujnika orientacji, zalecamy użycie metody getRotationMatrix() w połączeniu z metodą getOrientation() do obliczania wartości orientacji, jak pokazano w tym przykładzie kodu. W ramach tego procesu możesz użyć metody remapCoordinateSystem(), aby przekształcić wartości orientacji w ramach 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.
    }
}

Zwykle nie trzeba przetwarzać ani filtrować surowych kątów orientacji urządzenia, wystarczy przekształcić system współrzędnych czujnika w układ odniesienia aplikacji.

Korzystanie z czujnika pola geomagnetycznego

Czujnik pola geomagnetycznego umożliwia monitorowanie zmian pola magnetycznego Ziemi. Poniższy kod pokazuje, jak uzyskać 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 API 31) lub nowszego, ten czujnik jest ograniczony 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 wektora obrotu, aby określić surowy ruch obrotowy, lub użyć akcelerometru i czujnika pola geomagnetycznego w połączeniu z metodą getRotationMatrix(), aby uzyskać macierz obrotu i macierz pochylenia. Następnie możesz użyć tych macierzy z metodami getOrientation()getInclination(), aby uzyskać dane o azimutach i inklinacji geomagnetycznej.

Uwaga: podczas testowania aplikacji możesz zwiększyć dokładność czujnika, pomachając urządzeniem aż do ósemki.

Korzystanie z nieskalibrowanego magnetometru

Nieskalibrowany magnetometr jest podobny do czujnika pola geomagnetycznego, ale w odróżnieniu od niego nie jest kalibrowany na stałe na potrzeby pola magnetycznego. Kalibracja fabryczna i kompensacja temperatury są nadal stosowane do pola magnetycznego. Nieskalibrowany magnetometr jest przydatny do obsługi złych szacunków twardego żelaza. Ogólnie geomagneticsensor_event.values[0]będzie zbliżone do uncalibrated_magnetometer_event.values[0] - uncalibrated_magnetometer_event.values[3].

calibrated_x ~= uncalibrated_x - bias_estimate_x

Uwaga: nieskalibrowane czujniki zapewniają bardziej surowe wyniki i mogą zawierać pewne odchylenia, ale ich pomiary zawierają mniej skoków wynikających z poprawek wprowadzonych podczas kalibracji. Niektóre aplikacje mogą preferować te nieskalibrowane wyniki, ponieważ są one płynniejsze i bardziej niezawodne. Jeśli na przykład aplikacja próbuje przeprowadzić własną fuzje czujników, wprowadzenie kalibracji może zniekształcić wyniki.

Poza polem magnetycznym nieskalibrowany magnetometr podaje też szacowany współczynnik zniekształcenia na 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);

Korzystanie z czujnika zbliżeniowego

Czujnik zbliżeniowy pozwala określić odległość obiektu od urządzenia. Poniższy kod pokazuje, jak pobrać 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 służy zwykle do określania odległości głowy użytkownika od mikrofonu (np. gdy użytkownik nawiązuje lub odbiera połączenie). Większość czujników zbliżeniowych zwraca bezwzględną odległość w cm, ale niektóre zwracają tylko wartości bliskie i dalekie.

Uwaga: w przypadku niektórych modeli czujnik zbliżeniowy znajduje się pod ekranem, co może powodować miganie kropki na ekranie, jeśli czujnik jest włączony, gdy ekran jest włączony.

Poniższy kod pokazuje, jak używać 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 oznaczają „blisko” lub „daleko”. W takim przypadku czujnik zwykle podaje maksymalną wartość zasięgu w stanie „daleko” i mniejszą wartość w stanie „blisko”. Zazwyczaj daleka wartość to wartość >5 cm, ale może się ona różnić w zależności od czujnika. Maksymalny zasięg czujnika możesz określić, korzystając z metody getMaximumRange().

Przeczytaj też