Sensörlere Genel Bakış

Android destekli çoğu cihazın hareketi, yönü ve çeşitli çevre koşullarını ölçen yerleşik sensörleri vardır. Bu sensörler, yüksek hassasiyet ve doğrulukla ham veriler sağlayabilir. Ayrıca üç boyutlu cihaz hareketini veya konumlandırmasını ya da cihazın yakınındaki ortam ortamında gerçekleşen değişiklikleri izlemek istediğinizde kullanışlıdır. Örneğin, bir oyun; yatırma, sallama, döndürme veya sallama gibi karmaşık kullanıcı hareketlerini ve hareketlerini anlamak için cihazın yerçekimi sensöründen gelen ölçümleri izleyebilir. Benzer şekilde, bir hava durumu uygulaması çiy noktasını hesaplamak ve raporlamak için cihazın sıcaklık sensörünü ve nem sensörünü kullanabilir ya da bir seyahat uygulaması pusula yönünü bildirmek için jeomanyetik alan sensörü ve ivme ölçeri kullanabilir.

Android platformu üç geniş sensör kategorisini destekler:

  • Hareket sensörleri

    Bu sensörler, üç eksen boyunca ivme kuvvetlerini ve dönme kuvvetlerini ölçer. Bu kategori ivme ölçerler, yer çekimi sensörleri, jiroskoplar ve dönme vektör sensörlerini içerir.

  • Çevre sensörleri

    Bu sensörler ortam hava sıcaklığı ve basıncı, aydınlatma ve nem gibi çeşitli çevre parametrelerini ölçer. Bu kategori barometreleri, fotometreleri ve termometreleri içerir.

  • Konum sensörleri

    Bu sensörler bir cihazın fiziksel konumunu ölçer. Bu kategori yön sensörlerini ve manyetometreleri içerir.

Cihazda bulunan sensörlere erişebilir ve Android sensör çerçevesini kullanarak ham sensör verileri elde edebilirsiniz. Sensör çerçevesi, sensörlerle ilgili çok çeşitli görevleri gerçekleştirmenize yardımcı olan çeşitli sınıflar ve arayüzler sunar. Örneğin, şunları yapmak için sensör çerçevesini kullanabilirsiniz:

  • Bir cihazda hangi sensörlerin kullanılabilir olduğunu belirleyin.
  • Bağımsız bir sensörün maksimum menzili, üreticisi, güç gereksinimleri ve çözünürlük gibi özelliklerini belirleyin.
  • Ham sensör verilerini edinme ve sensör verilerini elde ettiğiniz minimum hızı tanımlayın.
  • Sensör değişikliklerini izleyen sensör etkinliği işleyicilerini kaydedin ve kayıtlarını silin.

Bu makalede, Android platformunda bulunan sensörlere genel bir bakış sunulmaktadır. Ayrıca sensör çerçevesine giriş niteliğindedir.

Sensörlere Giriş

Android sensör çerçevesi pek çok sensör türüne erişmenize olanak tanır. Bu sensörlerin bazıları donanım bazlı, bazıları ise yazılım tabanlıdır. Donanım tabanlı sensörler, telefon veya tablet cihazda yerleşik olarak bulunan fiziksel bileşenlerdir. İvme, jeomanyetik alan kuvveti veya açısal değişim gibi çevresel özellikleri doğrudan ölçerek verilerini türetirler. Yazılım tabanlı sensörler, donanım tabanlı sensörleri taklit etse de fiziksel cihazlar değildir. Yazılım tabanlı sensörler, verilerini donanım tabanlı bir veya daha fazla sensörden alır ve bazen sanal sensörler veya sentetik sensörler olarak da adlandırılır. Doğrusal ivme sensörü ve yerçekimi sensörü, yazılım tabanlı sensörlere örnektir. Tablo 1'de Android platformu tarafından desteklenen sensörler özetlenmiştir.

Her türde sensöre sahip olan Android destekli cihaz sayısı çok azdır. Örneğin, çoğu mobil cihaz ve tablette ivme ölçer ve manyetometre bulunurken daha az cihazda barometre veya termometre bulunur. Ayrıca, bir cihaz belirli bir türde birden fazla sensöre sahip olabilir. Örneğin, bir cihazda her biri farklı bir mesafeye sahip olan iki yer çekimi sensörü olabilir.

Tablo 1. Android platformunun desteklediği sensör türleri.

