Sensörlere Genel Bakış

Android destekli çoğu cihazda hareketi, yönü ve çeşitli çevre koşullarını ölçen yerleşik sensörler bulunur. Bu sensörler, yüksek doğruluk ve doğrulukla ham veriler sağlayabilir. Üç boyutlu cihaz hareketini veya konumlandırmasını izlemek ya da bir cihazın yakınındaki ortam ortamındaki değişiklikleri izlemek istiyorsanız bu sensörler kullanışlıdır. Örneğin bir oyun, eğme, sallama, döndürme veya sallanma gibi karmaşık kullanıcı hareketlerini ve hareketlerini tahmin etmek için cihazın yerçekimi sensöründen gelen okumaları izleyebilir. Benzer şekilde, bir hava durumu uygulaması çiy noktasını hesaplayıp bildirmek için cihazın sıcaklık sensörünü ve nem sensörünü, seyahat uygulaması ise pusula yönünü bildirmek için jeomanyetik alan sensörünü ve ivme ölçeri kullanabilir.

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

  • Hareket sensörleri

    Bu sensörler, üç eksendeki ivme kuvvetlerini ve dönme kuvvetlerini ölçer. Bu kategori ivme ölçer, 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. Barometreler, fotometreler ve termometreler bu kategoriye dahildir.

  • Konum sensörleri

    Bu sensörler bir cihazın fiziksel konumunu ölçer. Bu kategoride yön sensörleri ve manyetometreler bulunur.

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

  • Bir cihazda hangi sensörlerin kullanılabilir olduğunu belirleme.
  • Her bir sensörün maksimum menzili, üreticisi, güç gereksinimleri ve çözünürlüğü gibi özelliklerini belirleyin.
  • Ham sensör verilerini edinin ve sensör verilerini elde ettiğiniz minimum hızı tanımlayın.
  • Sensör değişikliklerini izleyen sensör etkinlik dinleyicilerini kaydedin ve bunların kaydını iptal edin.

Bu başlıkta, Android platformunda kullanılabilen sensörlere genel bir bakış sunulmaktadır. Ayrıca sensör çerçevesi hakkında da bilgi verir.

Sensörlere Giriş

Android sensör çerçevesi sayesinde birçok sensör türüne erişebilirsiniz. Bu sensörlerin bazıları donanım, bazıları ise yazılım tabanlıdır. Donanım tabanlı sensörler, telefonlarda veya tabletlerde yerleşik olarak bulunan fiziksel bileşenlerdir. Bu mülkler, verilerini ivme, jeomanyetik alan gücü veya açısal değişim gibi belirli çevresel özellikleri doğrudan ölçerek elde eder. 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 türetir ve bazen sanal sensör ya da sentetik sensör 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 platformunun desteklediği sensörler özetlenmiştir.

Az sayıda Android destekli cihazda her tür sensör bulunur. Örneğin, çoğu mobil cihazda ve tablette ivme ölçer ve manyetometre bulunur, ancak daha az cihazda barometre veya termometre vardır. Ayrıca, bir cihaz belirli bir türde birden fazla sensöre sahip olabilir. Örneğin, bir cihazda her birinin farklı aralıklara sahip iki yer çekimi sensörü olabilir.

Tablo 1. Android platformu tarafından desteklenen sensör türleri.

Sensör Tür Açıklama Yaygın Kullanımlar
TYPE_ACCELEROMETER Donanım İvme kuvvetini, yer çekimi kuvveti de dahil olmak üzere üç fiziksel eksende (x, y ve z) bulunan cihaza uygulanan m/s2 cinsinden ölçer. Hareket algılama (sarsıntı, eğme vb.).
TYPE_AMBIENT_TEMPERATURE Donanım Ortam oda sıcaklığını santigrat derece (°C) cinsinden ölçer. Aşağıdaki nota bakın. Hava sıcaklıklarını izleme
TYPE_GRAVITY Yazılım veya Donanım Üç fiziksel eksende (x, y, z) cihaza uygulanan yer çekimi kuvvetini m/s2 cinsinden ölçer. Hareket algılama (sarsıntı, eğme vb.).
TYPE_GYROSCOPE Donanım Cihazın, üç fiziksel eksenin (x, y ve z) her biri çevresinde rad/sn cinsinden dönüş hızını ölçer. Döndürme algılama (dönme, dönüş 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ç üç fiziksel eksende (x, y ve z) bulunan cihaza uygulanan ivme kuvvetini m/s2 cinsinden ölçer. Tek bir eksendeki ivmeyi izleme.
TYPE_MAGNETIC_FIELD Donanım Üç fiziksel eksenin de (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) çevresinde yaptığı dönüş derecelerini ölçer. API seviye 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ın konumu belirleniyor.
TYPE_PRESSURE Donanım Ortam hava basıncını hPa veya mbar cinsinden ölçer. Hava basıncı değişiklikleri izleniyor.
TYPE_PROXIMITY Donanım Bir nesnenin yakınlığını, cihazın görünüm ekranına göre cm cinsinden ölçer. Bu sensör, genellikle telefonun bir kişinin kulağına tutulup tutulmadığını belirlemek için kullanılır. Çağrı sırasında telefon konumu.
TYPE_RELATIVE_HUMIDITY Donanım Bağıl ortam nemini yüzde (%) olarak ölçer. Çiy noktası, mutlak nem ve bağıl nem izleniyor.
TYPE_ROTATION_VECTOR Yazılım veya Donanım Bir cihazın yönünü, cihazın dönme vektörünün üç öğesini sağlayarak ölçer. Hareket algılama ve dönüş algılama.
TYPE_TEMPERATURE Donanım Cihazın sıcaklığını santigrat derece (°C) cinsinden ölçer. Bu sensör uygulaması cihazlar arasında değişiklik gösterir ve bu sensör, API Düzeyi 14'te TYPE_AMBIENT_TEMPERATURE sensörüyle değiştirilmiştir Sıcaklıklar izleniyor.

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 bir örneğini oluşturmak için bu sınıfı kullanabilirsiniz. Bu derste sensörlere erişmek ve sensörleri listelemek, sensör etkinliği dinleyicilerini kaydetmek/kaydetmek ve yön bilgilerini edinmek için çeşitli yöntemler sunulmaktadır. Bu sınıfta; sensör doğruluğunu raporlamak, veri edinme oranlarını belirlemek ve sensörleri kalibre etmek için kullanılan çeşitli sensör sabitleri de sağlanmaktadır.
Sensor
Belirli bir sensörün örneğini oluşturmak için bu sınıfı kullanabilirsiniz. Bu derste, sensörlerin özelliklerini belirlemenize olanak tanıyan çeşitli yöntemler sunulmaktadır.
SensorEvent
Sistem bu sınıfı kullanarak bir sensör etkinliği nesnesi oluşturur. Bu nesne, bir sensör olayı hakkında bilgi sağlar. Sensör etkinliği 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 olayları) 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 bu sensörle ilişkili API'leri kullanırsınız:

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

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

  • Sensör etkinliklerini izleme

    Sensör etkinliklerini izlemek, ham sensör verilerini elde etme yöntemidir. Bir sensör, ölçtüğü parametrelerde bir değişiklik algıladığında bir sensör etkinliği gerçekleşir. Sensör olayı dört bilgi sağlar: etkinliği tetikleyen sensörün adı, etkinliğin zaman damgası, etkinliğin doğruluğu ve ham sensör verileri.

Sensör Kullanılabilirliği

Sensör kullanılabilirliği cihazdan cihaza farklılık gösterse de Android sürümleri arasında da değişiklik gösterebilir. Bunun nedeni, Android sensörlerinin çeşitli platform sürümlerinde kullanıma sunulmuş olmasıdır. Örneğin, birçok sensör Android 1.5'te (API Düzeyi 3) kullanıma sunulmuş olsa da bazıları uygulanmadı ve Android 2.3'e (API Düzeyi 9) kadar kullanıma sunulmadı. Benzer şekilde, Android 2.3 (API Düzeyi 9) ve Android 4.0 (API Düzeyi 14) sürümlerde de çok sayıda sensör kullanıma sunulmuştur. İki sensör kullanımdan kaldırıldı ve bunların yerini daha yeni ve daha iyi sensörler aldı.

Tablo 2'de, her sensörün kullanılabilirlik durumu platform bazında özetlenmiştir. Yalnızca dört platform listeleniyor çünkü bunlar sensör değişikliklerine dahil olan platformlar. Kullanımdan kaldırılmış 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ılabilir.

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'te (API Düzeyi 3) eklenmişti ancak Android 2.3'e (API Düzeyi 9) kadar kullanılamayacaktı.

2 Bu sensör kullanılabilir, ancak kullanımdan kaldırıldı.

Sensörleri ve Sensör Yeteneklerini Tanımlama

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

Bir cihazdaki sensörleri tanımlamak 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. Örneğin:

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örün listesini alabilirsiniz. Örneğin:

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 geçirerek bir cihazda belirli bir sensör türünün olup olmadığını belirleyebilirsiniz. Bir cihazda belirli bir türde birden fazla sensör varsa 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. Bu, cihazda bu tür bir sensör olmadığı anlamına gelir. Ö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ürde sensörler eklemesini gerektirmez. Bu nedenle cihazlar çok çeşitli sensör yapılandırmaları kullanabilir.

Bir cihazdaki sensörleri listelemenin yanı sıra, bağımsız sensörlerin özelliklerini ve özelliklerini belirlemek için Sensor sınıfının herkese açık yöntemlerini kullanabilirsiniz. Uygulamanızın, bir cihazda hangi sensörlerin veya sensör özelliklerinin bulunduğuna göre farklı davranmasını istiyorsanız bu yararlı bir özelliktir. Ö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 yararlı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 optimizasyon grubu, yerçekimi sensörü olmayan ve yalnızca ivme ölçere sahip olan cihazlar için başka bir veri filtreleme kuralları ve optimizasyon 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'yi listeleyen ve sürüm numarası 3 olan bir yer çekimi sensörü 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.
    }
}

Yararlı 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 bir akış sensörüdür. Akış sensörleri, verileri düzenli aralıklarla algılar ve Android 2.3'te (API Düzeyi 9) kullanıma sunulmuştur. getMinDelay() yöntemini çağırdığınızda bir sensörün sıfır döndürmesi, sensörün 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 edinebileceği maksimum hızı belirlemenize olanak tanıdığı için yararlıdır. Uygulamanızdaki bazı özellikler için yüksek veri edinme hızları veya akış sensörü gerekiyorsa bir sensörün bu gereksinimleri karşılayıp karşılamadığını belirlemek için bu yöntemi kullanabilir ve ardından uygulamanızdaki ilgili özellikleri buna uygun şekilde etkinleştirebilir veya devre dışı bırakabilirsiniz.

Dikkat: Bir sensörün maksimum veri edinme hızı, sensör çerçevesinin uygulamanıza sensör verileri gönderme hızı değildir. Sensör çerçevesi, verileri sensör olayları aracılığıyla bildirir ve çeşitli faktörler uygulamanızın sensör etkinliklerini alma hızını etkiler. Daha fazla bilgi için Sensör Etkinliklerini İzleme bölümüne bakın.

Sensör Olaylarını İzleme

Ham sensör verilerini izlemek için SensorEventListener arayüzü üzerinden gösterilen iki geri çağırma yöntemi uygulamanız gerekir: onAccuracyChanged() ve onSensorChanged(). Aşağıdaki durumlarda 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ı), onSensorChanged() geri çağırma yöntemi aracılığıyla sensör etkinliklerinin 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 gecikme kullanır. SENSOR_DELAY_GAME (20.000 mikrosaniye gecikme), SENSOR_DELAY_UI (60.000 mikrosaniye gecikme) veya SENSOR_DELAY_FASTEST (0 mikrosaniye gecikme) gibi başka veri gecikmeleri de belirtebilirsiniz. Android 3.0 (API Düzeyi 11) sürümünden itibaren gecikmeyi mutlak değer (mikrosaniye cinsinden) olarak da belirtebilirsiniz.

Belirttiğiniz gecikme yalnızca önerilen bir gecikmedir. Android sistemi ve diğer uygulamalar bu gecikmeyi değiştirebilir. En iyi uygulama olarak mümkün olan en uzun gecikmeyi belirtmeniz gerekir. Çünkü sistem genellikle belirttiğinizden daha kısa bir gecikme kullanır (yani uygulamanızın ihtiyaçlarını hâlâ karşılayan en yavaş örnekleme hızını seçmeniz gerekir). Daha büyük bir gecikme kullanmak işlemciye daha düşük bir yük uygular ve bu nedenle daha az güç kullanır.

Sensör çerçevesinin uygulamanıza sensör etkinlikleri gönderme hızını belirlemek için herkese açık bir yöntem yoktur. Ancak çeşitli etkinlikler üzerinden örnekleme hızını hesaplamak için her bir sensör olayıyla ilişkili zaman damgalarını kullanabilirsiniz. Örnekleme hızını (gecikme) ayarladıktan sonra değiştirmeniz gerekmez. Herhangi bir nedenle gecikmeyi değiştirmeniz gerekirse sensör dinleyicisinin kaydını iptal etmeniz ve yeniden kaydetmeniz gerekir.

Bu örneğin, sensör etkinlik işleyicisini kaydetmek ve kaydını silmek için onResume() ve onPause() geri çağırma yöntemlerini kullandığını unutmamak da önemlidir. En iyi uygulama olarak, özellikle etkinliğiniz duraklatıldığında ihtiyacınız olmayan sensörleri her zaman devre dışı bırakmanız gerekir. Bazı sensörlerin çok güçlü güç gereksinimleri olması ve pilin gücünü hızlı bir şekilde tüketmesine yol açabileceğinden, bu işlemi yapmazsanız sadece birkaç saat içinde piliniz bitebilir. 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ı belirlemez. Yani, cihaz üreticileri Android destekli cihazlarına istedikleri sensör yapılandırmasını dahil edebilir. 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ıyla çalışabilmesi için sensörün bir cihazda bulunduğundan emin olmanız gerekir.

Belirli bir sensörün bir cihazda bulunduğ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 veya devre dışı bırakın.
  • Belirli sensör yapılandırmalarına sahip cihazları hedeflemek için Google Play filtrelerini kullanma

Her bir seçenek, aşağıdaki bölümlerde ele alınmıştır.

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

Uygulamanız belirli bir sensör türünü kullanmasına rağmen bu sensöre ihtiyaç duymuyorsa ç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ık, barometrik basınç, konum ve pusula yönünü görüntülemek için sıcaklık sensörünü, 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 olup olmadığını algılamak için sensör çerçevesini kullanabilir ve ardından uygulamanızın kullanıcı arayüzünün basınç gösteren 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 manifest dosyanızdaki <uses-feature> öğesini kullanarak uygulamanızı, uygulamanız için uygun sensör yapılandırmasına sahip olmayan cihazlardan filtreleyebilirsiniz. <uses-feature> öğesinde, uygulamaları belirli sensörlerin varlığına göre filtrelemenize olanak tanıyan çeşitli donanım tanımlayıcıları vardır. Listeleyebileceğiniz sensörler arasında şunlar bulunur: ivme ölçer, barometre, pusula (jeromanyetik alan), jiroskop, ışık ve yakınlık. Aşağıda, ivme ölçer bulunmayan uygulamaları filtreleyen bir manifest girişi örneği verilmiştir:

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

Bu öğeyi ve tanımlayı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ür.

Yalnızca uygulamanız tamamen belirli bir sensöre dayalıysa açıklayıcıyı android:required="true" değerine ayarlamalısınız. Uygulamanız bazı işlevler için sensör kullandığı halde sensör olmadan çalışıyorsa sensörü <uses-feature> öğesinde listelemeniz ancak açıklayıcıyı android:required="false" olarak ayarlamanız gerekir. Böylece cihazlar, belirli bir sensöre sahip olmasalar bile uygulamanızı yükleyebilirler. Bu, aynı zamanda uygulamanızın kullandığı özellikleri takip etmenize yardımcı olan proje yönetimi en iyi uygulamalarından biridir. Uygulamanız belirli bir sensör kullanmasına rağmen sensör olmadan da çalışıyorsa çalışma zamanında sensörü algılamanız ve uygulama özelliklerini devre dışı bırakmanız veya uygun şekilde etkinleştirmeniz gerektiğini unutmayın.

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ör için koordinat sistemi, cihaz varsayılan yönünde tutulduktan sonra cihazın ekranına göre tanımlanır (şekil 1'e bakın). Bir cihaz varsayılan yönünde tutulduğunda X ekseni yatay ve sağa, Y ekseni dikey ve yukarı, Z ekseni ise ekranın dış tarafına doğru 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şmemesidir. Diğer bir deyişle, cihaz hareket ettikçe sensörün koordinat sistemi hiçbir zaman değişmez. Bu davranış, OpenGL koordinat sisteminin davranışıyla aynıdır.

Anlaşılması gereken bir başka nokta da uygulamanızın, cihazın doğal (varsayılan) yönünün dikey olduğunu varsaymaması gerektiğidir. Birçok tablet cihaz için 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ştirirse 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'iniz yalnızca dikey görüntüleme belirtse 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 cihazın dünyaya göre konumunu temsil eden veriler döndürür. Daha fazla bilgi için getOrientation() yöntemi, getRotationMatrix() yöntemi, Yön Sensörü ve Rotasyon Vektör Sensörü yöntemlerini inceleyin.

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

Uygulamanız Android 12 (API düzeyi 31) veya sonraki bir sürümü 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 koyar. Bu veriler, cihazın ivme ölçeri, 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:

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 hareket sensörü verilerini daha yüksek bir hızda toplamaya çalışırsa SecurityException oluşur.

AndroidManifest.xml

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

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

Sensör uygulamanızı tasarlarken bu bölümde açıklanan yönergeleri uyguladığınızdan emin olun. Bu yönergeler, sensörlere erişmek ve sensör verileri almak için sensör çerçevesini kullanan herkes için önerilen en iyi uygulamalardır.

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:

  • İvme ölçer ve jiroskop gibi sürekli raporlama modunu kullanan sensörler etkinlik almaz.
  • Değiştirilir veya tek çekim raporlama modlarını kullanan sensörler etkinlik almaz.

Bu kısıtlamalar göz önünde bulundurulduğunda, sensör olaylarını uygulamanız ön plandayken veya bir ön plan hizmetinin parçası olarak tespit etmek en iyi seçenektir.

Sensör dinleyicilerinin kaydını iptal et

Sensör kullanmayı bitirdiğinizde veya sensör etkinliği durduğunda sensör dinleyicisinin kaydını iptal ettiğinizden emin olun. Kayıtlı bir sensör dinleyicisi varsa ve etkinliği duraklatılırsa sensör, kaydını iptal etmediğiniz sürece veri almaya 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 bilgi için unregisterListener(SensorEventListener) inceleyin.

Android Emülatör ile test etme

Android Emülatör'de ivme ölçer, ortam sıcaklığı, manyetometre, yakınlık ve ışık gibi sensörleri test etmenizi sağlayan sanal sensör kontrolleri bulunur.

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 kullanılıyorsa Düzeltme 2 yüklü olmalıdır.) SdkControllerSensor uygulaması, cihazdaki sensörlerde gerçekleşen değişiklikleri izleyip 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ı uygulayın:

  1. Cihazınızda USB hata ayıklama özelliğinin etkin olduğundan emin olun.
  2. Cihazınızı bir USB kablosuyla 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üşümler uygulayabilirsiniz.

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

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

onSensorChanged() yöntemini engellemeyin

Sensör verileri yüksek bir hızda değişebilir. Bu durum, sistemin onSensorChanged(SensorEvent) yöntemini oldukça sık çağırabileceği anlamına gelir. 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 filtreleme veya azaltma işlemleri yapmanızı gerektiriyorsa bu işlemi onSensorChanged(SensorEvent) yönteminin dışında yapmanız gerekir.

Kullanımdan kaldırılan yöntemleri veya sensör türlerini kullanmaktan kaçının

Birçok yöntem ve sabit değer kullanımdan kaldırılmıştır. Özellikle, TYPE_ORIENTATION sensör türü kullanımdan kaldırılmıştır. Yön verilerini almak için bunun yerine getOrientation() yöntemini kullanmanız gerekir. 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

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

Sensör gecikmelerini dikkatlice seçin

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