Android destekli çoğu cihazda hareketi, yönü ve çeşitli ortam koşullarını ölçen yerleşik sensörler bulunur. Bu sensörler, yüksek hassasiyet ve doğrulukla ham veri sağlayabilir. Üç boyutlu cihaz hareketini veya konumunu ya da cihazın yakınındaki ortamda meydana gelen değişiklikleri izlemek istiyorsanız bu sensörler kullanışlıdır. Örneğin, bir oyun, cihazın yerçekimi sensöründen gelen değerleri izleyerek eğme, sallama, döndürme veya sallandırma gibi karmaşık kullanıcı hareketlerini ve hareketlerini tahmin edebilir. Benzer şekilde, bir hava durumu uygulaması, çiğ noktasını hesaplamak ve bildirmek için cihazın sıcaklık sensörünü ve nem sensörünü kullanabilir veya bir seyahat uygulaması, pusula yönünü bildirmek için jeomanyetik alan sensörünü ve ivme ölçeri kullanabilir.
Aşağıdaki ilgili kaynaklara göz atın:
Android platformu üç geniş sensör kategorisini destekler:
- Hareket sensörü
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 sıcaklığı ve basıncı, aydınlatma ve nem gibi çeşitli çevresel parametreleri ölçer. Bu kategoriye barometreler, fotometreler ve termometreler dahildir.
- Konum sensörleri
Bu sensörler, cihazın fiziksel konumunu ölçer. Bu kategori, yön sensörlerini ve manyetometreleri içerir.
Android sensör çerçevesini kullanarak cihazdaki sensörlere erişebilir ve ham sensör verilerini alabilirsiniz. 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 sağlar. Örneğin, sensör çerçevesini kullanarak aşağıdakileri yapabilirsiniz:
- Cihazda hangi sensörlerin bulunduğunu belirleme
- Maksimum menzil, üretici, güç gereksinimleri ve çözünürlük gibi tek bir sensörün özelliklerini belirleme
- Ham sensör verilerini alın ve sensör verilerini alacağınız minimum hızı tanımlayın.
- Sensör değişikliklerini izleyen sensör etkinlik işleyicileri kaydetme ve kaydını silme
Bu konuda, Android platformunda kullanılabilen sensörlere genel bir bakış sunulmaktadır. Ayrıca sensör çerçevesine giriş niteliğinde bilgiler de sunulur.
Sensörlere Giriş
Android sensör çerçevesi, birçok sensör türüne erişmenize olanak tanır. Bu sensörlerin bazıları donanım tabanlı, bazıları ise yazılım tabanlıdır. Donanım tabanlı sensörler, cep telefonu veya tablet cihazlara yerleştirilmiş fiziksel bileşenlerdir. Verilerini, ivme, jeomanyetik alan gücü veya açısal değişim gibi belirli çevresel özellikleri doğrudan ölçerek elde ederler. 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 bir veya daha fazla donanım tabanlı sensörden alır ve bazen sanal sensörler veya sentetik sensörler olarak adlandırılır. Doğrusal ivme sensörü ve yerçekimi sensörü, yazılım tabanlı sensörlere örnek verilebilir. Tablo 1'de Android platformu tarafından desteklenen sensörler özetlenmiştir.
Android destekli cihazların çok azında her tür sensör bulunur. Örneğin, çoğu mobil cihazda ve tablette ivme ölçer ve manyetometre bulunur ancak barometre veya termometre bulunan cihaz sayısı daha azdır. Ayrıca bir cihazda belirli bir türden birden fazla sensör bulunabilir. Örneğin, bir cihazda her biri farklı bir aralığa 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 | Yer çekimi kuvveti de dahil olmak üzere üç fiziksel eksenin (x, y ve z) tümünde bir cihaza uygulanan ivme kuvvetini m/s2 cinsinden ölçer. | Hareket algılama (sallama, eğme vb.) |
TYPE_AMBIENT_TEMPERATURE |
Donanım | 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 | Bir cihaza üç fiziksel eksenin (x, y, z) tümünde uygulanan yerçekimi kuvvetini m/sn2 cinsinden ölçer. | Hareket algılama (sallama, eğme vb.) |
TYPE_GYROSCOPE |
Donanım | Bir cihazın üç fiziksel eksenin (x, y ve z) her birinin etrafındaki dönüş hızını rad/sn cinsinden ölçer. | Dönüş algılama (dönme, dönüş vb.) |
TYPE_LIGHT |
Donanım | Ambiyans ışığı seviyesini (aydınlatma) lüks cinsinden ölçer. | Ekran parlaklığını kontrol etme |
TYPE_LINEAR_ACCELERATION |
Yazılım veya Donanım | Yer çekimi kuvveti hariç olmak üzere, bir cihaza üç fiziksel eksenin (x, y ve z) tümünde uygulanan ivme kuvvetini m/sn.2 cinsinden ölçer. | Tek bir eksen boyunca ivmeyi izleme. |
TYPE_MAGNETIC_FIELD |
Donanım | Üç fiziksel eksenin (x, y, z) tümü için ortam jeomanyetik alanını μT cinsinden ölçer. | Pusula oluşturma |
TYPE_ORIENTATION |
Yazılım | Bir cihazın üç fiziksel eksen (x, y, z) etrafında yaptığı dönüş derecelerini ölçer.
API düzeyi 3'ten itibaren, getRotationMatrix() yöntemiyle birlikte yerçekimi sensörünü 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şikliklerini izleme. |
TYPE_PROXIMITY |
Donanım | Bir nesnenin cihazın görüntüleme ekranına olan yakınlığını santimetre cinsinden ölçer. Bu sensör genellikle bir telefonun kişinin kulağına tutulup tutulmadığını belirlemek için kullanılır. | Arama sırasında telefonun konumu. |
TYPE_RELATIVE_HUMIDITY |
Donanım | Bağıl ortam nemini yüzde (%) olarak ölçer. | Çiğ noktası, mutlak nem ve bağıl nemi izleme |
TYPE_ROTATION_VECTOR |
Yazılım veya Donanım | Cihazın dönüş vektörünün üç öğesini sağlayarak cihazın yönünü ö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ün uygulanma şekli cihazlar arasında farklılık 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 verilerini alabilirsiniz.
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- Bu sınıfı kullanarak sensör hizmetinin bir örneğini oluşturabilirsiniz. Bu sınıf; sensörlere erişme ve sensörleri listeleme, sensör etkinlik işleyicilerini kaydetme ve kaydını silme, yön bilgisi alma gibi çeşitli yöntemler sunar. Bu sınıf, sensör doğruluğunu bildirmek, veri alma hızlarını ayarlamak ve sensörleri kalibre etmek için kullanılan çeşitli sensör sabitleri de 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ı kullanarak sensör etkinliği hakkında bilgi sağlayan bir sensör etkinliği nesnesi oluşturur. 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- Bu arayüzü kullanarak, sensör değerleri veya sensör doğruluğu değiştiğinde bildirim (sensör etkinlikleri) alan iki geri çağırma yöntemi oluşturabilirsiniz.
Tipik bir uygulamada, sensörle ilgili bu API'leri iki temel görevi gerçekleştirmek için kullanırsınız:
- Sensörleri ve sensör özelliklerini belirleme
Uygulamanızda belirli sensör türlerine veya özelliklerine dayalı ö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örleri kullanan uygulama özelliklerini devre dışı bırakmak isteyebilirsiniz. Benzer şekilde, uygulamanız için en iyi performansa sahip sensör uygulamasını seçebilmek amacıyla belirli bir türdeki tüm sensörleri tanımlamak isteyebilirsiniz.
- Sensör etkinliklerini izleme
Sensör etkinliklerini izleyerek ham sensör verilerini elde edersiniz. Bir sensör, ölçtüğü parametrelerde bir değişiklik algıladığında sensör etkinliği gerçekleşir. Sensör etkinliği size dört 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örlerin kullanılabilirliği cihazdan cihaza ve Android sürümleri arasında farklılık gösterebilir. Bunun nedeni, Android sensörlerinin birkaç platform sürümü boyunca kullanıma sunulmuş olmasıdır. Örneğin, Android 1.5'te (API düzeyi 3) birçok sensör kullanıma sunulmuş olsa da bazıları Android 2.3'e (API düzeyi 9) kadar uygulanmamış ve kullanıma sunulmamıştır. Benzer şekilde, Android 2.3 (API düzeyi 9) ve Android 4.0'da (API düzeyi 14) çeşitli sensörler kullanıma sunulmuştur. İki sensör kullanımdan kaldırıldı ve yerlerine daha yeni, daha iyi sensörler getirildi.
Tablo 2'de, her bir sensörün platform bazında kullanılabilirliği özetlenmektedir. Yalnızca sensör değişiklikleri içeren dört platform listelenir. Desteği sonlandırılmış olarak listelenen sensörler, Android'in ileriye dönük uyumluluk politikasına uygun olarak sonraki platformlarda da kullanılabilir (sensörün cihazda mevcut olması koşuluyla).
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ş ancak Android 2.3'e (API düzeyi 9) kadar kullanıma sunulmamıştır.
2 Bu sensör kullanılabilir ancak desteği sonlandırılmıştır.
Sensörleri ve Sensör Özelliklerini Tanımlama
Android sensör çerçevesi, çalışma zamanında bir cihazda hangi sensörlerin bulunduğunu kolayca belirlemenizi sağlayan çeşitli yöntemler sunar. API ayrıca her sensörün maksimum menzili, çözünürlüğü ve güç gereksinimleri gibi özelliklerini belirlemenize olanak tanıyan yöntemler de sağlar.
Bir cihazdaki sensörleri tanımlamak için öncelikle sensör hizmetine referans almanız gerekir. Bunun 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);
Ardından, getSensorList() yöntemini çağırıp TYPE_ALL sabitini kullanarak cihazdaki her 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 istiyorsanız TYPE_ALL yerine TYPE_GYROSCOPE, TYPE_LINEAR_ACCELERATION veya TYPE_GRAVITY gibi başka bir sabit kullanabilirsiniz.
Ayrıca, getDefaultSensor() yöntemini kullanarak ve belirli bir sensör için tür sabitini ileterek bir cihazda belirli bir sensör türünün mevcut olup olmadığını belirleyebilirsiniz. Bir cihazda belirli bir türden birden fazla sensör varsa sensörlerden biri varsayılan sensör olarak belirlenmelidir. Belirli bir sensör türü için varsayılan bir 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, 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 yerleştirmesini zorunlu kılmaz. Bu nedenle, cihazlar çok çeşitli sensör yapılandırmalarına sahip olabilir.
Bir cihazdaki sensörleri listelemenin yanı sıra, sensörlerin özelliklerini ve niteliklerini belirlemek için Sensor sınıfının herkese açık yöntemlerini kullanabilirsiniz. Bu, uygulamanızın bir cihazda bulunan sensörlere veya sensör özelliklerine göre farklı davranmasını istediğinizde kullanışlı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. Bir 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 eğme 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ı kümesi, yerçekimi sensörü olmayan ve yalnızca ivme ölçeri olan cihazlar için başka bir veri filtreleme kuralları ve optimizasyonları kümesi 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. } }
Bir diğer kullanışlı yöntem ise bir sensörün verileri algılamak için kullanabileceği minimum zaman aralığını (mikrosaniye cinsinden) döndüren getMinDelay() yöntemidir. 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ılar ve Android 2.3 (API düzeyi 9) sürümünde kullanıma sunulmuştur. getMinDelay() yöntemini çağırdığınızda bir sensör sıfır döndürüyorsa bu, sensörün akış sensörü olmadığı anlamına gelir. Çünkü sensör, yalnızca algıladığı parametrelerde değişiklik olduğunda veri bildirir.
getMinDelay() yöntemi, bir sensörün veri alabileceği maksimum hızı belirlemenize olanak tanıdığı için kullanışlıdır. Uygulamanızdaki belirli özellikler yüksek veri alma hızları veya akış sensörü gerektiriyorsa 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 göre etkinleştirebilir veya devre dışı bırakabilirsiniz.
Dikkat: Bir sensörün maksimum veri alma hızı, sensör çerçevesinin sensör verilerini uygulamanıza ilettiği hız olmayabilir. Sensör çerçevesi, verileri sensör etkinlikleri aracılığıyla bildirir ve uygulamanızın sensör etkinliklerini alma hızını çeşitli faktörler etkiler. Daha fazla bilgi için Sensör Etkinliklerini İzleme başlıklı makaleyi inceleyin.
Sensör Etkinliklerini İzleme
Ham sensör verilerini izlemek için SensorEventListener arayüzü üzerinden sunulan iki geri çağırma yöntemini uygulamanız gerekir: onAccuracyChanged() ve onSensorChanged(). Android sistemi, aşağıdaki durumlarda bu yöntemleri çağırır:
- Sensörün doğruluğu değiştiğinde
Bu durumda sistem,
onAccuracyChanged()yöntemini çağırarak size değişenSensornesnesine bir referans ve sensörün yeni doğruluğunu sağlar. Doğruluk, dört durum sabitinden biriyle temsil edilir:SENSOR_STATUS_ACCURACY_LOW,SENSOR_STATUS_ACCURACY_MEDIUM,SENSOR_STATUS_ACCURACY_HIGH, veyaSENSOR_STATUS_UNRELIABLE. - Sensör yeni bir değer bildirir.
Bu durumda sistem,
onSensorChanged()yöntemini çağırarak size birSensorEventnesnesi sağlar.SensorEventnesnesi, yeni sensör verileriyle ilgili bilgileri içerir. Bu bilgiler arasında verilerin doğruluğu, verileri oluşturan sensör, verilerin oluşturulduğu zaman damgası ve sensörün kaydettiği yeni veriler yer alı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) belirtilir. Veri gecikmesi (veya örnekleme hızı), sensör etkinliklerinin onSensorChanged() geri çağırma yöntemi aracılığıyla uygulamanıza gönderilme aralığını 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'dan (API düzeyi 11) 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. Sistem genellikle belirttiğinizden daha kısa bir gecikme süresi kullandığından, en iyi uygulama olarak belirtebileceğiniz en uzun gecikme süresini belirtmeniz gerekir (yani uygulamanızın ihtiyaçlarını karşılayan en yavaş örnekleme hızını seçmeniz gerekir). Daha uzun bir gecikme süresi kullanmak, işlemciye daha az yük bindirir 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 birkaç etkinlikte örnekleme hızını hesaplamak için her sensör etkinliğiyle 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 edip yeniden kaydetmeniz gerekir.
Bu örnekte, sensör etkinlik işleyicisini kaydetmek ve kaydını silmek için onResume() ve onPause() geri çağırma yöntemlerinin kullanıldığını da belirtmek gerekir. 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 önemli ölçüde güç gereksinimleri olduğundan ve pil gücünü hızla tüketebileceğinden, bunu yapmamak pilin yalnızca birkaç saat içinde tükenmesine neden olabilir. Sistem, ekran kapandığında 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. Bu nedenle, cihaz üreticileri Android destekli cihazlarına istedikleri sensör yapılandırmasını dahil edebilirler. Bu nedenle cihazlar, çok çeşitli yapılandırmalarda farklı sensörler içerebilir. Uygulamanız belirli bir sensör türüne bağlıysa uygulamanızın başarıyla çalışabilmesi için sensörün cihazda bulunduğundan emin olmanız gerekir.
Belirli bir sensörün cihazda mevcut 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 veya devre dışı bırakın.
- Belirli sensör yapılandırmalarına sahip cihazları hedeflemek için Google Play filtrelerini kullanın.
Her 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ü kullanıyor ancak bu sensöre bağlı değilse sensör çerçevesini kullanarak sensörü çalışma zamanında algılayabilir 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ö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ı algılamak için sensör çerçevesini kullanabilir ve ardından uygulamanızın kullanıcı arayüzünün basıncı gösteren kısmını devre dışı bırakabilirsiniz. Örneğin, aşağıdaki kod bir 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 için uygun sensör yapılandırmasına sahip olmayan cihazları filtrelemek amacıyla manifest dosyanızda <uses-feature>
öğesini kullanabilirsiniz. <uses-feature> öğesinde, uygulamaları belirli sensörlerin varlığına göre filtrelemenize olanak tanıyan çeşitli donanım tanımlayıcıları bulunur. Listeyebileceğ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 örnek bir manifest giriş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.
Tanımlayıcıyı yalnızca uygulamanız tamamen belirli bir sensöre bağlıysa android:required="true" olarak ayarlamanız gerekir. Uygulamanız bazı işlevler için sensör kullanıyor ancak sensör olmadan da çalışıyorsa sensörü <uses-feature> öğesinde listelemeniz ancak tanımlayıcıyı android:required="false" olarak ayarlamanız gerekir. Bu sayede, söz konusu sensöre sahip olmayan cihazlar da uygulamanızı yükleyebilir. Bu, uygulamanızın kullandığı özellikleri takip etmenize yardımcı olan bir proje yönetimi en iyi uygulamasıdır.
Uygulamanız belirli bir sensörü kullanıyor ancak 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 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 tutulduğunda cihazın ekranına göre tanımlanır (bkz. Şekil 1). Cihaz varsayılan yönünde tutulduğunda X ekseni yataydır ve sağa, Y ekseni dikey olup yukarı, Z ekseni ise ekran yüzeyinin dışına doğru bakar. Bu sistemde, ekranın arkasındaki koordinatların Z değerleri negatiftir. Bu koordinat sistemi aşağıdaki sensörler tarafından kullanılır:
Şekil 1. Sensor API tarafından kullanılan koordinat sistemi (bir 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. Yani 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 diğer 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ın doğal yönü yataydır. Sensör koordinat sistemi her zaman cihazın doğal yönünü temel alır.
Son olarak, uygulamanız sensör verilerini ekrandaki görüntüyle eşleştiriyorsa ekran rotasyonunu belirlemek için getRotation() yöntemini, sensör koordinatlarını ekran koordinatlarıyla eşlemek için de remapCoordinateSystem() yöntemini kullanmanız gerekir. Manifestiniz yalnızca dikey ekranı belirtse bile bunu yapmanız gerekir.
Not: Bazı sensörler ve yöntemler, dünyanın referans çerçevesine (cihazın referans çerçevesine kıyasla) göre bir koordinat sistemi kullanır. Bu sensörler ve yöntemler, cihazın hareketini veya cihazın dünyaya göre konumunu temsil eden veriler döndürür. Daha fazla bilgi için getOrientation() yöntemine, getRotationMatrix() yöntemine, Yön Sensörü'ne ve Dönüş Vektörü Sensörü'ne bakın.
Sensör Sıklık Sınırlaması
Uygulamanız Android 12 (API düzeyi 31) veya sonraki sürümleri hedefliyorsa sistem, kullanıcılarla ilgili hassas olabilecek bilgileri korumak için belirli hareket sensörlerinden ve konum sensörlerinden gelen verilerin yenileme hızını sınırlandırır. Bu veriler, cihazın ivme ölçeri, jiroskopu 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ırlanır. Bu,registerListener()yönteminin tüm aşırı yüklenmiş varyantları için geçerlidir. SensorDirectChannelsınıfını kullanırsanız sensör örnekleme hızıRATE_NORMALile sınırlanır. Bu değer genellikle yaklaşık 50 Hz'dir.
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ü verileri 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şme ve Sensörleri Kullanmayla İlgili En İyi Uygulamalar
Sensör uygulamanızı tasarlarken bu bölümde ele alınan kurallara uyduğunuzdan emin olun. Bu yönergeler, sensörlere erişmek ve sensör verilerini almak için sensör çerçevesini kullanan herkes için önerilen en iyi uygulamalardır.
Sensör verilerini yalnızca ön planda toplama
Android 9 (API düzeyi 28) veya sonraki sürümlerin yüklü olduğu cihazlarda, arka planda çalışan uygulamalar aşağıdaki kısıtlamalara tabidir:
- Sürekli raporlama modunu kullanan sensörler (ör. ivme ölçerler ve jiroskoplar) etkinlikleri almaz.
- Değişiklik olduğunda veya tek seferlik raporlama modlarını kullanan sensörler etkinlik almaz.
Bu kısıtlamalar göz önüne alındığında, sensör etkinliklerini uygulamanız ön plandayken veya bir ön plan hizmetinin parçası olarak algılamak en iyisidir.
Sensör işleyicilerin kaydını silme
Sensörü kullanmayı bıraktığınızda veya sensör etkinliği duraklatıldığında sensörün dinleyicisinin kaydını iptal etmeyi unutmayın. Bir sensör dinleyici kaydedilirse 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 kodda, bir dinleyicinin kaydını iptal etmek için onPause() yönteminin nasıl kullanılacağı gösterilmektedir:
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) sayfasına bakın.
Android Emulator ile test etme
Android Emulator; ivme ölçer, ortam sıcaklığı, manyetometre, yakınlık, ışık ve daha fazlası gibi sensörleri test etmenize olanak tanıyan 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 yüklüyse düzeltme 2'nin yüklü olması gerekir.) SdkControllerSensor uygulaması, cihazdaki sensörlerde yapılan değişiklikleri izler ve bunları emülatöre iletir. Ardından 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ız ile emülatör arasında veri aktarmak için aşağıdaki adımları uygulayın:
- Cihazınızda USB üzerinden hata ayıklamanın etkinleştirildiğinden emin olun.
- USB kablosu kullanarak cihazınızı geliştirme makinenize bağlayın.
- Cihazınızda SdkControllerSensor uygulamasını başlatın.
- Uygulamada, emüle etmek istediğiniz sensörleri seçin.
Aşağıdaki
adbkomutunu çalıştırın:- Emülatörü başlatın. Artık cihazınızı hareket ettirerek emülatöre dönüşüm uygulayabilirsiniz.
$ adb forward tcp:1968 tcp:1968
Not: Fiziksel cihazınızda yaptığınız hareketler emülatörü değiştirmiyorsa 5. adımdaki adb komutunu tekrar çalıştırmayı deneyin.
Daha fazla bilgi için Android Emulator kılavuzuna bakın.
onSensorChanged() yöntemini engellemeyin
Sensör verileri yüksek bir hızda değişebilir. Bu da 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 bu yöntemde mümkün olduğunca az işlem yapmanız gerekir. Uygulamanız, sensör verilerini filtrelemenizi veya azaltmanı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.
Bazı yöntemler ve sabitler kullanımdan kaldırıldı.
Özellikle TYPE_ORIENTATION sensör türü kullanımdan kaldırıldı. Yön verilerini almak için getOrientation() yöntemini kullanmanız gerekir. Benzer şekilde, TYPE_TEMPERATURE sensör türü de kullanımdan kaldırıldı. Android 4.0 çalıştıran cihazlarda bunun yerine TYPE_AMBIENT_TEMPERATURE sensör türünü kullanmanız gerekir.
Sensörleri kullanmadan önce doğrulama
Bir cihazdan veri almaya çalışmadan önce cihazda sensör olup olmadığını her zaman doğrulayın. Sık kullanılan bir sensör olduğu için bir sensörün var olduğunu varsaymayın. Cihaz üreticilerinin, cihazlarında belirli sensörleri sağlaması gerekmez.
Sensör gecikmelerini dikkatli seçin
registerListener() yöntemiyle bir sensör kaydettiğinizde uygulamanıza veya kullanım alanınıza 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 ek veriler göndermesine izin vermek, sistem kaynaklarını boşa harcar ve pil gücü tüketir.