Sensör Tür Açıklama Yaygın Kullanımlar
TYPE_ACCELEROMETER Donanım Yer çekimi kuvveti de dahil olmak üzere üç fiziksel eksende (x, y ve z) cihaza uygulanan ivme kuvvetini m/sn2 cinsinden ölçer. Hareket algılama (titreme, yatırma vb.).
TYPE_AMBIENT_TEMPERATURE Donanım Odanın ortam sıcaklığını Santigrat (°C) cinsinden ölçer. Aşağıdaki nota bakın. Hava sıcaklıkları izleniyor.
TYPE_GRAVITY Yazılım veya Donanım Üç fiziksel eksenin (x, y, z) üzerinde cihaza uygulanan yerçekimi kuvvetini m/s2 cinsinden ölçer. Hareket algılama (titreme, yatırma vb.).
TYPE_GYROSCOPE Donanım Bir cihazın, üç fiziksel eksenin (x, y ve z) her biri etrafında rad/sn cinsinden dönme hızını ölçer. Döndürme algılama (dönme, döndürme vb.).
TYPE_LIGHT Donanım Ortam ışığı seviyesini (aydınlatma) Lx cinsinden ölçer. Ekran parlaklığını kontrol etme.
TYPE_LINEAR_ACCELERATION Yazılım veya Donanım Yer çekimi kuvveti hariç olmak üzere, üç fiziksel eksende (x, y ve z) bir cihaza uygulanan ivme kuvvetini m/sn2 cinsinden ölçer. Tek bir eksen üzerinde ivmeyi izleme.
TYPE_MAGNETIC_FIELD Donanım Üç fiziksel eksenin (x, y, z) μT cinsinden ortam jeomanyetik alanını ölçer. Pusula oluşturuluyor.
TYPE_ORIENTATION Yazılım Bir cihazın üç fiziksel eksenin (x, y, z) etrafında yaptığı dönüş derecelerini ölçer. API seviyesi 3'ten itibaren, getRotationMatrix() yöntemiyle birlikte yerçekimi sensörü ve jeomanyetik alan sensörünü kullanarak bir cihazın eğim matrisini ve dönüş matrisini elde edebilirsiniz. Cihaz konumu belirleniyor.
TYPE_PRESSURE Donanım Ortamdaki hava basıncını hPa veya mbar cinsinden ölçer. Hava basıncı değişikliklerini izleme.
TYPE_PROXIMITY Donanım Bir cihazın görüntüleme ekranına göre nesnenin yakınlığını cm cinsinden ölçer. Bu sensör, genellikle telefonun bir kişinin kulağına tutunup tutulmadığını belirlemek için kullanılır. Çağrı sırasında telefonun konumu.
TYPE_RELATIVE_HUMIDITY Donanım Bağıl ortam nemini yüzde (%) cinsinden ölçer. Çiy noktası, mutlak ve bağıl nem takip ediliyor.
TYPE_ROTATION_VECTOR Yazılım veya Donanım Cihazın dönme vektörünün üç öğesini sağlayarak cihazın yönünü ölçer. Hareket algılama ve döndürme algılama.
TYPE_TEMPERATURE Donanım Cihazın sıcaklığını Santigrat (°C) cinsinden ölçer. Bu sensör uygulaması cihaza göre değişir ve bu sensör, API Seviyesi 14'te TYPE_AMBIENT_TEMPERATURE sensörüyle değiştirildi Sıcaklıkları izleme.

Sensör Çerçevesi

Android sensör çerçevesini kullanarak bu sensörlere erişebilir ve ham sensör verileri elde edebilirsiniz. Sensör çerçevesi, android.hardware paketinin bir parçasıdır ve aşağıdaki sınıfları ve arayüzleri içerir:

SensorManager
Sensör hizmetinin örneğini oluşturmak için bu sınıfı kullanabilirsiniz. Bu sınıf, sensörlere erişme ve bunları listeleme, sensör etkinlik dinleyicilerini kaydedip silme ve yön bilgileri edinme için çeşitli yöntemler sunar. Bu sınıf ayrıca sensör doğruluğunu raporlamak, veri edinme hızlarını ayarlamak ve sensörleri kalibre etmek için kullanılan çeşitli sensör sabitleri sağlar.
Sensor
Belirli bir sensörün örneğini oluşturmak için bu sınıfı kullanabilirsiniz. Bu sınıf, bir sensörün özelliklerini belirlemenize olanak tanıyan çeşitli yöntemler sunar.
SensorEvent
Sistem, bu sınıfı bir sensör etkinliği nesnesi oluşturmak için kullanır. Bu nesne, sensör etkinliği hakkında bilgi sağlar. Bir sensör etkinlik nesnesi şu bilgileri içerir: ham sensör verileri, etkinliği oluşturan sensörün türü, verilerin doğruluğu ve etkinliğin zaman damgası.
SensorEventListener
Sensör değerleri değiştiğinde veya sensör doğruluğu değiştiğinde bildirim (sensör etkinlikleri) alan iki geri çağırma yöntemi oluşturmak için bu arayüzü kullanabilirsiniz.

