Sensors API — είναι η διεπαφή της πλατφόρμας Android για πρόσβαση στους αισθητήρες υλικού της συσκευής. Το API παρέχει έναν ενοποιημένο τρόπο λήψης δεδομένων από το επιταχυνσιόμετρο, γυροσκόπιο, μαγνητόμετρο, αισθητήρα φωτός και άλλους αισθητήρες. Σύμφωνα με τα δεδομένα Google, 2026, περισσότερες από 95% των σύγχρονων συσκευών Android είναι εξοπλισμένες με τουλάχιστον τρεις τύπους αισθητήρων, γεγονός που ανοίγει ευρείες δυνατότητες για την ανάπτυξη εφαρμογών με επίγνωση περιβάλλοντος.
Κύρια Σημεία
Sensors API — είναι η διεπαφή προγραμματισμού του Android Framework, που παρέχει στους προγραμματιστές πρόσβαση στους αισθητήρες υλικού της κινητής συσκευής. Το API αποτελεί μέρος του Android SDK από την έκδοση 1.0 και είναι προσβάσιμο μέσω του πακέτου android.hardware. Η διεπαφή αφαιρεί τις διαφορές μεταξύ των υλοποιήσεων αισθητήρων από διαφορετικούς κατασκευαστές — Qualcomm, MediaTek, Samsung Exynos — και παρέχει ένα ενοποιημένο μοντέλο εργασίας με αισθητήρες.
Το API επιτρέπει την εκτέλεση τριών βασικών λειτουργιών: λήψη λίστας διαθέσιμων αισθητήρων, εγγραφή ακροατών για λήψη δεδομένων και διαχείριση της συχνότητας ενημέρωσης των μετρήσεων. SensorManager είναι το κεντρικό σημείο πρόσβασης σε όλες τις λειτουργίες. Το σύστημα ειδοποιεί την εφαρμογή μέσω callback onSensorChanged, μεταδίδοντας ένα αντικείμενο SensorEvent με πίνακα τιμών float.
Κατά τη διάρκεια ύπαρξης του Android, το API πέρασε από διάφορα στάδια ανάπτυξης. Στην έκδοση 2.3 (Gingerbread) εμφανίστηκε υποστήριξη για Batch Processing — ομαδοποίηση συμβάντων αισθητήρα για μείωση κατανάλωσης ενέργειας. Android 4.0 (Ice Cream Sandwich) πρόσθεσε εικονικούς αισθητήρες Gravity και Linear Acceleration. Από το Android 8.0, το σύστημα περιόρισε την πρόσβαση παρασκηνίου σε αισθητήρες για αυξημένη ιδιωτικότητα.
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
Log.d("Αισθητήρες", "${sensor.name} — ${sensor.type}")
}
Δεν έχουν όλες οι συσκευές το ίδιο σύνολο αισθητήρων. Η εφαρμογή πρέπει να ελέγχει τη διαθεσιμότητα ενός συγκεκριμένου αισθητήρα πριν από την εγγραφή ακροατή. Ο εξομοιωτής Android υποστηρίζει μόνο περιορισμένο σύνολο αισθητήρων — επιταχυνσιόμετρο και μαγνητόμετρο. Για τη δοκιμή των υπόλοιπων αισθητήρων απαιτείται φυσική συσκευή. Από το Android 12, οι εφαρμογές πρέπει να δηλώνουν τη χρήση αισθητήρων στο manifest.
Το Android ταξινομεί όλους τους αισθητήρες σε τρεις κατηγορίες: Motion (κίνηση), Position (θέση) και Environment (περιβάλλον). Οι αισθητήρες Motion περιλαμβάνουν επιταχυνσιόμετρο, γυροσκόπιο και βηματόμετρο. Οι αισθητήρες Position περιλαμβάνουν μαγνητόμετρο και Orientation. Environment — αισθητήρας φωτός, πίεσης, θερμοκρασίας και υγρασίας.
| Κατηγορία | Αισθητήρες | Τύπος (σταθερά) | Φυσικός/Εικονικός |
|---|---|---|---|
| Motion | Επιταχυνσιόμετρο | TYPE_ACCELEROMETER | Φυσικός |
| Motion | Γυροσκόπιο | TYPE_GYROSCOPE | Φυσικός |
| Motion | Βηματόμετρο | TYPE_STEP_COUNTER | Φυσικός |
| Motion | Gravity | TYPE_GRAVITY | Εικονικός |
| Position | Μαγνητόμετρο | TYPE_MAGNETIC_FIELD | Φυσικός |
| Position | Rotation Vector | TYPE_ROTATION_VECTOR | Εικονικός |
| Environment | Φως | TYPE_LIGHT | Φυσικός |
| Environment | Πίεση | TYPE_PRESSURE | Φυσικός |
Το επιταχυνσιόμετρο μετρά την επιτάχυνση σε m/s² κατά μήκος τριών αξόνων — X, Y και Z. Οι τιμές περιλαμβάνουν τη βαρύτητα (9.8 m/s² στον άξονα Z σε κατάσταση ηρεμίας). Το γυροσκόπιο μετρά τη γωνιακή ταχύτητα σε rad/s — την ταχύτητα περιστροφής της συσκευής γύρω από κάθε άξονα. Ο συνδυασμός αυτών των δύο αισθητήρων χρησιμοποιείται στην πλοήγηση, τα παιχνίδια και τις εφαρμογές AR.
class SensorActivity : Activity(), SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
val x = event.values[0]
val y = event.values[1]
val z = event.values[2]
textView.text = "X: $x, Y: $y, Z: $z"
}
}
override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}
Το μαγνητόμετρο (TYPE_MAGNETIC_FIELD) μετρά το μαγνητικό πεδίο σε μικροτέσλα (µT) κατά μήκος τριών αξόνων. Χρησιμοποιείται ως ψηφιακή πυξίδα — σε συνδυασμό με το επιταχυνσιόμετρο επιτρέπει τον προσδιορισμό του αζιμουθίου της συσκευής. Το Rotation Vector — ένας εικονικός αισθητήρας που συνδυάζει δεδομένα από γυροσκόπιο, επιταχυνσιόμετρο και μαγνητόμετρο για ακριβή προσδιορισμό προσανατολισμού.
Ο αισθητήρας φωτός (TYPE_LIGHT) μετρά το επίπεδο εξωτερικού φωτισμού σε lux (lx). Χρησιμοποιείται για αυτόματη ρύθμιση της φωτεινότητας της οθόνης. Ο αισθητήρας πίεσης (TYPE_PRESSURE) μετρά την ατμοσφαιρική πίεση σε εκτοπασκάλ (hPa) — χρησιμοποιείται σε εφαρμογές πλοήγησης για τον προσδιορισμό του υψομέτρου πάνω από την επιφάνεια της θάλασσας.
Το Sensors API είναι χτισμένο σε αρχιτεκτονική πελάτη-εξυπηρετητή. Η εφαρμογή λειτουργεί ως πελάτης, ο SensorManager — ως υπηρεσία συστήματος Android. Όταν η εφαρμογή εγγράφει έναν ακροατή μέσω registerListener, ο SensorManager συνδέεται με το HAL (Hardware Abstraction Layer) — τον οδηγό χαμηλού επιπέδου του αισθητήρα που λειτουργεί σε επίπεδο πυρήνα Linux.
Ο οδηγός HAL λαμβάνει ακατέργαστα δεδομένα από το τσιπ υλικού, φιλτράρει τον θόρυβο και τα μεταδίδει προς τα πάνω στη στοίβα — μέσω SensorService (διεργασία συστήματος) στην εφαρμογή. Τα δεδομένα μεταδίδονται ως αντικείμενο SensorEvent, που περιέχει έναν πίνακα τιμών float values και μια χρονική σήμανση σε νανοδευτερόλεπτα. Η συχνότητα των συμβάντων εξαρτάται από την επιλεγμένη λειτουργία παράδοσης.
Κατά την εγγραφή ακροατή, ο προγραμματιστής καθορίζει την επιθυμητή καθυστέρηση μεταξύ συμβάντων μέσω των σταθερών SENSOR_DELAY_NORMAL (200 ms), SENSOR_DELAY_UI (60 ms), SENSOR_DELAY_GAME (20 ms) και SENSOR_DELAY_FASTEST (0 ms — μέγιστη συχνότητα). Η πραγματική συχνότητα μπορεί να διαφέρει — το σύστημα βελτιστοποιεί την κατανάλωση ενέργειας.
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
this,
sensor,
SensorManager.SENSOR_DELAY_GAME
)
Από Android 2.3, οι αισθητήρες υποστηρίζουν λειτουργία παρτίδας — τα συμβάντα συσσωρεύονται σε προσωρινή μνήμη FIFO και παραδίδονται σε ένα πακέτο. Αυτό επιτρέπει στον επεξεργαστή να παραμένει σε κατάσταση ύπνου περισσότερο, μειώνοντας την κατανάλωση ενέργειας έως και 60%. Το μέγεθος της προσωρινής μνήμης εξαρτάται από το τσιπ αισθητήρα και αναφέρεται στο πεδίο Sensor.fifoMaxEventCount.
SensorManager — υπηρεσία συστήματος προσβάσιμη μέσω getSystemService(Context.SENSOR_SERVICE). Παρέχει μεθόδους για λήψη λίστας αισθητήρων, λήψη συγκεκριμένου προεπιλεγμένου αισθητήρα και εγγραφή/ακύρωση ακροατών. SensorManager — singleton, μία παρουσία για ολόκληρη την εφαρμογή.
Πριν από τη χρήση ενός αισθητήρα, πρέπει να ελέγχεται η ύπαρξή του. Η μέθοδος getDefaultSensor(type) επιστρέφει null εάν ο αισθητήρας δεν είναι διαθέσιμος στη συσκευή. Η λήψη null χωρίς έλεγχο θα οδηγήσει σε NullPointerException κατά την εγγραφή ακροατή. Η λίστα όλων των αισθητήρων επιστρέφεται από τη μέθοδο getSensorList(type).
fun checkSensorAvailability(type: Int): Boolean {
val sensorManager =
getSystemService(Context.SENSOR_SERVICE) as SensorManager
return sensorManager.getDefaultSensor(type) != null
}
// Χρήση:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
Log.d("Sensor", "Γυροσκόπιο διαθέσιμο")
}
Ο ακροατής εγγράφεται μέσω registerListener(listener, sensor, delay). Σημαντικό: η ακύρωση του ακροατή πρέπει να γίνεται στη μέθοδο onPause() μέσω unregisterListener(listener). Εάν δεν γίνει αυτό, η εφαρμογή θα συνεχίσει να λαμβάνει συμβάντα αισθητήρα, εξαντλώντας την μπαταρία ακόμα και στο παρασκήνιο. Το Android 8+ εμφανίζει προειδοποίηση στο logcat για μη καταχωρημένους ακροατές.
Η μέθοδος onAccuracyChanged(sensor, accuracy) καλείται όταν αλλάζει η ακρίβεια του αισθητήρα. Τιμές: SENSOR_STATUS_ACCURACY_HIGH, MEDIUM, LOW και UNRELIABLE. Κατά τη λήψη UNRELIABLE, τα δεδομένα του αισθητήρα πρέπει να αγνοούνται έως ότου αποκατασταθεί η ακρίβεια. Για παράδειγμα, το μαγνητόμετρο απαιτεί βαθμονόμηση — τίναγμα της συσκευής σε σχήμα οκτώ.
Ας εξετάσουμε πρακτικά παραδείγματα χρήσης του Sensors API σε εφαρμογές Android σε Kotlin. Πρώτο παράδειγμα — προσδιορισμός προσανατολισμού οθόνης με χρήση επιταχυνσιόμετρου. Δεύτερο — ανάγνωση ενδείξεων μαγνητόμετρου με βαθμονόμηση. Τρίτο — ανιχνευτής βημάτων με χρήση βηματόμετρου.
Για τον προσδιορισμό προσανατολισμού χρησιμοποιείται συνδυασμός επιταχυνσιόμετρου και μαγνητόμετρου. Η μέθοδος SensorManager.getRotationMatrix() υπολογίζει τον πίνακα περιστροφής, και η getOrientation() εξάγει τις γωνίες pitch, roll και azimuth. Azimuth (αζιμούθιο) — η γωνία σε σχέση με τον μαγνητικό βορρά σε ακτίνια.
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)
SensorManager.getRotationMatrix(
rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())
Το βηματόμετρο (TYPE_STEP_COUNTER) επιστρέφει τον συνολικό αριθμό βημάτων που έχει κάνει ο χρήστης από την τελευταία επανεκκίνηση της συσκευής. Ο αισθητήρας λειτουργεί σε επίπεδο υλικού — είναι ενεργός ακόμα και όταν η εφαρμογή δεν εκτελείται. Για να λάβετε τον αριθμό βημάτων ανά συνεδρία, πρέπει να αποθηκεύσετε την αρχική τιμή και να υπολογίσετε τη διαφορά.
var initialSteps = 0
var isInitialized = false
override fun onSensorChanged(event: SensorEvent) {
if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
if (!isInitialized) {
initialSteps = event.values[0].toInt()
isInitialized = true
}
val currentSteps = event.values[0].toInt()
val sessionSteps = currentSteps - initialSteps
Log.d("Βήματα", "Βήματα ανά συνεδρία: $sessionSteps")
}
}
Ο αισθητήρας φωτός επιτρέπει την προσαρμογή της διεπαφής στις συνθήκες περιβάλλοντος. Σε χαμηλό φωτισμό (λιγότερο από 10 lx) μπορείτε να μεταβείτε σε σκούρο θέμα. Σε έντονο ηλιακό φως (πάνω από 10000 lx) — να αυξήσετε την αντίθεση. Για το φιλτράρισμα θορύβου χρησιμοποιείται κινητός μέσος όρος των τελευταίων 5 τιμών.
Το Android παρέχει αρκετούς εικονικούς αισθητήρες που δεν έχουν άμεσο αντίστοιχο υλικού. Ένας εικονικός αισθητήρας υπολογίζει τις ενδείξεις του βάσει συνδυασμού φυσικών αισθητήρων. Αυτό μειώνει το φορτίο του προγραμματιστή — το σύστημα υλοποιεί μόνο του τους αλγόριθμους σύντηξης δεδομένων.
Ο αισθητήρας Gravity (TYPE_GRAVITY) εξάγει τη βαρυτική συνιστώσα από τις μετρήσεις του επιταχυνσιόμετρου χρησιμοποιώντας φίλτρο χαμηλής διέλευσης (low-pass). Το Linear Acceleration (TYPE_LINEAR_ACCELERATION) — αντίθετα, αφαιρεί τη βαρύτητα και αφήνει μόνο τη γραμμική επιτάχυνση της συσκευής. Το άθροισμα των Gravity και Linear Acceleration δίνει τις ακατέργαστες μετρήσεις του επιταχυνσιόμετρου.
Rotation Vector — ο πιο σύνθετος εικονικός αισθητήρας. Συνδυάζει δεδομένα από γυροσκόπιο (αλλαγές υψηλής συχνότητας), επιταχυνσιόμετρο (διάνυσμα βαρύτητας) και μαγνητόμετρο (προσανατολισμός ως προς βορρά). Το αποτέλεσμα — ένα τετραδόνιο που περιγράφει τον απόλυτο προσανατολισμό της συσκευής στο χώρο. Χρησιμοποιείται σε εφαρμογές AR και ακουστικά VR.
Game Rotation Vector — μια απλοποιημένη έκδοση του Rotation Vector χωρίς χρήση μαγνητόμετρου. Αυτό δίνει χαμηλότερη ακρίβεια προσδιορισμού αζιμουθίου, αλλά υψηλότερη συχνότητα ενημέρωσης και σταθερότητα. Συνιστάται για παιχνίδια όπου η χαμηλή καθυστέρηση είναι σημαντική, όχι ο απόλυτος προσανατολισμός ως προς βορρά.
Οι αισθητήρες — ένα από τα πιο ενεργοβόρα εξαρτήματα της συσκευής. Το επιταχυνσιόμετρο και το γυροσκόπιο στη μέγιστη συχνότητα δειγματοληψίας μπορούν να εξαντλήσουν την μπαταρία σε 3–4 ώρες συνεχούς λειτουργίας. Η βελτιστοποίηση της εργασίας με αισθητήρες είναι κρίσιμη εργασία για κάθε εφαρμογή που χρησιμοποιεί Sensors API.
Μην χρησιμοποιείτε το SENSOR_DELAY_FASTEST χωρίς ανάγκη. Για κινούμενα σχέδια UI αρκεί SENSOR_DELAY_UI (60 ms). Για προσδιορισμό προσανατολισμού οθόνης — SENSOR_DELAY_NORMAL (200 ms). Όσο υψηλότερη είναι η συχνότητα, τόσο περισσότερο χρόνο ξοδεύει ο επεξεργαστής σε ενεργή κατάσταση. Η διαφορά μεταξύ NORMAL και FASTEST είναι έως και 10x στην κατανάλωση ενέργειας.
Από Android 8.0 (API 26), οι εφαρμογές παρασκηνίου λαμβάνουν συμβάντα αισθητήρων με μειωμένη συχνότητα. Σε Android 12+ η πρόσβαση παρασκηνίου σε αισθητήρες Motion και Position απαιτεί άδεια BODY_SENSORS_BACKGROUND. Ακυρώστε την εγγραφή ακροατή κατά τη μετάβαση της εφαρμογής σε λειτουργία παρασκηνίου — αυτό παρατείνει τη διάρκεια ζωής της μπαταρίας.
Χρησιμοποιήστε επεξεργασία παρτίδας μέσω της μεθόδου registerListener(listener, sensor, delay, maxReportLatencyUs). Η παράμετρος maxReportLatencyUs καθορίζει τη μέγιστη καθυστέρηση παράδοσης συμβάντων σε μικροδευτερόλεπτα. Στην τιμή 1000000 (1 δευτερόλεπτο), τα συμβάντα συσσωρεύονται στην προσωρινή μνήμη FIFO του αισθητήρα και παραδίδονται μία φορά το δευτερόλεπτο — ο επεξεργαστής ξυπνά λιγότερο συχνά.
Συχνές Ερωτήσεις
Το ελάχιστο σύνολο — επιταχυνσιόμετρο και μαγνητόμετρο. Αυτοί οι δύο αισθητήρες υπάρχουν σε περισσότερες από 95% των συσκευών. Γυροσκόπιο, αισθητήρας φωτός και αισθητήρας εγγύτητας — στο 70–80% των σύγχρονων μοντέλων. Οι υπόλοιποι αισθητήρες (πίεση, θερμοκρασία, υγρασία, βηματόμετρο) είναι λιγότερο συνηθισμένοι και εξαρτώνται από την κατηγορία τιμής της συσκευής.
TYPE_ACCELEROMETER επιστρέφει την πλήρη επιτάχυνση, συμπεριλαμβανομένης της βαρύτητας (9.8 m/s²). TYPE_LINEAR_ACCELERATION επιστρέφει την επιτάχυνση χωρίς βαρύτητα — μόνο την επιτάχυνση από την κίνηση της συσκευής. Εάν η συσκευή είναι ακίνητη, το επιταχυνσιόμετρο θα δείξει 9.8 m/s² στον άξονα Z, ενώ το Linear Acceleration — 0 σε όλους τους άξονες.
Χρησιμοποιήστε getPackageManager().hasSystemFeature() με τις αντίστοιχες σταθερές: FEATURE_SENSOR_ACCELEROMETER, FEATURE_SENSOR_GYROSCOPE, FEATURE_SENSOR_PROXIMITY και άλλες. Εναλλακτική μέθοδος — καλέστε getDefaultSensor(type) και ελέγξτε το αποτέλεσμα για null. Η πρώτη μέθοδος είναι προτιμότερη για έλεγχο στο στάδιο αρχικοποίησης.
Τα ακατέργαστα δεδομένα από τους αισθητήρες περιέχουν θόρυβο. Για εξομάλυνση χρησιμοποιήστε φίλτρο χαμηλής διέλευσης (low-pass): newValue = alpha * rawValue + (1 — alpha) * previousValue. Ο συντελεστής alpha = 0.1–0.3 δίνει καλή ισορροπία μεταξύ απόκρισης και ομαλότητας. Για το γυροσκόπιο εφαρμόζεται επίσης φίλτρο υψηλής διέλευσης (high-pass) για αφαίρεση της μετατόπισης μηδενός.
Ναι, αλλά με περιορισμούς. Από Android 8.0, η συχνότητα των συμβάντων αισθητήρα μειώνεται για εφαρμογές παρασκηνίου. Από Android 12, απαιτείται άδεια BODY_SENSORS_BACKGROUND για πρόσβαση σε αισθητήρες στο παρασκήνιο. Για εργασία παρασκηνίου συνιστάται η χρήση Foreground Service με ειδοποίηση.
Σύνοψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης