---
title: Sensörler
source: 'https://academia.sh/tr/kurslar/android-servisler/sensorler'
course: 'Platform Servisleri ve Tümleştirmeler'
language: tr
updated: '2026-10-21T05:02:42+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Sensör yöneticisi, sensör olayı ve örnekleme kavramlarını tanır'
    - 'Yavaş alıcıda yalnız son okumanın ulaştığını ve öncekilerin ezilen olduğunu ölçer'
    - 'Arabellek taşınca en yeni okumaların kayıp olduğunu gösterir'
    - 'Dinleyici kaydı kaldırıldıktan sonra üretilen okumaların kayıp olduğunu gösterir'
---

# Sensörler

Sensör olayları aygıtın ivmeölçer gibi donanımlarından hızla gelir; yavaş bir alıcı hepsine yetişemez. Ders arabellek taştığında ve alıcı yalnız son okumayı aldığında hangi sensör olayının ulaştığını ve dinleyici kaydı kaldırılınca ne olduğunu ölçer.

Önceki derste olay bir kullanıcı eyleminden doğuyordu ve her eylem tek bir sonuç veriyordu. Sensörde olay donanımdan gelir ve kullanıcıdan bağımsız, sürekli üretilir. İvmeölçer aygıtın hareketini, ışık sensörü ortam ışığını okur. Okumalar alıcının işleyebildiğinden hızlı gelebilir. Bu derste de aynı soruyu soruyoruz: **gönderilen bu olay alıcıya kaç kopya olarak ulaştı?**

```kotlin
// Arrival.kt — gonderilen bir olayin aliciya kac kopya olarak ulastigini siniflandirir
class Signal(val key: String, val seq: Int)

class Arrival(val label: String, val sent: Signal, received: List<Signal>) {
    val copies: Int = received.count { it.seq == sent.seq }
    val verdict: String = when {
        copies > 1 -> "yinelenen"
        copies == 1 -> "birebir"
        received.any { it.key == sent.key && it.seq > sent.seq } -> "ezilen"
        else -> "kayip"
    }

    fun line() {
        println("$label: anahtar=${sent.key} | kopya=$copies -> $verdict")
    }
}

fun countArrivals(arrivals: List<Arrival>) {
    for (name in listOf("birebir", "yinelenen", "ezilen", "kayip")) {
        println("$name: ${arrivals.count { it.verdict == name }}")
    }
}
```

Sınıflandırma önceki derslerdekiyle aynıdır. Kural alıcının listesinde aynı sırayı taşıyan kopyaları sayar; hiç kopya yoksa aynı anahtarla daha sonraki bir olayın ulaşıp ulaşmadığına bakar. İçeriği ve nedeni görmez.

## Sensör Yöneticisi ve Dinleyici

Platform sensörlere sensör yöneticisi üzerinden erişir. Uygulama bir sensör seçer, bir dinleyici kaydeder ve yöneticiye örnekleme hızını söyler. Hız bir istektir: platform okumaları bu hıza yakın bir sıklıkla verir ama sayıyı garanti etmez. Her okuma bir sensör olayı olarak dinleyicinin geri çağrısına düşer. Okumaların platform tarafından toplu teslim edilmesi de mümkündür; bu durumda okumalar aynı anda birden fazla gelebilir.

```kotlin
// Platform kodu: MotionWatcher
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager

class MotionWatcher(private val manager: SensorManager) : SensorEventListener {
    fun start() {
        val accel = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
        manager.registerListener(this, accel, SensorManager.SENSOR_DELAY_UI)
    }

    fun stop() = manager.unregisterListener(this)

    override fun onSensorChanged(event: SensorEvent) = process(event.values)
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) = Unit
}
```

`start` dinleyiciyi kaydeder, `stop` kaydı kaldırır. Modelde kaydı kaldırılmış dinleyici artık okuma almaz. Bu parça bir hız sayısı yazmaz ve çıktı iddia etmez. Model, platformun bu kuralını kurar; model platformun kendisi değildir.

## Örnekleme Hızı Bir İstektir