Tipik bir uygulamada iki temel görevi gerçekleştirmek için sensörle ilgili bu API'leri kullanırsınız:

  • Sensörleri ve sensör özelliklerini tanımlama

    Uygulamanızda belirli sensör türlerine veya özelliklerine dayanan özellikler varsa çalışma zamanında sensörleri ve sensör özelliklerini tanımlamak faydalı olur. Örneğin, bir cihazda bulunan tüm sensörleri tanımlamak ve mevcut olmayan sensörlere dayalı uygulama özelliklerini devre dışı bırakmak isteyebilirsiniz. Benzer şekilde, uygulamanız için optimum performansa sahip sensör uygulamasını seçmek için belirli bir türdeki tüm sensörleri tanımlamak isteyebilirsiniz.

  • Sensör etkinliklerini izleme

    Ham sensör verilerini elde etme yönteminiz, sensör etkinliklerini izlemedir. Bir sensör ölçtüğü parametrelerde değişiklik algıladığında bir sensör etkinliği oluşur. Bir sensör etkinliği size dört adet bilgi sağlar: etkinliği tetikleyen sensörün adı, etkinliğin zaman damgası, etkinliğin doğruluğu ve etkinliği tetikleyen ham sensör verileri.

Sensör Kullanılabilirliği

Sensör kullanılabilirliği cihazdan cihaza değişse de Android sürümleri arasında da değişiklik gösterebilir. Bunun nedeni, Android sensörlerinin birkaç platform sürümünde kullanıma sunulmasıdır. Örneğin, birçok sensör Android 1.5'te (API Düzeyi 3) kullanıma sunulmuştu, ancak bazıları uygulanmadı ve Android 2.3'e (API Düzeyi 9) kadar kullanılamıyordu. Benzer şekilde Android 2.3 (API Düzeyi 9) ve Android 4.0'da (API Düzeyi 14) birkaç sensör kullanıma sunulmuştur. İki sensör kullanımdan kaldırıldı ve artık daha yeni ve daha iyi sensörlerle değiştirildi.

Tablo 2'de her bir sensörün kullanılabilirliği platform bazında özetlenmiştir. Sensör değişikliklerinin yapıldığı platformlar olduğu için yalnızca dört platform listelenmektedir. Kullanımdan kaldırıldı olarak listelenen sensörler, Android'in ileriye dönük uyumluluk politikasına uygun olarak sonraki platformlarda (sensörün bir cihazda bulunması şartıyla) kullanılmaya devam eder.

Tablo 2. Platforma göre sensör kullanılabilirliği.

Sensör Android 4.0
(API Düzeyi 14)
Android 2.3
(API Düzeyi 9)
Android 2.2
(API Düzeyi 8)
Android 1.5
(API Düzeyi 3)
TYPE_ACCELEROMETER Evet Evet Evet Evet
TYPE_AMBIENT_TEMPERATURE Evet Yok Yok Yok
TYPE_GRAVITY Evet Evet Yok Yok
TYPE_GYROSCOPE Evet Evet Yok1 Yok1
TYPE_LIGHT Evet Evet Evet Evet
TYPE_LINEAR_ACCELERATION Evet Evet Yok Yok
TYPE_MAGNETIC_FIELD Evet Evet Evet Evet
TYPE_ORIENTATION Evet2 Evet2 Evet2 Evet
TYPE_PRESSURE Evet Evet Yok1 Yok1
TYPE_PROXIMITY Evet Evet Evet Evet
TYPE_RELATIVE_HUMIDITY Evet Yok Yok Yok
TYPE_ROTATION_VECTOR Evet Evet Yok Yok
TYPE_TEMPERATURE Evet2 Evet Evet Evet

1 Bu sensör türü, Android 1.5 (API Düzeyi 3) sürümünde eklenmiş ancak Android 2.3'e (API Düzeyi 9) kadar kullanıma sunulmamıştı.

2 Bu sensör kullanılabilir ancak kullanımdan kaldırılmıştır.

Sensörleri ve Sensör Becerilerini Tanımlama

Android sensör çerçevesi, çalışma zamanında hangi sensörlerin cihazda olduğunu belirlemenizi kolaylaştıran çeşitli yöntemler sunar. API, her bir sensörün özelliklerini (ör. maksimum menzili, çözünürlüğü ve güç gereksinimleri gibi) belirlemenizi sağlayan yöntemler de sunar.

Bir cihazdaki sensörleri belirlemek için öncelikle sensör hizmetine referans almanız gerekir. Bunu yapmak için getSystemService() yöntemini çağırıp SENSOR_SERVICE bağımsız değişkenini ileterek SensorManager sınıfının bir örneğini oluşturursunuz. Örnek:

Kotlin

private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

Java

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

