Android destekli çoğu cihazda hareket, yön ve çeşitli çevre koşullarını ölçen yerleşik sensörler bulunur. Bu sensörler yüksek hassasiyet ve doğrulukta ham veriler sağlayabilir. Üç boyutlu cihaz hareketini veya konumlandırmasını izlemek ya da bir 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, eğme, sallama, döndürme veya sallanma gibi karmaşık kullanıcı hareketlerini ve hareketlerini anlamak için cihazın yer çekimi sensöründen gelen okumaları izleyebilir. Benzer şekilde, bir hava durumu uygulaması çiğlenme noktasını hesaplayıp bildirmek için cihazın sıcaklık sensörünü ve nem sensörünü kullanabilir. Bir seyahat uygulaması ise 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örleri
Bu sensörler, üç eksen boyunca ivme kuvvetlerini ve dönme kuvvetlerini ölçer. Bu kategori; ivme ölçerleri, yerçekimi sensörlerini, 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 çevresel parametreleri ölçer. Bu kategoriye barometreler, fotometreler ve termometreler dahildir.
- Konum sensörleri
Bu sensörler, bir cihazın fiziksel konumunu ölçer. Bu kategori, yön sensörlerini ve manyetometreleri içerir.
Android sensör çerçevesini kullanarak cihazda bulunan sensörlere erişebilir ve ham sensör verileri elde edebilirsiniz. Sensör çerçevesi, çeşitli sensörle ilgili 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 şunları yapabilirsiniz:
- Bir cihazda hangi sensörlerin kullanılabildiğini belirleyin.
- Maksimum aralık, üretici, güç gereksinimleri ve çözünürlük gibi tek bir sensörün özelliklerini belirleyin.
- 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şleyicilerini kaydetme ve kaydını silme.
Bu konuda, Android platformunda bulunan 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, 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ıma dayalı sensörler, bir cep telefonuna veya tablet cihaza 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ıma dayalı sensörler, donanıma dayalı sensörleri taklit etse de fiziksel cihazlar değildir. Yazılıma dayalı sensörler, verilerini donanıma dayalı bir veya daha fazla 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ıma dayalı sensörlere örnek olarak verilebilir. 1. tabloda 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 cep telefonu ve tablette ivme ölçer ve manyetometre bulunur ancak daha az cihazda barometre veya termometre bulunur. Ayrıca, bir cihazda belirli bir türden birden fazla sensör olabilir. Örneğin, bir cihazda her biri farklı 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/sn2 cinsinden ölçer. | Hareket algılama (sallama, eğme vb.) |
TYPE_AMBIENT_TEMPERATURE |
Donanım | Ortam 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 eksende (x, y, z) 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 biri etrafındaki dönme hızını rad/sn cinsinden ölçer. | Dönme algılama (dönme, çevirme 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, bir cihaza üç fiziksel eksende (x, y ve z) uygulanan ivme kuvvetini m/sn2 cinsinden ölçer. | Tek bir eksen boyunca hızlanmayı izleme. |
TYPE_MAGNETIC_FIELD |
Donanım | μT cinsinden üç fiziksel eksenin (x, y, z) tümü için ortamdaki jeomanyetik alanı ölçer. | Pusula oluşturma |
TYPE_ORIENTATION |
Yazılım | Bir cihazın üç fiziksel eksenin (x, y, z) etrafında yaptığı dönme 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 konumunu belirleme |
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 bir nesnenin yakınlığını cm cinsinden ölçer. Bu sensör genellikle bir cep telefonunun 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öndürme 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 derece (°C) cinsinden ölçer. Bu sensörün uygulanması cihazlara göre değişir ve bu sensör, API düzeyi 14'te TYPE_AMBIENT_TEMPERATURE sensörüyle değiştirilmiştir. |
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 bir örneğini oluşturmak için bu sınıfı kullanabilirsiniz. Bu sınıf, sensörlere erişme ve sensörleri listeleme, sensör etkinliği işleyicilerini kaydetme ve kaydını iptal etme, yön bilgisi edinme gibi çeşitli yöntemler sunar. Bu sınıf, sensör doğruluğunu bildirmek, veri edinme 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. Bir 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
- Bu arayüzü, 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 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 belirleme
Uygulamanızda belirli sensör türlerine veya özelliklerine dayalı işlevler varsa çalışma zamanında sensörleri ve sensör özelliklerini tanımlamak yararlı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çebilmek amacıyla belirli bir türdeki tüm sensörleri belirlemek isteyebilirsiniz.
- Sensör etkinliklerini izleme
Ham sensör verilerini elde etmek için sensör etkinliklerini izlemeniz gerekir. 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ün Kullanılabilirliği
Sensörlerin kullanılabilirliği cihazdan cihaza değiştiği gibi Android sürümleri arasında da 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ştu ancak bazıları uygulanmamış ve Android 2.3'e (API düzeyi 9) kadar kullanılamamıştı. Ayrıca, Android 2.3 (API düzeyi 9) ve Android 4.0 (API düzeyi 14) sürümlerinde çeşitli sensörler kullanıma sunulmuştur. İki sensörün desteği sonlandırıldı ve bu sensörlerin yerini daha yeni ve daha iyi sensörler aldı.
Tablo 2'de her sensörün platform bazında kullanılabilirliği özetlenmektedir. Yalnızca dört platform listelenir. Bunun nedeni, sensör değişikliklerinin bu platformlarda yapılmış olmasıdır. Kullanımdan kaldırılmış olarak listelenen sensörler, Android'in ileriye dönük uyumluluk politikası doğrultusunda, sensörün cihazda bulunması koşuluyla sonraki platformlarda 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 | geçerli değil1 | geçerli değil1 |
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 | geçerli değil1 | geçerli değil1 |
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ılamamış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 belirlemenizi kolaylaştıran çeşitli yöntemler sunar. API ayrıca her bir sensörün özelliklerini (ör. maksimum aralığı, çözünürlüğü ve güç gereksinimleri) belirlemenize olanak tanıyan yöntemler de sunar.
Bir cihazdaki sensörleri tanımlamak için önce 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);
Ardından, getSensorList()
yöntemini çağırıp TYPE_ALL
sabitini kullanarak bir 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 olup olmadığını da 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 sensör yoksa yöntem çağrısı null değerini döndürür. Bu, cihazda söz konusu sensör türünün 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 yerleştirmesini zorunlu kılmaz. Bu nedenle, cihazlarda çok çeşitli sensör yapılandırmaları olabilir.
Bir cihazdaki sensörleri listelemenin yanı sıra, tek tek sensörlerin özelliklerini ve niteliklerini belirlemek için Sensor
sınıfının herkese açık yöntemlerini kullanabilirsiniz. Uygulamanızın, cihazda hangi sensörlerin veya sensör özelliklerinin bulunduğuna bağlı olarak farklı şekilde davranmasını istiyorsanız bu özellikten yararlanabilirsiniz. Ö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.
Herkese açık iki yöntem, uygulamanızı farklı üreticilerin sensörleri veya bir sensörün farklı sürümleri için optimize etmek istiyorsanız özellikle yararlıdır. Örneğin, uygulamanızın eğme ve sallama gibi kullanıcı hareketlerini izlemesi gerekiyorsa belirli bir satıcının yerçekimi sensörüne sahip yeni cihazlar için bir dizi veri filtreleme kuralı ve optimizasyon, yerçekimi sensörü olmayan ve yalnızca ivmeölçere sahip cihazlar için ise başka bir dizi veri filtreleme kuralı ve optimizasyon oluşturabilirsiniz. Aşağıdaki kod örneğinde, bu işlemi yapmak için getVendor()
ve getVersion()
yöntemlerini nasıl kullanabileceğiniz gösterilmektedir. Bu örnekte, satıcı olarak Google LLC'yi listeleyen ve sürüm numarası 3 olan bir yerçekimi sensörü arıyoruz. İlgili 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 yararlı yöntem ise 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 olmayan 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'te (API düzeyi 9) kullanıma sunulmuştur. Bir sensör, getMinDelay()
yöntemini çağırdığınızda sıfır değeri döndürüyorsa bu, sensörün yalnızca algıladığı parametrelerde değişiklik olduğunda veri bildirdiği için akış sensörü olmadığı anlamına gelir.
getMinDelay()
yöntemi, bir sensörün veri elde edebileceği maksimum hızı belirlemenize olanak tanıdığı için kullanışlı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 şartları karşılayıp karşılamadığını belirleyebilir, ardından uygulamanızdaki ilgili özellikleri buna göre etkinleştirebilir veya devre dışı bırakabilirsiniz.
Dikkat: Bir sensörün maksimum veri edinme 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öntemi uygulamanız gerekir: onAccuracyChanged()
ve onSensorChanged()
. Android sistemi, aşağıdakiler gerçekleştiğinde bu yöntemleri çağırır:
- Sensörün doğruluğu değişir.
Bu durumda sistem,
onAccuracyChanged()
yöntemini çağırarak değişenSensor
nesnesine ve sensörün yeni doğruluğuna referans sağlar. Doğruluk, dört durum sabitinden biriyle gösterilir:SENSOR_STATUS_ACCURACY_LOW
,SENSOR_STATUS_ACCURACY_MEDIUM
,SENSOR_STATUS_ACCURACY_HIGH
, veyaSENSOR_STATUS_UNRELIABLE
. - Bir sensör yeni bir değer bildiriyor.
Bu durumda sistem,
onSensorChanged()
yöntemini çağırarak sizeSensorEvent
nesnesi sağlar. BirSensorEvent
nesnesi, 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 TextView
içinde gösteriliyor. TextView
, main.xml dosyasında sensor_data
olarak tanımlanıyor.
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 arama yöntemiyle uygulamanıza gönderildiği aralığı kontrol eder. Varsayılan veri gecikmesi,normal 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 Seviyesi 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. En iyi uygulama olarak, sistem genellikle belirttiğinizden daha küçük bir gecikme kullandığı için mümkün olan en büyük gecikmeyi belirtmeniz gerekir (yani, uygulamanızın ihtiyaçlarını karşılamaya devam eden 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üç tüketir.
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ç etkinlikteki örnekleme hızını hesaplamak için her bir sensör etkinliğiyle ilişkili zaman damgalarını kullanabilirsiniz. Örnekleme hızını (gecikme) ayarladıktan sonra değiştirmeniz gerekmez. Gecikmeyi değiştirmeniz gerekirse sensör işleyicisinin kaydını silip yeniden kaydetmeniz gerekir.
Bu örnekte, sensör etkinliği 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ırakmalısınız. Bazı sensörler önemli ölçüde güç gerektirdiğinden ve pil gücünü hızlı bir şekilde tüketebildiğinden bu yapılmadığı takdirde pil birkaç saat içinde bitebilir. 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 edebilir. Bu nedenle, cihazlar çok çeşitli yapılandırmalarda çeşitli sensörler içerebilir. Uygulamanız belirli bir sensör türüne bağlıysa uygulamanızın başarılı bir şekilde çalışabilmesi için sensörün cihazda bulunduğundan emin olmanız gerekir.
Belirli bir sensörün 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 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 ç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östermek için sıcaklık sensörünü, basınç sensörünü, GPS sensörünü 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 bölümü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 cihazlarda uygulamanızı filtrelemek üzere manifest dosyanızdaki <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. Listeleyebileceğiniz sensörler arasında şunlar bulunur:
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 verilmiştir:
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Bu öğeyi ve tanımlayıcıyı uygulamanızın manifestine eklerseniz kullanıcılar uygulamanızı Google Play'de yalnızca cihazlarında ivmeölçer varsa görür.
Uygulamanız tamamen belirli bir sensöre bağlıysa tanımlayıcıyı yalnızca android:required="true"
olarak ayarlamalısınız. Uygulamanız bazı işlevler için sensör kullanıyorsa ancak sensör olmadan da çalışıyorsa sensörü <uses-feature>
öğesinde listelemeli ancak tanımlayıcıyı android:required="false"
olarak ayarlamalısınız. Bu sayede, cihazlar söz konusu sensöre sahip olmasalar bile 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ü kullanmasına rağmen sensör olmadan da çalışıyorsa çalışma zamanında sensörü 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örde koordinat sistemi, cihaz varsayılan yönünde tutulduğunda cihazın ekranına göre tanımlanır (bkz. Şekil 1). Bir cihaz varsayılan yönünde tutulduğunda X ekseni yataydır ve sağa doğru, Y ekseni dikey ve yukarı doğru, Z ekseni ise ekran yüzünün dışına doğru yönlendirilir. 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:

1.şekil Sensör API'si tarafından kullanılan koordinat sistemi (cihaza göre).
Bu koordinat sistemiyle ilgili olarak anlaşılması gereken en önemli nokta, cihazın ekran yönü değiştiğinde eksenlerin yerinin değiştirilmediğidir. Yani cihaz hareket ettikçe sensörün koordinat sistemi asla değişmez. Bu davranış, OpenGL koordinat sisteminin davranışıyla aynıdır.
Anlamanız 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. Ayrıca, sensör koordinat sistemi her zaman cihazın doğal yönüne göre belirlenir.
Son olarak, uygulamanız sensör verilerini ekrandaki gösterimle eşleştiriyorsa ekran döndürmeyi belirlemek için getRotation()
yöntemini, ardından sensör koordinatlarını ekran koordinatlarıyla eşlemek için remapCoordinateSystem()
yöntemini kullanmanız gerekir. Manifest dosyanızda yalnızca dikey ekran belirtilmiş olsa bile bu işlemi yapmanız gerekir.
Not: Bazı sensörler ve yöntemler, cihazın referans çerçevesine kıyasla dünyanın referans çerçevesine göreceli 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, Oryantasyon Sensörü ve Dönüş Vektörü Sensörü başlıklı makaleleri inceleyin.
Sensör Hızı Sınırlaması
Uygulamanız Android 12'yi (API düzeyi 31) veya sonraki sürümleri hedefliyorsa sistem, kullanıcılarla ilgili hassas olabilecek bilgileri korumak için belirli hareket sensörleri ve konum sensörlerinden gelen verilerin yenileme sıklığına sınır koyar. 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:
registerListener()
yöntemini sensör etkinliklerini izlemek için ç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.SensorDirectChannel
sınıfını kullanıyorsanız sensör örnekleme hızıRATE_NORMAL
ile sınırlıdı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 hareket sensörü verilerini daha yüksek bir hızda 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 Sensörleri Kullanmayla İlgili En İyi Uygulamalar
Sensör uygulamanızı tasarlarken bu bölümde ele alınan yönergelere uyduğunuzdan emin olun. Bu yönergeler, sensörlere erişmek ve sensör verileri elde etmek için sensör çerçevesini kullanan herkes için önerilen en iyi uygulamalardır.
Yalnızca ön planda sensör verilerini toplama
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 tabidir:
- İvme ölçerler ve jiroskoplar gibi sürekli raporlama modunu kullanan sensörler etkinlik almaz.
- Değişiklikte 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 ön plan hizmetinin bir parçası olarak algılamanız en iyisidir.
Sensör işleyicilerinin kaydını iptal etme
Sensörü kullanmayı bitirdiğinizde veya sensör etkinliği durakladığında sensörün dinleyicisinin kaydını kaldırdığınızdan emin olun. Bir sensör dinleyicisi kaydedilmişse ve etkinliği duraklatılmışsa sensörün kaydını silmediğiniz sürece veri almaya ve pil kaynaklarını kullanmaya devam eder. Aşağıdaki kodda, bir işleyicinin kaydını silmek 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 emülatörüyle test etme
Android Emulator, ivme ölçer, ortam sıcaklığı, manyetometre, yakınlık ve ışık gibi sensörleri test etmenize olanak tanıyan bir dizi sanal sensör kontrolü içerir.
Emülatör, SdkControllerSensor uygulamasının yüklü olduğu 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 2. revizyon yüklü olmalıdır.) SdkControllerSensor uygulaması, cihazdaki sensörlerdeki 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 şu 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 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, taklit etmek istediğiniz sensörleri seçin.
Aşağıdaki
adb
komutunu çalıştırın:- Emülatörü başlatın. Artık cihazınızı hareket ettirerek dönüştürmeleri emülatöre uygulayabilirsiniz.
$ adb forward tcp:1968 tcp:1968
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 Emulator kılavuzuna bakın.
onSensorChanged() yöntemini engellemeyin
Sensör verileri yüksek bir 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 bu yöntem içinde mümkün olduğunca az işlem yapmalısınız. Uygulamanızda veri filtreleme veya sensör verilerinde azaltma yapmanız gerekiyorsa bu işlemi onSensorChanged(SensorEvent)
yöntemi dışında gerçekleştirmeniz gerekir.
Kullanımdan kaldırılan yöntemleri veya sensör türlerini kullanmaktan kaçının
Çeşitli yöntemler ve sabitler kullanımdan kaldırıldı.
Özellikle TYPE_ORIENTATION
sensör türü kullanımdan kaldırıldı. Yönlendirme verilerini almak için bunun yerine getOrientation()
yöntemini kullanmanız gerekir. Aynı ş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 bulunduğunu her zaman doğrulayın. Sık kullanılan bir sensör olduğu için sensörün var olduğunu varsaymayın. Cihaz üreticilerinin cihazlarında belirli sensörler bulundurması gerekmez.
Sensör gecikmelerini dikkatli bir şekilde seçin
Bir sensörü registerListener()
yöntemiyle kaydederken uygulamanız veya kullanım alanınız için uygun bir yayın 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ın boşa harcanmasına ve pil gücünün kullanılmasına neden olur.