Platforma Android udostępnia 2 czujniki, które umożliwiają określenie położenia urządzenia: czujnik pola geomagnetycznego i akcelerometr. Platforma Android udostępnia też czujnik, który pozwala określić, jak blisko obiektu znajduje się przednia część urządzenia (tzw. czujnik zbliżeniowy). Czujnik pola geomagnetycznego i czujnik zbliżeniowy są oparte na sprzęcie. Większość producentów telefonów i tabletów instaluje czujnik pola geomagnetycznego. Podobnie producenci telefonów zwykle umieszczają w nich czujnik zbliżeniowy, który wykrywa, kiedy telefon jest trzymany blisko twarzy użytkownika (np. podczas rozmowy telefonicznej). Do określania 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 typ czujnika orientacji został wycofany w Androidzie 4.4W (poziom interfejsu API 20).
Czujniki położenia przydają się do określania fizycznego położenia urządzenia w odniesieniu do ś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 północy magnetycznej. Możesz też używać tych czujników do określania orientacji urządzenia w ramach odniesienia aplikacji. Czujniki położenia nie są zwykle używane do monitorowania ruchu urządzenia, np. wstrząsów, przechyleń czy pchnięć (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 dostarcza wartości siły pola geomagnetycznego dla każdej z 3 osi współrzędnych podczas jednego zdarzenia czujnika. Podobnie akcelerometr mierzy przyspieszenie działające na urządzenie podczas zdarzenia czujnika. 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 podaje jedną wartość dla każdego zdarzenia czujnika. W tabeli 1 znajdziesz podsumowanie czujników pozycji obsługiwanych na platformie Android.
Tabela 1. czujniki położenia obsługiwane na platformie Android;
| Czujnik | Dane zdarzeń z czujników | Opis | Jednostki miary |
|---|---|---|---|
TYPE_GAME_ROTATION_VECTOR |
SensorEvent.values[0] |
Składowa wektora obrotu wzdłuż osi X (x * sin(θ/2)). | Bez jednostek |
SensorEvent.values[1] |
Składowa wektora obrotu wzdłuż osi y (y * sin(θ/2)). | ||
SensorEvent.values[2] |
Składowa wektora obrotu na osi z (z * sin(θ/2)). | ||
TYPE_GEOMAGNETIC_ROTATION_VECTOR |
SensorEvent.values[0] |
Składowa wektora obrotu wzdłuż osi X (x * sin(θ/2)). | Bez jednostek |
SensorEvent.values[1] |
Składowa wektora obrotu wzdłuż osi y (y * sin(θ/2)). | ||
SensorEvent.values[2] |
Składowa wektora obrotu na osi z (z * sin(θ/2)). | ||
TYPE_MAGNETIC_FIELD |
SensorEvent.values[0] |
Natężenie pola geomagnetycznego wzdłuż osi X. | μT |
SensorEvent.values[1] |
Natężenie pola geomagnetycznego wzdłuż osi y. | ||
SensorEvent.values[2] |
Natężenie pola geomagnetycznego wzdłuż 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] |
Szacowanie odchylenia żelaza wzdłuż osi x. | ||
SensorEvent.values[4] |
Szacowanie odchylenia żelaza wzdłuż osi Y. | ||
SensorEvent.values[5] |
Szacowanie odchylenia żelaza wzdłuż osi z. | ||
TYPE_ORIENTATION1 |
SensorEvent.values[0] |
Azymut (kąt wokół osi Z). | Stopnie |
SensorEvent.values[1] |
Pochylenie (kąt wokół osi X). | ||
SensorEvent.values[2] |
Przechylenie (kąt wokół osi Y). | ||
TYPE_PROXIMITY |
SensorEvent.values[0] |
Odległość od obiektu2 | cm |
1 Ten czujnik został wycofany w Androidzie 2.2 (interfejs API na poziomie 8), a ten typ czujnika został wycofany w Androidzie 4.4W (interfejs API na poziomie 20). Platforma czujników udostępnia alternatywne metody uzyskiwania orientacji urządzenia, które zostały omówione w rozdziale 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 rotacji gry
Czujnik wektora obrotu gry jest identyczny z czujnikiem wektora obrotu, z tym że nie korzysta z pola geomagnetycznego. Dlatego oś Y nie jest skierowana na północ, ale w innym kierunku. Odchylenie od tego punktu odniesienia może być tego samego rzędu co odchylenie żyroskopu wokół osi Z.
Czujnik wektora obrotu gry nie korzysta z pola magnetycznego, więc względne obroty są dokładniejsze i nie mają na nie wpływu zmiany pola magnetycznego. Użyj tego czujnika w grze, jeśli nie zależy Ci na tym, gdzie jest północ, a normalny wektor rotacji nie spełnia Twoich potrzeb ze względu na zależność od pola magnetycznego.
Poniższy kod pokazuje, jak uzyskać instancję domyślnego czujnika wektora rotacji 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 korzysta z żyroskopu. Dokładność tego czujnika jest mniejsza niż w przypadku zwykłego czujnika wektora rotacji, ale zużycie energii jest mniejsze. Używaj tego czujnika tylko wtedy, gdy chcesz zbierać informacje o obrocie w tle bez nadmiernego zużywania baterii. Ten czujnik jest najbardziej przydatny w połączeniu z grupowaniem.
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 monitorować jego położenie względem układu odniesienia Ziemi (a konkretnie magnetycznego bieguna północnego). 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 za pomocą czujnika pola geomagnetycznego urządzenia w połączeniu z akcelerometrem urządzenia. System wykorzystuje te 2 czujniki sprzętowe do podawania danych dotyczących tych 3 kątów orientacji:
- Azymut (stopnie obrotu wokół osi –z). Jest to kąt między bieżącym kierunkiem kompasu urządzenia a północą magnetyczną. Jeśli górna krawędź urządzenia jest skierowana na północ magnetyczną, azymut wynosi 0 stopni, a jeśli jest skierowana na południe – 180 stopni. Podobnie, jeśli górna krawędź jest skierowana na wschód, azymut wynosi 90 stopni, a jeśli jest skierowana na zachód – 270 stopni.
- Pochylenie (kąt obrotu wokół osi X w stopniach). 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 podłoża, a dolna krawędź jest skierowana w Twoją stronę, i przechylisz górną krawędź urządzenia w kierunku podłoża, kąt pochylenia będzie dodatni. Przechylenie w przeciwnym kierunku – przesunięcie górnej krawędzi urządzenia w górę – powoduje, że kąt nachylenia staje się ujemny. Zakres wartości wynosi od -90 do 90 stopni.
- Przechylenie (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 podłoża, a dolna krawędź jest skierowana w Twoją stronę, i przechylisz lewą krawędź urządzenia w kierunku podłoża, kąt przechyłu będzie dodatni. Przechylenie w przeciwnym kierunku – przesunięcie prawej krawędzi urządzenia w stronę podłoża – powoduje, że kąt przechyłu staje się ujemny. Zakres wartości wynosi od -180 do 180 stopni.
Uwaga: definicja obrotu czujnika została zmieniona, aby odzwierciedlać zdecydowaną większość implementacji w ekosystemie czujników geograficznych.
Pamiętaj, że te kąty działają w innym układzie współrzędnych niż ten używany w lotnictwie (w przypadku odchylenia, pochylenia i przechylenia). W systemie lotniczym oś X przebiega wzdłuż dłuższego boku samolotu, od ogona do nosa.
Czujnik orientacji uzyskuje dane z czujnika, przetwarzając nieprzetworzone dane z akcelerometru i czujnika pola geomagnetycznego. Ze względu na duże obciążenie procesora dokładność i precyzja czujnika orientacji są mniejsze. W szczególności ten czujnik jest wiarygodny tylko wtedy, gdy kąt przechyłu 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.4W (poziom interfejsu API 20).
Zamiast używać surowych 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 układ 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 musisz przetwarzać ani filtrować surowych kątów orientacji urządzenia, poza przetłumaczeniem układu współrzędnych czujnika na układ odniesienia aplikacji.
Korzystanie z czujnika pola geomagnetycznego
Czujnik pola geomagnetycznego umożliwia monitorowanie zmian w polu magnetycznym 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 ma ograniczoną częstotliwość.
Ten czujnik dostarcza surowe dane o sile pola (w μT) dla każdej z 3 osi współrzędnych.
Zwykle nie musisz używać tego czujnika bezpośrednio. Zamiast tego możesz użyć czujnika wektora rotacji
, aby określić surowy ruch obrotowy, lub użyć akcelerometru i czujnika pola geomagnetycznego w połączeniu z metodą getRotationMatrix(), aby uzyskać macierz rotacji i macierz nachylenia. Następnie możesz użyć tych macierzy z metodami getOrientation() i getInclination(), aby uzyskać dane o azymucie i inklinacji geomagnetycznej.
Uwaga: podczas testowania aplikacji możesz zwiększyć dokładność czujnika, wykonując urządzeniem ruchy w kształcie ósemki.
Używanie niekalibrowanego magnetometru
Nie skalibrowany magnetometr jest podobny do czujnika pola geomagnetycznego, z tym że do pola magnetycznego nie jest stosowana kalibracja twardego żelaza. Kalibracja fabryczna i kompensacja temperatury są nadal stosowane do pola magnetycznego. Nie skalibrowany magnetometr przydaje się w przypadku nieprawidłowych szacunków twardego żelaza. Ogólnie rzecz biorąc, geomagneticsensor_event.values[0]
będzie zbliżone do uncalibrated_magnetometer_event.values[0] -
uncalibrated_magnetometer_event.values[3]. Oznacza to, że
calibrated_x ~= uncalibrated_x - bias_estimate_x
Uwaga: niekalibrowane czujniki dostarczają bardziej surowe wyniki i mogą zawierać pewne odchylenia, ale ich pomiary zawierają mniej skoków wynikających z korekt stosowanych podczas kalibracji. Niektóre aplikacje mogą preferować te niekalibrowane wyniki, ponieważ są one bardziej płynne i 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 niekalibrowany magnetometr podaje też szacunkowe odchylenie spowodowane przez twarde żelazo na każdej osi. Poniższy kod pokazuje, jak uzyskać instancję domyślnego niekalibrowanego 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ć, jak daleko obiekt znajduje się 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 jest zwykle używany do określania odległości głowy od przedniej części urządzenia (np. podczas rozmowy telefonicznej). Większość czujników zbliżeniowych zwraca odległość bezwzględną w centymetrach, ale niektóre zwracają tylko wartości „blisko” i „daleko”.
Uwaga: w niektórych modelach urządzeń czujnik zbliżeniowy znajduje się pod ekranem, co może powodować miganie kropki na ekranie, jeśli 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 zgłasza maksymalną wartość zakresu w stanie dalekim i mniejszą wartość w stanie bliskim. Zwykle wartość daleka jest większa niż 5 cm, ale może się różnić w zależności od czujnika. Maksymalny zasięg czujnika możesz określić za pomocą metody getMaximumRange().