Daha sonra, getSensorList() yöntemini çağırıp TYPE_ALL sabitini kullanarak bir cihazdaki tüm sensörlerin listesini alabilirsiniz. Örnek:

Kotlin

val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)

Java

List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

Belirli bir türdeki tüm sensörleri listelemek isterseniz TYPE_ALL yerine TYPE_GYROSCOPE, TYPE_LINEAR_ACCELERATION veya TYPE_GRAVITY gibi başka bir sabit değer kullanabilirsiniz.

Ayrıca getDefaultSensor() yöntemini kullanarak ve belirli bir sensörün tür sabitini ileterek bir cihazda belirli türde bir sensörün olup olmadığını belirleyebilirsiniz. Bir cihaz belirli bir türde birden fazla sensöre sahipse sensörlerden biri varsayılan sensör olarak atanmalıdır. Belirli bir sensör türü için varsayılan sensör yoksa yöntem çağrısı null değerini döndürür, yani cihazda bu tür bir sensör yoktur. Örneğin, aşağıdaki kod bir cihazda manyetometre olup olmadığını kontrol eder:

Kotlin

private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) {
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

Java

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

Not: Android, cihaz üreticilerinin Android destekli cihazlarına belirli türlerde sensörler oluşturmasını zorunlu kılmaz. Bu nedenle, cihazlar çok çeşitli sensör yapılandırmalarına sahip olabilir.

Bağımsız sensörlerin işlevlerini ve özelliklerini belirlemek için bir cihazdaki sensörleri listelemenin yanı sıra Sensor sınıfının herkese açık yöntemlerini de kullanabilirsiniz. Bu, uygulamanızın bir cihazda hangi sensörlerin veya sensör özelliklerinin bulunduğuna bağlı olarak farklı davranmasını istiyorsanız faydalıdır. Örneğin, bir sensörün çözünürlüğünü ve maksimum ölçüm aralığını elde etmek için getResolution() ve getMaximumRange() yöntemlerini kullanabilirsiniz. Sensörün güç gereksinimlerini öğrenmek için getPower() yöntemini de kullanabilirsiniz.

Uygulamanızı farklı üreticilerin sensörleri veya bir sensörün farklı sürümleri için optimize etmek istiyorsanız, herkese açık yöntemlerden ikisi özellikle kullanışlıdır. Örneğin, uygulamanızın yatırma ve sallama gibi kullanıcı hareketlerini izlemesi gerekiyorsa belirli bir tedarikçinin yerçekimi sensörüne sahip yeni cihazlar için bir veri filtreleme kuralları ve optimizasyonları grubu, yerçekimi sensörü olmayan ve yalnızca ivme ölçere sahip cihazlar için başka bir veri filtreleme kuralları ve optimizasyonları grubu oluşturabilirsiniz. Aşağıdaki kod örneğinde, bunu yapmak için getVendor() ve getVersion() yöntemlerini nasıl kullanabileceğiniz gösterilmektedir. Bu örnekte, tedarikçi olarak Google LLC'nin listelendiği ve sürüm numarası 3 olan bir yerçekimi sensörünü arıyoruz. Söz konusu sensör cihazda yoksa ivme ölçeri kullanmaya çalışırız.

Kotlin

private lateinit var sensorManager: SensorManager
private var mSensor: Sensor? = null

...

sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) {
    val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY)
    // Use the version 3 gravity sensor.
    mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 }
}
if (mSensor == null) {
    // Use the accelerometer.
    mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    } else {
        // Sorry, there are no accelerometers on your device.
        // You can't play this game.
        null
    }
}

Java

private SensorManager sensorManager;
private Sensor mSensor;

...

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = null;

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
    List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY);
    for(int i=0; i<gravSensors.size(); i++) {
        if ((gravSensors.get(i).getVendor().contains("Google LLC")) &&
           (gravSensors.get(i).getVersion() == 3)){
            // Use the version 3 gravity sensor.
            mSensor = gravSensors.get(i);
        }
    }
}
if (mSensor == null){
    // Use the accelerometer.
    if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
        mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    } else{
        // Sorry, there are no accelerometers on your device.
        // You can't play this game.
    }
}

Faydalı bir diğer yöntem de getMinDelay() yöntemidir. Bu yöntem, bir sensörün verileri algılamak için kullanabileceği minimum zaman aralığını (mikrosaniye cinsinden) döndürür. getMinDelay() yöntemi için sıfır dışında bir değer döndüren tüm sensörler akış sensörüdür. Akış sensörleri verileri düzenli aralıklarla algılıyor ve Android 2.3'te (API Düzeyi 9) kullanıma sunulmuştur. getMinDelay() yöntemini çağırdığınızda bir sensör sıfır döndürürse bu, sensörün bir akış sensörü olmadığı anlamına gelir. Çünkü yalnızca algıladığı parametrelerde bir değişiklik olduğunda verileri rapor eder.

