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). 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 API 8), a typ czujnika orientacji został wycofany w Androidzie 4.4W (poziom API 20).
Czujniki położenia są przydatne 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, które jest przykładane do urządzenia 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 rotacji wzdłuż osi X (x * sin(θ/2)). | Bez jednostek |
SensorEvent.values[1] |
Składowa wektora rotacji wzdłuż osi y (y * sin(θ/2)). | ||
SensorEvent.values[2] |
Składowa wektora rotacji wzdłuż osi z (z * sin(θ/2)). | ||
TYPE_GEOMAGNETIC_ROTATION_VECTOR |
SensorEvent.values[0] |
Składowa wektora rotacji wzdłuż osi X (x * sin(θ/2)). | Bez jednostek |
SensorEvent.values[1] |
Składowa wektora rotacji wzdłuż osi y (y * sin(θ/2)). | ||
SensorEvent.values[2] |
Składowa wektora rotacji wzdłuż 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] |
Obrót (kąt wokół osi Y). | ||
TYPE_PROXIMITY |
SensorEvent.values[0] |
Odległość od obiektu2 | cm |
1 Ten czujnik został wycofany w Androidzie 2.2 (API na poziomie 8), a ten typ czujnika został wycofany w Androidzie 4.4W (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 rotacji gry jest identyczny z czujnikiem wektora rotacji, z wyjątkiem tego, ż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 rotacji gry nie korzysta z pola magnetycznego, więc względne rotacje 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, ponieważ zależy 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 rotacji geomagnetycznej
Czujnik wektora rotacji geomagnetycznej jest podobny do czujnika wektora rotacji, 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 rotacji geomagnetycznej:
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. Dzięki tym 2 czujnikom sprzętowym system dostarcza dane dotyczące 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 (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 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 pochylenia staje się 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 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 to 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 systemie 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 dziobu.
Czujnik orientacji uzyskuje dane, 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ładzie kodu: W ramach tego procesu możesz użyć metody remapCoordinateSystem()
do przetłumaczenia 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, poruszając urządzeniem w kształcie ósemki.
Korzystanie z 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ę do obsługi 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ą więcej surowych wyników 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 ferromagnetyzm w 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, jak daleko głowa osoby znajduje się od przedniej części urządzenia (np. podczas wykonywania lub odbierania połączenia telefonicznego). Większość czujników zbliżeniowych zwraca bezwzględną odległość 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ą getMaximumRange().