Dinleyiciyi kaydederken verilen hız sabiti, okumaların ne sıklıkla geleceğine dair bir ipucudur. Platform dört ayrı düzey sunar: en hızlı, oyun için hızlı, kullanıcı arayüzü için orta ve normal; normal en yavaş olanıdır. Daha hızlı düzey daha çok okuma üretir; ama bu bir sözleşme değil, platformun bir yaklaşımıdır. Aygıtın o anki yüküne, pil durumuna ve sensörün donanım sınırlarına göre gerçek sıklık bundan sapabilir.

Bu yüzden iki ayrı teslim sorusu vardır ve ikisi birbirine karıştırılmamalıdır. Birincisi, sensörün kaç okuma ürettiğidir; bunu hız düzeyi belirler. İkincisi, üretilen okumaların alıcıya kaçının ulaştığıdır; bunu bu dersin kuralı ölçer. Hız düzeyini artırmak üretimi artırır ama alıcı yavaşsa ulaşan sayı değişmez: fazladan üretilen okumalar yalnız ezilen olur. Pil ve işlemci bedeli ise üretimle orantılı artar. Hızı artırmanın faydası alıcının o kadar okumayı işleyebildiği durumda vardır.

Yüksek örnekleme hızı bazı sürümlerde ayrı bir izin de ister. İzin bildirilmeden dinleyici kaydedilirse platform hızı sessizce bir üst sınıra çeker; başka bir yoldan daha yüksek hız istenirse güvenlik hatası oluşur. Uygulama istediği sıklığı alıp almadığını kendisi denetlemelidir.

## Yavaş Alıcı

Modelde her okuma bir `Signal`dır ve anahtarı sensörün adıdır. Alıcı yavaşsa tek bir işleme turunda biriken okumaların yalnız sonuncusunu alır; öncekiler atlanır. Bir tur kaç okumayı kapsıyorsa o sayı modelin uydurma değeridir.

```kotlin
// Sampling.kt — yavas alici her turda yalniz son okumayi alir
fun latestOnly(sent: List<Signal>, perTurn: Int): List<Signal> =
    sent.chunked(perTurn).map { it.last() }
```

```kotlin
// Main.kt — yavas alici her turda yalniz son okumayi alir
fun main() {
    val sent = (1..8).map { Signal("sensor.ivme", it) }
    val received = latestOnly(sent, perTurn = 3)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [3, 6, 8]
olay-1: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-2: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-3: anahtar=sensor.ivme | kopya=1 -> birebir
olay-4: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-5: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-6: anahtar=sensor.ivme | kopya=1 -> birebir
olay-7: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-8: anahtar=sensor.ivme | kopya=1 -> birebir
birebir: 3
yinelenen: 0
ezilen: 5
kayip: 0
```

Bu dersin teslimi **ezilen**dir. Sekiz okumanın beşi ulaşmadı, ama her birinin ardından aynı anahtarla daha yeni bir okuma ulaştı. Hareket izlemek için bu doğru bir takastır: güncel değer eskisinden değerlidir. Sekizinci okuma turun sonuncusu olduğu için ulaştı; son tur tamamlanmasa bile son okuma alınır.

**SY1.** Model, turları eşit uzunlukta kurar ve her turun sonunu alıcının okuma anı sayar. Platformda tur uzunluğu işleme yüküne göre değişir ve okumalar toplu teslimde birkaç kez gruplanabilir; bunlar modelde yoktur.

## Toplu Teslim ve Boşaltma

Pil tasarrufu için platform okumaları donanımda biriktirip topluca verebilir. Uygulama, bir okumanın üretimi ile teslimi arasında izin verilen en uzun gecikmeyi belirtir; platform okumaları o süre dolana ya da arabellek dolana kadar bekletir ve sonra hepsini bir arada teslim eder. Ekran kapalıyken bile sensör okuyabilmek bu düzenle mümkün olur.

Toplu teslimin kuralı kısadır: bir yığın ya tamamlanıp teslim edilir ya da bekler. Modelde beklemekte olan yığın, uygulama kaydı kaldırdığında kendiliğinden gelmez. Gecikmeli teslimde okumaları kaybetmemenin yolu, kaydı kaldırmadan önce bekleyen yığını açıkça boşaltmaktır. Modelde yığın boyutu üçtür ve yığını tamamlanmamış son okumalar boşaltılmadığı için teslim edilmez.