getMinDelay() yöntemi, bir sensörün veri alabileceği maksimum hızı belirlemenizi sağladığı için yararlıdır. Uygulamanızdaki belirli özellikler yüksek veri edinme hızları veya akış sensörü gerektiriyorsa bu yöntemi kullanarak bir sensörün bu gereksinimleri karşılayıp karşılamadığını belirleyebilir ve ardından uygulamanızdaki ilgili özellikleri uygun şekilde etkinleştirebilir veya devre dışı bırakabilirsiniz.

Dikkat: Bir sensörün maksimum veri edinme hızı, kesinlikle sensör çerçevesinin uygulamanıza sensör verilerini ilettiği hız değildir. Sensör çerçevesi, verileri sensör etkinlikleri aracılığıyla bildirir. Uygulamanızın sensör etkinliklerini alma hızı çeşitli faktörlerden etkilenir. Daha fazla bilgi için Sensör Etkinliklerini İzleme bölümüne bakın.

Sensör Etkinliklerini İzleme

Ham sensör verilerini izlemek için SensorEventListener arayüzü üzerinden açığa çıkan iki geri çağırma yöntemi uygulamanız gerekir: onAccuracyChanged() ve onSensorChanged(). Aşağıdaki durum gerçekleştiğinde Android sistemi bu yöntemleri çağırır:

Aşağıdaki kodda, ışık sensöründen gelen verileri izlemek için onSensorChanged() yönteminin nasıl kullanılacağı gösterilmektedir. Bu örnekte, ham sensör verileri main.xml dosyasında sensor_data olarak tanımlanan bir TextView içinde gösterilmektedir.

Kotlin

class SensorActivity : Activity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var mLight: Sensor? = null

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
    }

    override fun onSensorChanged(event: SensorEvent) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        val lux = event.values[0]
        // Do something with this sensor value.
    }

    override fun onResume() {
        super.onResume()
        mLight?.also { light ->
            sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}

Java

public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor mLight;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        float lux = event.values[0];
        // Do something with this sensor value.
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

Bu örnekte, registerListener() yöntemi çağrıldığında varsayılan veri gecikmesi (SENSOR_DELAY_NORMAL) belirtilmiştir. Veri gecikmesi (veya örnekleme hızı), sensör etkinliklerinin onSensorChanged() geri çağırma yöntemi aracılığıyla uygulamanıza gönderildiği aralığı kontrol eder. Varsayılan veri gecikmesi,tipik ekran yönü değişikliklerini izlemek için uygundur ve 200.000 mikrosaniyelik bir gecikmeyi kullanır. SENSOR_DELAY_GAME (20.000 mikrosaniye gecikme), SENSOR_DELAY_UI (60.000 mikrosaniye gecikme) veya SENSOR_DELAY_FASTEST (0 mikrosaniye gecikmesi) gibi başka veri gecikmeleri belirtebilirsiniz. Android 3.0 (API Düzeyi 11) sürümünden itibaren, gecikmeyi mutlak değer olarak da (mikrosaniye cinsinden) belirtebilirsiniz.

Belirttiğiniz gecikme yalnızca önerilen bir gecikmedir. Android sistemi ve diğer uygulamalar bu gecikmeyi değiştirebilir. Sistem genellikle belirttiğinizden daha küçük bir gecikme kullandığından mümkün olan en büyük gecikmeyi belirtmeniz gerekir (yani uygulamanızın ihtiyaçlarını karşılayan en yavaş örnekleme hızını seçmeniz gerekir). Daha büyük bir gecikmenin kullanılması işlemciye daha düşük bir yük oluşturur ve bu nedenle daha az güç kullanır.

Sensör çerçevesinin uygulamanıza sensör etkinliklerini gönderme hızını belirlemek için herkese açık bir yöntem yoktur. Ancak her bir sensör etkinliğiyle ilişkili zaman damgalarını kullanarak birkaç etkinlik üzerinden örnekleme hızını hesaplayabilirsiniz. Ayarladıktan sonra örnekleme hızını (gecikme) değiştirmeniz gerekmez. Herhangi bir nedenle gecikmeyi değiştirmeniz gerekirse sensörü iptal edip sensör dinleyiciyi yeniden kaydetmeniz gerekir.

Bu örneğin, sensör etkinliği işleyicisini kaydetmek ve kaydını iptal etmek için onResume() ve onPause() geri çağırma yöntemlerinin kullanıldığını da göz önünde bulundurun. En iyi uygulama olarak, özellikle etkinliğiniz duraklatıldığında ihtiyacınız olmayan sensörleri her zaman devre dışı bırakmalısınız. Bunu yapmazsanız bazı sensörlerin önemli güç gereksinimleri vardır ve pil gücünü hızlı bir şekilde tüketebilirler. Ekran kapandığında, sistem sensörleri otomatik olarak devre dışı bırakmaz.

Farklı Sensör Yapılandırmalarını İşleme

Android, cihazlar için standart bir sensör yapılandırması belirtmez. Yani, cihaz üreticileri Android destekli cihazlarına istedikleri herhangi bir sensör yapılandırmasını dahil edebilirler. Sonuç olarak, cihazlar çok çeşitli yapılandırmalarda çeşitli sensörler içerebilir. Uygulamanız belirli bir sensör türünü kullanıyorsa uygulamanızın başarılı bir şekilde çalışabilmesi için sensörün bir cihazda bulunduğundan emin olmanız gerekir.

Bir cihazda belirli bir sensörün olduğundan emin olmak için iki seçeneğiniz vardır:

  • Çalışma zamanında sensörleri algılayın ve uygulama özelliklerini uygun şekilde etkinleştirin ya da devre dışı bırakın.
  • Belirli sensör yapılandırmaları olan cihazları hedeflemek için Google Play filtrelerini kullanın.

Bu seçenekler aşağıdaki bölümlerde ele alınmaktadır.

Çalışma zamanında sensörleri algılama

Uygulamanız belirli bir tür sensör kullanıyorsa ancak bu sensöre güvenmiyorsa çalışma zamanında sensörü algılamak için sensör çerçevesini kullanabilir ve ardından uygulama özelliklerini uygun şekilde devre dışı bırakabilir veya etkinleştirebilirsiniz. Örneğin, bir navigasyon uygulaması sıcaklığı, barometrik basıncı, konumu ve pusula yönünü göstermek için sıcaklık sensörü, basınç sensörü, GPS sensörü ve jeomanyetik alan sensörünü kullanabilir. Bir cihazda basınç sensörü yoksa çalışma zamanında basınç sensörünün olmadığını tespit etmek için sensör çerçevesini kullanabilir ve ardından uygulamanızın basıncı gösteren kullanıcı arayüzünün bölümünü devre dışı bırakabilirsiniz. Örneğin, aşağıdaki kod cihazda basınç sensörü olup olmadığını kontrol eder:

Kotlin

private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) {
    // Success! There's a pressure sensor.
} else {
    // Failure! No pressure sensor.
}

