Android işletim sistemli ç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 hassasiyet ve doğrulukla ham veri sağlayabilir. Üç boyutlu cihaz hareketini veya konumunu izlemek ya da bir cihazın yakınındaki ortamdaki değişiklikleri izlemek istiyorsanız bu sensörlerden yararlanabilirsiniz. Örneğin, bir oyun; eğim, 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ı çiy 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 kategoriye ivme ölçerler, yerçekimi sensörleri, jiroskoplar ve dönme vektörü sensörleri dahildir.
- Çevre sensörleri
Bu sensörler, ortam hava sıcaklığı ve basıncı, aydınlatma ve nem gibi çeşitli çevre parametrelerini ölçer. Bu 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 edinebilirsiniz. Sensör çerçevesi, sensörle ilgili ç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 şunları yapabilirsiniz:
- Bir cihazda hangi sensörlerin kullanılabildiğini belirleyin.
- 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 edindiğiniz minimum hızı tanımlayın.
- Sensör değişikliklerini izleyen sensör etkinliği işleyicilerini kaydedin ve kaydedilmelerini iptal edin.
Bu konuda, Android platformunda bulunan sensörlere genel bir bakış sunulmaktadır. Ayrıca sensör çerçevesine giriş de sağlar.
Sensörlere Giriş
Android sensör çerçevesi, birçok türde sensöre erişmenize olanak tanır. Bu sensörlerin bazıları donanıma, bazıları ise yazılıma dayanır. Donanım tabanlı sensörler, cep telefonuna veya tablet cihaza yerleştirilmiş fiziksel bileşenlerdir. Verilerini, hızlanma, jeomanyetik alan gücü veya açısal değişim gibi belirli çevresel özellikleri doğrudan ölçerek elde ederler. Donanım tabanlı sensörleri taklit etmesine rağmen yazılım tabanlı sensörler fiziksel cihaz değildir. Yazılım tabanlı sensörler, verilerini donanım tabanlı sensörlerden bir veya daha fazlasından alır ve bazen sanal sensörler ya da sentetik sensörler olarak adlandırılır. Doğrusal hızlanma sensörü ve yerçekimi sensörü, yazılım tabanlı sensörlere örnek olarak verilebilir. Tablo 1'de Android platformu tarafından desteklenen sensörler özetlenmiştir.
Android destekli cihazların çoğunda her tür sensör bulunmaz. Örneğin, çoğu cep telefonu ve tablette ivme ölçer ve manyetometre bulunur ancak daha az sayıda cihazda barometre veya termometre bulunur. Ayrıca, bir cihazda belirli bir türde birden fazla sensör bulunabilir. Örneğin, bir cihazda her biri farklı bir aralığa sahip iki yerçekimi sensörü olabilir.
Sensör | Tür | Açıklama | Yaygın Kullanımlar |
---|---|---|---|
TYPE_ACCELEROMETER |
Donanım | Yer çekimi kuvveti dahil olmak üzere üç fiziksel eksende (x, y ve z) bir cihaza uygulanan ivme kuvvetini m/s2 cinsinden ölçer. | Hareket algılama (sallanma, eğme vb.). |
TYPE_AMBIENT_TEMPERATURE |
Donanım | Ortam oda sıcaklığını santigrat derece (°C) cinsinden ölçer. Aşağıdaki notu inceleyin. | Hava sıcaklıklarını izleme |
TYPE_GRAVITY |
Yazılım veya Donanım | Üç fiziksel eksende (x, y, z) bir cihaza uygulanan yerçekimi kuvvetini m/s2 cinsinden ölçer. | Hareket algılama (sallanma, eğme vb.). |
TYPE_GYROSCOPE |
Donanım | Bir cihazın üç fiziksel eksenin (x, y ve z) her biri etrafındaki rad/s cinsinden dönme hızını ölçer. | Döndürme algılama (dönme, döndürme vb.). |
TYPE_LIGHT |
Donanım | Ortam ışığı seviyesini (aydınlatma) lx cinsinden ölçer. | Ekran parlaklığını kontrol etme. |
TYPE_LINEAR_ACCELERATION |
Yazılım veya Donanım | Yer çekimi kuvveti hariç olmak üzere, bir cihaza üç fiziksel eksende (x, y ve z) uygulanan ivme kuvvetini m/s2 cinsinden ölçer. | Tek bir eksende ivmeyi izleme. |
TYPE_MAGNETIC_FIELD |
Donanım | Üç fiziksel eksenin (x, y, z) etrafındaki manyetik alanı μT cinsinden ö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önme matrisini elde edebilirsiniz. |
Cihaz konumunu belirleme. |
TYPE_PRESSURE |
Donanım | Ortam hava basıncını hPa veya mbar cinsinden ölçer. | Hava basıncındaki değişiklikleri izleme. |
TYPE_PROXIMITY |
Donanım | Bir nesnenin cihazın görüntü ekranına göre yakınlığını cm cinsinden ölçer. Bu sensör genellikle bir telefonun kulağa doğru tutulup tutulmadığını belirlemek için kullanılır. | Telefonun arama sırasındaki konumu. |
TYPE_RELATIVE_HUMIDITY |
Donanım | Bağıl ortam nemini yüzde cinsinden (%) ölçer. | Çiy noktası, mutlak nem ve bağıl nemi izleme. |
TYPE_ROTATION_VECTOR |
Yazılım veya Donanım | Cihazın dönme vektörünün üç öğesini sağlayarak cihazın yönünü ölçer. | Hareket algılama ve dönme algılama. |
TYPE_TEMPERATURE |
Donanım | Cihazın sıcaklığını santigrat derece (°C) cinsinden ölçer. Bu sensör uygulaması cihazlara göre değişir ve API düzeyi 14'te bu sensör 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 verilerini edinebilirsiniz.
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şmek ve sensörleri listelemek, sensör etkinliği dinleyicilerini kaydetmek ve kayıtlarını iptal etmek ve yön bilgilerini edinmek için çeşitli yöntemler sağlar. 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, bir sensör etkinliği hakkında bilgi sağlayan bir sensör etkinliği nesnesi oluşturmak için bu sınıfı kullanır. Sensör etkinliği nesnesi aşağıdaki bilgileri içerir: ham sensör verileri, etkinliği oluşturan sensör 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 etkinliği) 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 sensörleri ve sensör özelliklerini çalışma zamanında tanımlamak faydalıdır. Örneğin, bir cihazdaki tüm sensörleri tanımlamak ve mevcut olmayan sensörlere dayanan 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 tanımlamak isteyebilirsiniz.
- Sensör etkinliklerini izleme
Ham sensör verilerini, sensör etkinliklerini izleyerek elde edersiniz. Bir sensör, ölçtüğü parametrelerde her değişiklik algıladığında bir sensör etkinliği gerçekleşir. Sensör etkinlikleri dört tür bilgi sağlar: etkinliği tetikleyen sensörün adı, etkinliğin zaman damgası, etkinliğin doğruluğu ve etkinliği tetikleyen ham sensör verileri.
Sensör Kullanılabilirliği
Sensör kullanılabilirliği cihaza göre değişse de Android sürümlerine göre de değişebilir. Bunun nedeni, Android sensörlerinin birkaç platform sürümünde kullanıma sunulmasıdır. Örneğin, Android 1.5'te (API düzeyi 3) birçok sensör kullanıma sunulmuştur ancak bazı sensörler uygulanmamış ve Android 2.3'e (API düzeyi 9) kadar kullanılamamıştır. Benzer şekilde, 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 daha yeni, daha iyi sensörlerle değiştirildi.
Tablo 2'de her sensörün platform bazında kullanılabilirliği özetlenmiştir. Yalnızca dört platform listelenir. Bunlar, sensör değişiklikleri içeren platformlardır. Desteği sonlandırılmış olarak listelenen sensörler, sonraki platformlarda (sensörün bir cihazda bulunması koşuluyla) kullanılmaya devam eder. Bu durum, Android'in ileriye dönük uyumluluk politikasıyla uyumludur.
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'e (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, her sensörün özelliklerini (ör. maksimum menzili, çözünürlüğü ve güç gereksinimleri) belirlemenize olanak tanıyan yöntemler de sağlar.
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. Örnek:
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. Örnek:
Kotlin
val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
Java
List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
Belirli bir türdeki tüm sensörleri listelemek 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 type sabit değerini ileterek 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 döndürür. Bu, cihazda bu tür bir sensör olmadığı anlamına gelir. Örneğin, aşağıdaki kod bir cihazda mıknatısölçer 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 sensör türleri yerleştirmesini zorunlu tutmaz. Bu nedenle, cihazlarda çok çeşitli sensör yapılandırmaları bulunabilir.
Bir cihazdaki sensörleri listelemenin yanı sıra, ayrı sensörlerin özelliklerini ve özelliklerini belirlemek için Sensor
sınıfının herkese açık yöntemlerini kullanabilirsiniz. Bu, uygulamanızın bir cihazda hangi sensörlerin veya sensör özelliklerinin kullanılabildiğine bağlı olarak farklı davranmasını istiyorsanız yararlı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 elde etmek için getPower()
yöntemini de kullanabilirsiniz.
Herkese açık yöntemlerden ikisi, 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ğilme ve sallama gibi kullanıcı hareketlerini izlemesi gerekiyorsa belirli bir tedarikçinin yerçekimi sensörüne sahip olan yeni cihazlar için bir veri filtreleme kuralı ve optimizasyon grubu, yerçekimi sensörü olmayan ve yalnızca ivmeölçer bulunan cihazlar için de başka bir veri filtreleme kuralı 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'nin listelendiği 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 yararlı 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 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 döndürüyorsa yalnızca algıladığı parametrelerde bir değişiklik olduğunda veri bildirdiği için akış sensörü değildir.
getMinDelay()
yöntemi, bir sensörün veri edinebileceğ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 bir sensörün bu koşulları 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 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 raporlar 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ü aracılığıyla 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şir.
Bu durumda sistem,
onAccuracyChanged()
yöntemini çağırır ve değişenSensor
nesnesine ve sensörün yeni doğruluğuna dair bir referans 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
. - Bir sensör yeni bir değer bildirir.
Bu durumda sistem,
onSensorChanged()
yöntemini çağırarak size birSensorEvent
nesnesi sağlar.SensorEvent
nesnesi, yeni sensör verileri hakkında aşağıdakiler gibi bilgiler içerir: verilerin doğruluğu, verilerin oluşturulduğu sensör, verilerin oluşturulduğu zaman damgası ve sensörün kaydettiği yeni veriler.
Aşağıdaki kodda, onSensorChanged()
yönteminin ışık sensöründen gelen verileri izlemek için nasıl kullanılacağı gösterilmektedir. Bu örnekte, main.xml dosyasında sensor_data
olarak tanımlanan bir TextView
içinde ham sensör verileri 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ı), onSensorChanged()
geri arama yöntemi aracılığıyla sensör etkinliklerinin 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 (API seviyesi 11) itibarıyla gecikmeyi mutlak değer olarak da (mikrosaniye cinsinden) belirtebilirsiniz.
Belirttiğiniz gecikme yalnızca önerilen bir gecikmedir. Android sistemi ve diğer uygulamalar bu gecikmeyi değiştirebilir. Sistem genellikle belirttiğinizden daha küçük bir gecikme kullandığı için en iyi uygulama olarak 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 kullanmak, işlemciye daha az yük bindirir ve dolayısıyla 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, çeşitli etkinliklerdeki örnekleme hızını hesaplamak için her sensör etkinliğiyle ilişkili zaman damgalarını kullanabilirsiniz. Bir kez ayarladıktan sonra örnekleme hızını (gecikme) 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 etkinliği dinleyicisini kaydetmek ve kaydını iptal etmek için onResume()
ve onPause()
geri çağırma yöntemlerinin kullanıldığını da belirtmek önemlidir. En iyi uygulama olarak, özellikle de etkinliğiniz duraklatıldığında ihtiyacınız olmayan sensörleri her zaman devre dışı bırakmanız gerekir. Bazı sensörlerin önemli güç gereksinimleri olduğundan ve pil gücünü hızlı bir şekilde tüketebildiğinden, bunu yapmamak pilin 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ı işleme
Android, cihazlar için standart bir sensör yapılandırması belirtmez. Bu, cihaz üreticilerinin istedikleri sensör yapılandırmasını Android destekli cihazlarına dahil edebileceği anlamına gelir. Sonuç olarak, cihazlar çok çeşitli yapılandırmalarda çeşitli sensörler içerebilir. Uygulamanız belirli bir sensör türünü kullanıyorsa uygulamanızın başarılı bir şekilde çalışabilmesi için bu 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:
- Sensörleri çalışma zamanında 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.
Sensörleri çalışma zamanında algılama
Uygulamanız belirli bir sensör türünü kullanıyor ancak bu sensöre ihtiyaç duymuyorsa sensörü çalışma zamanında 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ü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 yokluğunu algılamak için sensör çerçevesini kullanabilir ve ardından uygulamanızın kullanıcı arayüzünde basıncı gösteren kısmı 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ı, uygulamanız için uygun sensör yapılandırmasına sahip olmayan cihazlardan 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 şunlardır: ivme ölçer, barometre, pusula (jeomanyetik alan), jiroskop, ışık ve yakınlık. Aşağıda, ivmeölçer içermeyen 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 dayanıyorsa android:required="true"
olarak ayarlamanız gerekir. Uygulamanız bazı işlevler için sensör kullanıyorsa 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 olmasalar bile cihazların uygulamanızı yükleyebilmesi sağlanır. 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ıyorsa ancak sensör olmadan çalışmaya devam ediyorsa 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önde tutulduğunda cihazın ekranına göre tanımlanır (bkz. Şekil 1). Cihaz varsayılan yönde tutulduğunda X ekseni yataydır ve sağa, Y ekseni dikeydir ve yukarı, Z ekseni ise ekran yüzeyinin dışına doğru yönlendirilir. 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:
- İvmelenme sensörü
- Yerçekimi sensörü
- Jiroskop
- Doğrusal ivmelenme sensörü
- Jeomanyetik alan algılayıcısı
Bu koordinat sistemiyle ilgili en önemli nokta, cihazın ekran yönü değiştiğinde eksenlerin değiştirilmemesidir. Yani sensörün koordinat sistemi, cihaz hareket ettikçe hiçbir zaman 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. Sensör koordinat sistemi her zaman cihazın doğal yönüne dayanır.
Son olarak, uygulamanız sensör verilerini ekrandaki görüntüyle eşleşiyorsa ekran dönüşünü 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 bunu yapmanız gerekir.
Not: Bazı sensörler ve yöntemler, cihazın referans çerçevesinin aksine dünyanın referans çerçevesine göre 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öntemine, getRotationMatrix()
yöntemine, Yönleme Sensörü'ne ve Dönme Vektörü Sensörü'ne bakın.
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örlerinden ve konum sensörlerinden gelen verilerin yenilenme hızını sınırlandırır. Bu veriler, cihazın ivme ölçeri, jiroskopu ve jeomanyetik alan algılayıcısı 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ırlıdır. Bu durum,registerListener()
yönteminin tüm aşırı yüklenen varyantları için geçerlidir. SensorDirectChannel
sınıfını kullanıyorsanız sensör örnekleme hızı genellikle yaklaşık 50 Hz olanRATE_NORMAL
ile sınırlı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
iznine sahip olduğunuzu belirtmeniz 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.
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Sensörlere Erişme ve Sensörleri Kullanma ile İlgili En İyi Uygulamalar
Sensör uygulamanızı tasarlarken bu bölümde açıklanan 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 verileri 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şiklik olduğunda veya tek seferlik bildirme 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 hizmeti kapsamında algılamak en iyisidir.
Sensör dinleyicilerinin kaydını iptal etme
Sensörü kullanmayı bıraktığınızda veya sensör etkinliği duraklatıldığında sensörün dinleyicisinin kaydını sildiğinizden emin olun. Bir sensör dinleyicisi kaydedilirse ve etkinliği duraklatılırsa sensörün kaydını silmediğiniz sürece sensör 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 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ılabileceğini unutmayın. (Cihaz Android 4.0 kullanıyorsa 2. Düzeltme sürümü yüklü olmalıdır.) SdkControllerSensor uygulaması, cihazdaki sensörlerdeki 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ıklama özelliğinin etkinleştirildiğinden emin olun.
- Cihazınızı USB kablosuyla 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ürme işlemlerini emülatöre uygulayabilirsiniz.
$ adb forward tcp:1968 tcp:1968
Not: Fiziksel cihazınızda yaptığınız hareketler emülatörde dönüşüm yapmı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 oldukça sık çağırabilir. 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 gerçekleştirmeniz gerekir.
Desteği sonlandırılan yöntemleri veya sensör türlerini kullanmaktan kaçının
Bazı yöntemlerin ve sabitlerin desteği sonlandırıldı.
Özellikle TYPE_ORIENTATION
sensör türü kullanımdan kaldırıldı. Yön verileri almak için bunun yerine getOrientation()
yöntemini kullanmalısınız. Benzer şekilde, TYPE_TEMPERATURE
sensör türü de kullanımdan kaldırıldı. Android 4.0 yüklü 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 her zaman cihazda sensör bulunduğundan emin olun. Sık kullanılan bir sensör olduğu için var olduğunu varsaymayın. Cihaz üreticilerinin cihazlarında belirli sensörler sağlaması gerekmez.
Sensör gecikmeleri dikkatli bir şekilde seçilmelidir.
Bir sensörü registerListener()
yöntemiyle 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ı ve pil gücünü tüketir.