```kotlin
// Batch.kt — tamamlanmamis son yigin bosaltilmadan teslim edilmez
fun deliverBatched(sent: List<Signal>, size: Int): List<Signal> =
    sent.chunked(size).filter { it.size == size }.flatten()
```

```kotlin
// Main.kt — tamamlanmamis son yigin teslim edilmez
fun main() {
    val sent = (21..27).map { Signal("sensor.adim", it) }
    val received = deliverBatched(sent, size = 3)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [21, 22, 23, 24, 25, 26]
olay-21: anahtar=sensor.adim | kopya=1 -> birebir
olay-22: anahtar=sensor.adim | kopya=1 -> birebir
olay-23: anahtar=sensor.adim | kopya=1 -> birebir
olay-24: anahtar=sensor.adim | kopya=1 -> birebir
olay-25: anahtar=sensor.adim | kopya=1 -> birebir
olay-26: anahtar=sensor.adim | kopya=1 -> birebir
olay-27: anahtar=sensor.adim | kopya=0 -> kayip
birebir: 6
yinelenen: 0
ezilen: 0
kayip: 1
```

Altı okuma iki tam yığınla teslim edildi ve birebir ulaştı. Yedinci okuma tamamlanmamış yığında kaldı ve ondan sonra aynı anahtarla bir okuma ulaşmadığı için kayıp oldu. Kural bunu sensörün ya da kaydın hatası olarak görmez; yalnızca ulaşmadığını sayar. Alıcı tarafın önlemi, kaydı kaldırmadan önce bekleyen okumaları açıkça istemektir.

**SY2.** Model, yığını sabit boyutlu ve gecikmesiz kurar. Platformda yığın boyutu okuma hızına, gecikme sınırına ve arabellek kapasitesine bağlıdır ve boşaltma isteği de bir geri çağrıyla tamamlanır; bunlar modelde yoktur.

## Arabellek Taşınca

Alıcının önünde bir arabellek durabilir. Arabellek dolduğunda iki seçenek vardır: en eskiyi atmak ya da yeni gelen okumayı atmak. Önceki bölümdeki alıcı en yeni okumayı tutuyordu; yeni geleni atan arabellek bunun tersini yapar.

```kotlin
// Overflow.kt — arabellek dolunca yeni gelen okumalari birakir
fun overflow(sent: List<Signal>, capacity: Int): List<Signal> =
    sent.take(capacity)
```

```kotlin
// Main.kt — arabellek tasinca en yeni okumalar ulasmaz
fun main() {
    val sent = (9..14).map { Signal("sensor.isik", it) }
    val received = overflow(sent, capacity = 3)
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [9, 10, 11]
olay-9: anahtar=sensor.isik | kopya=1 -> birebir
olay-10: anahtar=sensor.isik | kopya=1 -> birebir
olay-11: anahtar=sensor.isik | kopya=1 -> birebir
olay-12: anahtar=sensor.isik | kopya=0 -> kayip
olay-13: anahtar=sensor.isik | kopya=0 -> kayip
olay-14: anahtar=sensor.isik | kopya=0 -> kayip
birebir: 3
yinelenen: 0
ezilen: 0
kayip: 3
```

İlk üç okuma birebir ulaştı; 12, 13 ve 14 numaralı okumalar kayıp oldu. Atılan okumalardan sonra aynı anahtarla yeni bir okuma ulaşmadığı için kural bunları ezilen saymaz. Aynı taşma, en eskiyi atan bir arabellekte ezilen olarak sonuçlanırdı. Hangi okumanın atılacağı alıcının değerine bağlıdır; kural yalnız sonucu sayar.

**SY3.** Model, arabellek kapasitesini sabit bir tamsayı olarak kurar. Platformda arabellek boyutu donanıma ve sürüme bağlıdır ve taşma sırasında hangi okumanın atılacağı sensöre göre değişebilir; bunlar modelde yoktur.

