Working with Sensors
trieda SensorManager
, akcelerometer, senzor magnetického poľa
About
Súčasťou chytrých telefónov sú rozličné senzory. Bežne sa viete stretnúť so zariadeniami, ktoré sú vybavené GPS senzorom, akcelerometrom alebo senzorom intenzity svetla. Dnes sa pozrieme na to, ako k týmto senzorom pristupovať a na dva z nich sa pozrieme zblízka.
Objectives
- zoznámiť sa so správcom senzorov (
SensorManager
) - zistiť zoznam senzorov dostupných na zariadení
- zoznámiť sa s objektom reprezentujúcim senzor
- vytvorenie listener-a pre získavanie dát zo senzora
Postup
Sensor Manager
V prvom kroku vytvoríme kostru aplikácie a vyžiadame si inštanciu triedy SensorManager
.
Úloha
Vytvorte si nový projekt s názvom Compass a v ňom aktivitu s názvom CompassActivity
.
Úloha
V metóde onCreate()
získajte referenciu na inštanciu triedy SensorManager
.
SensorManager
nám pomôže zistiť, aké senzory má zariadenie k dispozícii. Jeho inštanciu získame volaním metódy getSystemService()
a odovzdaním argumentu SENSOR_SERVICE
:
= (SensorManager) getSystemService(Context.SENSOR_SERVICE); SensorManager manager
Úloha
Získajte zoznam všetkých dostupných senzorov, ktoré obsahuje vaše zariadenie.
Zoznam všetkých dostupných senzorov získate volaním metódy getSensorList()
nad objektom SensorManager
-a. Metóda getSensorList()
očakáva konštantu, pomocou ktorej je možné špecifikovať príslušný typ senzoru, napr. TYPE_GYROSCOPE
, TYPE_LINEAR_ACCELERATION
alebo TYPE_GRAVITY
. Ak použijete konštantu TYPE_ALL
, zoznam bude obsahovať všetky senzory, ktoré zariadenie obsahuje. Položky zoznamu budú objekty typu Sensor
.
Poznámka
Uvedené konštanty sa nachádzajú v triede Sensor
.
Úloha
Overte, či sa v zozname senzorov vášho zariadenia nachádza akcelerometer a senzor magnetického poľa.
V prípade, že sa v zozname nachádzajú, z ich referencií vytvorte členské premenné. V prípade, že sa v zozname nenachádzajú, ukončite aplikáciu.
Poznámka
getDefaultSensor()
Monitoring Accelerometer Sensor Events
Akcelerometer meria zrýchlenie v osiach x, y a z. Vďaka nemu vieme zistiť napríklad to, ako je chytré zariadenie natočené, ale rovnako aj aktuálne lineárne zrýchlenie. Aby sme mohli s akcelerometrom pracovať (vo všeobecnosti s ľubovoľným senzorom), potrebujeme sa prihlásiť na odber udalostí, ktoré tento senzor emituje. V tomto kroku sa teda pozrieme na to, ako sa prihlásiť na odber príslušných udalostí a ako následne zobrazovať údaje z akcelerometra.
Úloha
Zabezpečte, aby aktivita CompassActivity
implementovala rozhranie SensorEventListener
.
Poznámka
Implementovaním rozhrania SensorEventListener
implementujete metódy onAccuracyChanged()
a onSensorChanged()
. Android tieto metódy volá vždy, keď:
- A sensor’s accuracy changes.
- A sensor reports a new value.
Úloha
Zaregistrujte listener, aby sme boli notifikovaní pri každej zmene hodnôt akcelerometra.
Registráciu vykonáte volaním metódy registerListener()
nad objektom SensorManager
-a. Hodnotu oneskorenia nastavte na SENSOR_DELAY_NORMAL
.
Poznámka
Je vhodné, aby aktivita počúvala na zmeny len vtedy, keď je zobrazená. Ak nie je zobrazená, tak nemá počúvanie na zmeny v našom prípade význam. Dokonca môže pri použití niektorých iných senzorov viesť k zvýšeniu spotreby batérie. Preto je vhodné, aby sme listener zaregistrovali vtedy, keď sa aktivita zobrazí a odregistrovali ho zasa vtedy, keď aktivita zmizne. Na tento účel sú vhodné metódy onResume()
a onPause()
.
Úloha
V metóde onSensorChanged()
rozhrania SensorEventListener
zapíšte do log-u získané hodnoty z akcelerometra.
Poznámka
Hodnoty si môžete overiť v rozšírených nastaveniach emulátora alebo pomocou niektorej z aplikácií monitorujúcich činnosť senzorov na reálnom zariadení, ako je napr. Sensors Multitool.
Monitoring Magnetic Field Sensor Events
Bežne sa v rámci jednej aplikácie spracovávajú hodnoty z viacerých senzorov ako len z jedného. OS Android umožňuje v rámci jedného listener-a identifikovať aj senzor, ktorý danú udalosť emitoval, čím je možné tento problém jednoducho vyriešiť. Našim druhým senzorom v tomto prípade bude senzor magnetického poľa, pomocou ktorého dokážeme zistiť našu polohu voči severnému pólu.
Úloha
Zaregistrujte listener, aby sme boli upozornení aj na zmeny zo senzora magnetického poľa.
Hodnotu oneskorenia nastavte podobne ako v prípade akcelerometra na SENSOR_DELAY_NORMAL
.
Poznámka
Listener je potrebné zaregistrovať osobitne, pretože sa viaže na typ senzoru. Pri odregistrovaní to už nie je potrebné. Preto stačí upraviť len kód nachádzajúci sa v metóde onResume()
.
Úloha
Aktualizujte metódu onSensorChanged()
tak, aby reflektovala senzor, z ktorého boli údaje získané.
The Device’s Orientation
Na to, aby sme zistili orientáciu zariadenia, využijeme kombináciu získaných hodnôt z akcelerometra a senzora magnetického poľa. OS Android obsahuje aj tzv. softvérový senzor, ktorý nám vie príslušné hodnoty priamo poskytnúť.
Úloha
Medzi zdroje aplikácie si pridajte tento obrázok.
Poznámka
V prípade, že sa vám obrázok nezobrazí na obrazovke vášho zariadenia, zmenšite ho.
Úloha
Upravte si rozloženie aktivity tak, aby ste v nej mali len obrázok kompasu a priestor pre vypísanie azimutu.
Obrázok pomenujte compass
.
Úloha
Upravte si manifest aplikácie tak, aby sa aktivita CompassActivity
neotáčala, ale bola stále fixne orientovaná na stojato.
Otvorte súbor AndroidManifest.xml
a element <activity>
upravte nasledovne:
activity android:name=".CompassActivity" android:screenOrientation="portrait"> <
Úloha
Upravte svoj kód tak, aby do metódy onSensorChanged()
mohli vložiť nasledujúci fragment kódu.
// Rotation matrix based on current readings from accelerometer and magnetometer.
final float[] rotationMatrix = new float[9];
.getRotationMatrix(rotationMatrix, null, this.accValues, this.magValues);
SensorManager
// Express the updated rotation matrix as three orientation angles.
final float[] orientationAngles = new float[3];
.getOrientation(rotationMatrix, orientationAngles);
SensorManager
float azimuth = (float) Math.toDegrees(orientationAngles[0]) % 360;
= new RotateAnimation(
Animation animation this.currentAzimuth,
-azimuth,
.RELATIVE_TO_SELF,
Animation0.5f,
.RELATIVE_TO_SELF,
Animation0.5f
);
// how long the animation will take place
.setDuration(500);
animation
// set the animation after the end of the reservation status
.setFillAfter(true);
animation
this.compass.startAnimation(animation);
this.currentAzimuth = -azimuth;
Úloha
Otestujte správnosť svojej implementácie.
Pokiaľ ste postupovali správne, na obrazovke vášho zariadenia sa zobrazí ružica kompasu, ktorá bude reagovať na zmeny orientácie zariadenia. Rovnako sa podľa zmien orientácie bude aktualizovať aj hodnota azimutu. Overiť správnosť fungovania môžete napr. pomocou aplikácie Sensors Multitool a opticky, nakoľko hodnota azimutu sa musí zhodovať s hodnotou stupňov na ružici kompasu.
Additional Links
Sensors Overview - úvod do práce so senzormi v OS Android
getSystemService()
- Return the handle to a system-level service by name.SensorManager
-SensorManager
lets you access the device’s sensors.getSensorList()
- Use this method to get the list of available sensors of a certain type.getDefaultSensor()
- Use this method to get the default sensor for a given type.SensorEventListener
- Used for receiving notifications from theSensorManager
when there is new sensor data.registerListener()
- Registers aSensorEventListener
for the given sensor at the given sampling frequency.