Java

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){
    // Success! There's a pressure sensor.
} else {
    // Failure! No pressure sensor.
}

Belirli sensör yapılandırmalarını hedeflemek için Google Play filtrelerini kullanma

Uygulamanızı Google Play'de yayınlıyorsanız uygulamanızı uygulamanıza uygun sensör yapılandırmasına sahip olmayan cihazlardan filtrelemek için manifest dosyanızda <uses-feature> öğesini kullanabilirsiniz. <uses-feature> öğesinin, uygulamaları belirli sensörlerin varlığına göre filtrelemenizi sağlayan çeşitli donanım tanımlayıcıları vardır. Listeleyebileceğiniz sensörler şunlardır: ivme ölçer, barometre, pusula (jeomanyetik alan), jiroskop, ışık ve yakınlık. Aşağıda, ivme ölçeri olmayan uygulamaları filtreleyen bir manifest girişi örneği gösterilmektedir:

<uses-feature android:name="android.hardware.sensor.accelerometer"
              android:required="true" />

Bu öğeyi ve açıklayıcıyı uygulamanızın manifest dosyasına eklerseniz kullanıcılar uygulamanızı Google Play'de yalnızca cihazlarında ivme ölçer varsa görürler.

Tanımlayıcıyı yalnızca uygulamanız tamamen belirli bir sensöre dayanıyorsa android:required="true" olarak ayarlamalısınız. Uygulamanız bazı işlevler için sensör kullanmasına rağmen sensör olmadan çalışıyorsa sensörü <uses-feature> öğesinde listelemeniz ancak tanımlayıcıyı android:required="false" olarak ayarlamanız gerekir. Bu şekilde, cihazlar ilgili sensöre sahip olmasalar bile uygulamanızı yükleyebilirler. Uygulamanızda kullanılan özellikleri takip etmenize yardımcı olan bu en iyi proje yönetimi uygulamasıdır. Uygulamanız belirli bir sensörü kullanmasına rağmen sensör olmadan da çalışıyorsa sensörü çalışma zamanında algılamanız ve uygulama özelliklerini uygun şekilde devre dışı bırakmanız veya etkinleştirmeniz gerekir.

Sensör Koordinat Sistemi