## Sensör Türleri ve İzin

Sensörlerin hepsi aynı izin düzeyinde değildir. Hareket ve ışık sensörleri izin istemez. Kalp atışı gibi bedene dair sensörler çalışma zamanı izni ister ve kullanıcı bu izni vermezse sensör listede görünmeyebilir ya da okuma vermez. İzin eksikliği kayıtta hata üretmez; dinleyici kaydedilir, ama geri çağrı hiç çalışmaz.

Bu, önceki iki dersten tanıdık bir kayıptır. Konumda izin geri alındıktan sonra güncellemeler gelmedi; kamerada izin verilmeden önceki istekler sonuç üretmedi. Sensörde de izinsiz bir dinleyici sessizdir. Sessizlik üç ayrı durumdan doğabilir: izin yok, sensör donanımda yok, ya da sensör var ama olay üretmiyor. Uygulama bunları ayırmak için önce sensörün varlığına, sonra iznin durumuna, en son okumaların akıp akmadığına bakar.

## Doğruluk Geri Çağrısı ve Zaman Damgası

Dinleyicinin iki geri çağrısı vardır. Birincisi okumayı verir, ikincisi sensörün doğruluk düzeyi değiştiğinde çalışır. Platform kodundaki parça ikincisini boş bıraktı. Bu çoğu uygulama için yeterlidir, ama bazı sensörler için yanlış bir tercih olabilir: pusula gibi sensörler kalibrasyon gerektirir ve doğruluk düşükken okuma sayıları gelir ama anlamsızdır.

Bu durumun teslim modeliyle ilişkisi şudur. Düşük doğrulukla gelen okuma alıcıya ulaşmıştır ve kural onu birebir sayar. Okumanın kullanılabilir olup olmadığı kuralın görmediği bir özelliktir. Sayı doğru ulaşmış, değer güvenilmez kalmıştır. Alıcı bu iki soruyu ayrı tutmalıdır: ulaştı mı, ve ulaştıysa güvenilir mi.

Her okuma bir zaman damgası da taşır. Damga okumanın donanımda üretildiği anı gösterir, alıcıya teslim edildiği anı değil. Toplu teslimde ya da yavaş alıcıda iki an birbirinden uzaklaşır: okuma geç gelir ama damgası eskidir. Alıcı bir okumayı işlerken damgaya bakarsa eski bir okumayı güncel gibi göstermez. Modelde sıra numarası bu rolü üstlenir: daha büyük sıra daha yeni üretim demektir ve ezilen kuralı bu sıraya dayanır.

## Yaygın Yanılgılar

**"Hızı artırırsam daha çok okuma alırım."** Üretim artar, alıcıya ulaşan sayı alıcının hızıyla sınırlıdır. Yavaş alıcıda fazladan okumalar yalnız ezilen sayılır; ölçümde sekiz okumanın beşi bu yüzden ezilen oldu.

**"Ezilen okuma kayıptır, bu bir hata."** Ezilen okumanın yerini aynı anahtarla daha yeni bir okuma almıştır. Hareket izleyen bir uygulama için güncel değer eskisinden değerlidir ve bu davranış istenir. Hata, bir okumanın ardından hiçbir okuma gelmediğinde, yani kayıpta aranır.

**"Kayıt kaldırılırsa bekleyen okumalar yine gelir."** Modelde kaydın kaldırılması dinleyiciyi susturur. Toplu teslimde bekleyen yığın kendiliğinden gelmez; uygulama onu önce açıkça boşaltmalıdır.

**"Sensör olayı gerçek zamanlıdır."** Olay, üretildiği andan teslim edildiği ana kadar bekleyebilir. Toplu teslimde ve yavaş alıcıda bu bekleme uzar. Zaman damgası olayın ne zaman üretildiğini söyler; ne zaman işlendiğini söylemez.