Genel olarak sensör çerçevesi, veri değerlerini ifade etmek için standart bir 3 eksenli koordinat sistemi kullanır. Çoğu sensörde, cihaz varsayılan yönünde tutulduğunda koordinat sistemi cihazın ekranına göre tanımlanır (bkz. Şekil 1). Bir cihaz varsayılan yönünde tutulduğunda, X ekseni yatay olur ve sağa doğru, Y ekseni dikeydir ve yukarıyı, Z ekseni ise ekran yüzünün dışına işaret eder. Bu sistemde, ekranın arkasındaki koordinatlar negatif Z değerlerine sahiptir. Bu koordinat sistemi aşağıdaki sensörler tarafından kullanılır:

Şekil 1. Sensor API tarafından kullanılan koordinat sistemi (cihaza göre).

Bu koordinat sistemiyle ilgili anlaşılması gereken en önemli nokta, cihazın ekran yönü değiştiğinde eksenlerin değişmediği, yani cihaz hareket ettikçe sensörün koordinat sisteminin değişmediğidir. Bu davranış, OpenGL koordinat sisteminin davranışıyla aynıdır.

Unutulmaması gereken bir diğer nokta da uygulamanızın, cihazın doğal (varsayılan) yönünün dikey olduğunu varsaymamaktır. Birçok tabletin doğal yönü yataydır. Sensör koordinat sistemi her zaman cihazın doğal yönüne bağlıdır.

Son olarak, uygulamanız sensör verilerini ekrandaki ekranla eşleştiriyorsa ekran dönüşünü belirlemek için getRotation() yöntemini kullanmanız ve ardından sensör koordinatlarını ekran koordinatlarıyla eşlemek için remapCoordinateSystem() yöntemini kullanmanız gerekir. Manifest dosyanız yalnızca dikey görüntülemeyi belirtiyor olsa bile bunu yapmanız gerekir.

Not: Bazı sensörler ve yöntemler, cihazın referans çerçevesinin aksine, dünyanın referans çerçevesine bağlı bir koordinat sistemi kullanır. Bu sensörler ve yöntemler, cihaz hareketini veya dünyaya göre cihaz konumunu temsil eden veriler döndürür. Daha fazla bilgi için getOrientation() yöntemi, getRotationMatrix() yöntemi, Yön Sensörü ve Döndürme Vektörü Sensörü'nü inceleyin.

Sensör Hız Sınırlaması

Uygulamanız Android 12 (API düzeyi 31) veya sonraki sürümleri hedefliyorsa kullanıcılar hakkındaki hassas olabilecek bilgileri korumak için sistem, belirli hareket sensörlerinden ve konum sensörlerinden gelen verilerin yenileme hızına bir sınır uygular. Bu veriler, cihazın ivme ölçer, jiroskop ve jeomanyetik alan sensörü tarafından kaydedilen değerleri içerir.

Yenileme hızı sınırı, sensör verilerine nasıl eriştiğinize bağlıdır:

  • Sensör etkinliklerini izlemek için registerListener() yöntemini çağırırsanız sensör örnekleme hızı 200 Hz ile sınırlandırılır. Bu durum, registerListener() yönteminin tüm aşırı yüklenmiş varyantları için geçerlidir.
  • SensorDirectChannel sınıfını kullanırsanız sensör örnekleme hızı, genellikle yaklaşık 50 Hz olan RATE_NORMAL ile sınırlandırılır.

Uygulamanızın hareket sensörü verilerini daha yüksek bir hızda toplaması gerekiyorsa aşağıdaki kod snippet'inde gösterildiği gibi HIGH_SAMPLING_RATE_SENSORS iznini beyan etmeniz gerekir. Aksi takdirde, uygulamanız bu izni beyan etmeden daha yüksek bir hızda hareket sensörü verisi toplamaya çalışırsa SecurityException hatası oluşur.

AndroidManifest.xml

<manifest ...>
    <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
    <application ...>
        ...
    </application>
</manifest>

Sensörlere Erişme ve Kullanmayla İlgili En İyi Uygulamalar

Sensör uygulamanızı tasarlarken bu bölümde açıklanan yönergeleri uyguladığınızdan emin olun. Bu kurallar, sensörlere erişmek ve sensör verileri elde etmek için sensör çerçevesini kullanan herkes için önerilir.

Yalnızca ön planda sensör verilerini topla

Android 9 (API düzeyi 28) veya sonraki sürümleri çalıştıran cihazlarda arka planda çalışan uygulamalar aşağıdaki kısıtlamalara sahiptir:

Bu kısıtlamalar doğrultusunda, uygulamanız ön plandayken veya bir ön plan hizmetinin parçası olarak sensör etkinliklerini tespit etmek en iyi seçenektir.

Sensör işleyicilerin kaydını sil

Sensörü kullanmayı bitirdiğinizde veya sensör etkinliği durakladığında sensör dinleyicisinin kaydını iptal ettiğinizden emin olun. Bir sensör dinleyici kayıtlıysa ve etkinliği duraklatılmışsa sensörün kaydını iptal etmediğiniz sürece sensör veri toplamaya ve pil kaynaklarını kullanmaya devam eder. Aşağıdaki kod, bir işleyicinin kaydını iptal etmek için onPause() yönteminin nasıl kullanılacağını gösterir:

Kotlin

private lateinit var sensorManager: SensorManager
...
override fun onPause() {
    super.onPause()
    sensorManager.unregisterListener(this)
}

Java

private SensorManager sensorManager;
...
@Override
protected void onPause() {
    super.onPause();
    sensorManager.unregisterListener(this);
}

Daha fazla bilgiyi unregisterListener(SensorEventListener) sayfasında bulabilirsiniz.

Android Emülatör ile test etme

Android Emulator, ivme ölçer, ortam sıcaklığı, manyetometre, yakınlık, ışık ve diğer sensörleri test etmenizi sağlayan bir dizi sanal sensör kontrolü içerir.

Emülatör, SdkControllerSensor uygulamasını çalıştıran bir Android cihazla bağlantı kullanır. Bu uygulamanın yalnızca Android 4.0 (API düzeyi 14) veya sonraki sürümleri çalıştıran cihazlarda kullanılabildiğini unutmayın. (Cihazda Android 4.0 çalışıyorsa Düzeltme 2 yüklü olmalıdır.) SdkControllerSensor uygulaması, cihazdaki sensörlerde yapılan değişiklikleri izler ve bunları emülatöre iletir. Daha sonra emülatör, cihazınızdaki sensörlerden aldığı yeni değerlere göre dönüştürülür.

SdkControllerSensor uygulamasının kaynak kodunu aşağıdaki konumda görüntüleyebilirsiniz:

$ your-android-sdk-directory/tools/apps/SdkController

Cihazınızla emülatör arasında veri aktarmak için şu adımları izleyin:

  1. Cihazınızda USB üzerinden hata ayıklamanın etkin olduğundan emin olun.
  2. Bir USB kablosu kullanarak cihazınızı geliştirme makinenize bağlayın.
  3. Cihazınızda SdkControllerSensor uygulamasını başlatın.
  4. Uygulamada, emüle etmek istediğiniz sensörleri seçin.
  5. Aşağıdaki adb komutunu çalıştırın:

  6. $ adb forward tcp:1968 tcp:1968
    
  7. Emülatörü başlatın. Artık cihazınızı taşıyarak emülatöre dönüşüm uygulayabilirsiniz.

Not: Fiziksel cihazınızda yaptığınız hareketler emülatörü dönüştürmüyorsa 5. adımdaki adb komutunu tekrar çalıştırmayı deneyin.

Daha fazla bilgi için Android Emülatör kılavuzuna bakın.

onSensorChanged() yöntemini engellemeyin

Sensör verileri yüksek hızda değişebilir. Bu nedenle sistem, onSensorChanged(SensorEvent) yöntemini sık sık çağırabilir. En iyi uygulama olarak, onSensorChanged(SensorEvent) yöntemini engellememek için mümkün olduğunca az işlem yapmalısınız. Uygulamanız, sensör verilerini azaltma veya filtreleme gibi işlemler yapmanızı gerektiriyorsa bu işlemleri onSensorChanged(SensorEvent) yöntemi dışında gerçekleştirmelisiniz.

Desteği sonlandırılmış yöntemleri veya sensör türlerini kullanmaktan kaçının

Birçok yöntem ve sabit değer kullanımdan kaldırıldı. Özellikle, TYPE_ORIENTATION sensör türü kullanımdan kaldırıldı. Yön verileri almak için bunun yerine getOrientation() yöntemini kullanmalısınız. Benzer şekilde, TYPE_TEMPERATURE sensör türü de kullanımdan kaldırılmıştır. Android 4.0 çalıştıran cihazlarda bunun yerine TYPE_AMBIENT_TEMPERATURE sensör türünü kullanmalısınız.

Kullanmadan önce sensörleri doğrulayın

Cihazdan veri almaya çalışmadan önce her zaman cihazda bir sensörün olduğunu doğrulayın. Bir sensörün sadece sık kullanılan bir sensör olduğunu varsaymayın. Cihaz üreticilerinin, cihazlarında belirli sensörler sağlamaları gerekmez.

Sensör gecikmelerini dikkatli bir şekilde seçin

registerListener() yöntemiyle bir sensörü kaydederken uygulamanız veya kullanım alanınız için uygun bir yayınlama hızı seçtiğinizden emin olun. Sensörler çok yüksek hızlarda veri sağlayabilir. Sistemin, ihtiyacınız olmayan fazladan verileri göndermesine izin vermek, sistem kaynaklarını boşa harcar ve pil gücünü kullanır.