**"Sensör olayı her zaman ana akışta işlenir."** Geri çağrı, `Handler` verilmezse ana iş parçacığında, verilirse o `Handler`'ın looper'ında çalışır; yani kayıt nasıl yapıldığına bağlıdır. Ağır işlemi geri çağrıda yapan uygulama alıcıyı yavaşlatır ve yavaş alıcı bu dersin ilk ölçümündeki gibi okumaları ezer. Geri çağrıda yalnızca değeri almak ve işlemi başka bir akışa bırakmak, kaybı değil ezilmeyi seçmek demektir.

**"Dinleyiciyi hep açık bırakmak zararsızdır."** Açık bir dinleyici, ekran kapalıyken bile okuma üretir ve pil harcar. Okumaya ihtiyaç kalmadığında kaydı kaldırmak, hem enerjiyi korur hem de kimsenin işlemediği okumaların birikmesini önler.

**"Okuma sayısı doğruluk demektir."** Çok sayıda okuma, değerlerin güvenilir olduğunu göstermez. Doğruluk düzeyi ayrı bir bilgidir ve sayıdan bağımsız değişir.

## Sınırlayıcı Ölçüm

Alıcı okumaları zaten işleyebilecek kadar hızlı olsa bile, dinleyici kaydı kaldırıldığı anda okumalar kesilir. Uygulama ekrandan ayrıldığında `stop` çağırmayı unutmazsa pil harcar; çağırırsa o andan sonraki okumalar ulaşmaz.

```kotlin
// Main.kt — dinleyici kaydi kaldirilinca sonraki okumalar ulasmaz
fun main() {
    val sent = (15..20).map { Signal("sensor.ivme", it) }
    val received = latestOnly(sent, perTurn = 2).filter { it.seq < 19 }
    println("ulasan siralar: ${received.map { it.seq }}")

    val arrivals = sent.map { Arrival("olay-${it.seq}", it, received) }
    arrivals.forEach { it.line() }
    countArrivals(arrivals)
}
```

```text
ulasan siralar: [16, 18]
olay-15: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-16: anahtar=sensor.ivme | kopya=1 -> birebir
olay-17: anahtar=sensor.ivme | kopya=0 -> ezilen
olay-18: anahtar=sensor.ivme | kopya=1 -> birebir
olay-19: anahtar=sensor.ivme | kopya=0 -> kayip
olay-20: anahtar=sensor.ivme | kopya=0 -> kayip
birebir: 2
yinelenen: 0
ezilen: 2
kayip: 2
```

16 ve 18 numaralı okumalar ulaştı; 15 ve 17 ezilen oldu. 19 ve 20 numaralı okumalar kayıp oldu: dinleyici kaydı 19'dan önce kaldırıldığı için sonrasında hiçbir okuma ulaşmadı. Kural kaybın nedeninin kaldırılmış kayıt olduğunu görmez.

**SY4.** Model, kaydın kaldırılmasını tek bir adımda ve anında kurar. Platformda kaldırma çağrısından sonra bile arabellekte kalmış okumalar gelebilir; bu modelde yoktur.

## Özet

- Bu dersin teslimi: ezilen. Yavaş alıcı her turda yalnız son okumayı alır ve öncekiler yerini aynı anahtarlı yeni okumaya bırakır.
- Sekiz okumadan beşi ezilen, üçü birebir oldu: ezilen 5, birebir 3.
- Yeni gelen okumayı atan arabellek taştığında üç okuma kayıp oldu: kayip 3. En eskiyi atan arabellek aynı okumaları ezilen yapardı.
- Dinleyici kaydı kaldırıldıktan sonra üretilen iki okuma kayıp oldu: kayip 2.
- Tamamlanmamış son yığın boşaltılmadan teslim edilmez: altı okuma birebir ulaştı, yedincisi kayıp oldu: birebir 6, kayip 1.
- Örnekleme hızı bir istektir; platform okumaları bu sıklıkla vermeyi garanti etmez.

## Sonraki Adım

Bu derste olay donanımdan geldi ve alıcı yetişemeyince ezildi. Derin bağlantıda olay dışarıdan bir bağlantı olarak gelir ve uygulama yeniden oluşturulurken aynı bağlantı bir kez daha işlenebilir. Sıradaki ders, `Derin Bağlantılar ve Kısayollar`, döndürmede yeniden işlenen derin bağlantıyı ölçer.
