Android destekli cihazların çoğunda hareketi, yönü ve çeşitli çevre koşullarını ölçen yerleşik sensörler bulunur. Bu sensörler, yüksek doğruluk ve doğrulukta ham veri sağlayabilir. Üç boyutlu cihaz hareketini veya konumlandırmasını izlemek ya da bir cihazın yakınında bulunan ortam ortamındaki değişiklikleri izlemek istiyorsanız kullanışlıdır. Örneğin, bir oyun; yatırma, sallama, döndürme veya salıncak 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 bir cihazın sıcaklık sensörü 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 kaynakları inceleyin:
Android platformu, üç geniş kapsamlı sensör kategorisini destekler:
- Hareket sensörleri
Bu sensörler, üç eksen boyunca ivme kuvvetlerini ve dönme kuvvetlerini ölçer. Bu kategori ivme ölçer, yer çekimi sensörleri, jiroskoplar ve dönme vektör sensörlerini içerir.
- Çevre sensörleri
Bu sensörler ortam hava sıcaklığı ve basıncı, aydınlatma, nem gibi çeşitli çevresel parametreleri ölçer. Barometreler, fotometreler ve termometreler bu kategoriye dahildir.
- Konum sensörleri
Bu sensörler bir cihazın fiziksel konumunu ölçer. Bu kategoride yön sensörleri ve manyetometreler bulunur.
Android sensör çerçevesini kullanarak cihazda bulunan sensörlere erişebilir ve ham sensör verilerini elde edebilirsiniz. Sensör çerçevesi, sensörle ilgili çok çeşitli görevleri yerine getirmenize yardımcı olan çeşitli sınıflar ve arayüzler sunar. Örneğin, aşağıdakileri yapmak için sensör çerçevesini kullanabilirsiniz:
- Bir cihazda hangi sensörlerin kullanılabilir olduğunu belirleme.
- Bağımsız bir sensörün özelliklerini (ör. maksimum menzil, üretici, güç gereksinimleri ve çözünürlük) belirleyin.
- Ham sensör verilerini edinin ve sensör verilerini elde ettiğiniz minimum hızı tanımlayın.
- Sensör değişikliklerini izleyen sensör etkinliği dinleyicilerini kaydedin ve kaydını iptal edin.
Bu bölümde, Android platformunda kullanılabilen sensörlere genel bir bakış sunulmaktadır. Ayrıca sensör çerçevesiyle ilgili de temel bilgiler yer almaktadır.
Sensörlere Giriş
Android sensör çerçevesi, birçok sensör türüne erişmenizi sağlar. Bu sensörlerin bazıları donanım tabanlı, bazıları ise yazılım tabanlıdır. Donanım tabanlı sensörler, telefonlarda veya tabletlerde yerleşik fiziksel bileşenlerdir. Bu analizler ivme, jeomanyetik alan gücü veya açısal değişim gibi belirli çevresel özellikleri doğrudan ölçerek verilerini elde eder. Yazılım tabanlı sensörler, donanım tabanlı sensörleri taklit etmelerine rağmen fiziksel cihazlar değildir. Yazılım tabanlı sensörler, verilerini donanım tabanlı bir veya daha fazla sensörden türetir ve bazen sanal sensö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 örnektir. Tablo 1'de Android platformunun desteklediği sensörler özetlenmiştir.
Her tür sensöre sahip olan az sayıda Android destekli cihaz vardır. Örneğin, çoğu mobil cihazda ve tablette ivme ölçer ve manyetometre bulunur, ancak barometre veya termometre olan cihaz sayısı daha azdır. Ayrıca, bir cihaz belirli bir türde birden fazla sensöre sahip olabilir. Örneğin, bir cihazda her biri farklı mesafeye sahip iki yerçekimi sensörü bulunabilir.
Sensör | Tür | Açıklama | Yaygın Kullanımlar |
---|---|---|---|
TYPE_ACCELEROMETER |
Donanım | Yer çekimi kuvveti de dahil olmak üzere üç fiziksel eksende (x, y ve z) bir cihaza uygulanan ivme kuvvetini m/s2 cinsinden ölçer. | Hareket algılama (sarsıntı, yatırma vb.). |
TYPE_AMBIENT_TEMPERATURE |
Donanım | Ortam oda sıcaklığını santigrat derece (°C) cinsinden ölçer. Aşağıdaki nota bakın. | Hava sıcaklıkları izleniyor. |
TYPE_GRAVITY |
Yazılım veya Donanım | Bir cihaza üç fiziksel eksende de (x, y, z) uygulanan yer çekimi kuvvetini m/sn2 cinsinden ölçer. | Hareket algılama (sarsıntı, yatırma vb.). |
TYPE_GYROSCOPE |
Donanım | Cihazın üç fiziksel eksenin (x, y ve z) her biri çevresinde rad/sn cinsinden dönüş hızını ölçer. | Döndürme algılama (dönme, dönüş vb.). |
TYPE_LIGHT |
Donanım | Ortam ışığı seviyesini (aydınlatma) lx cinsinden ölçer. | Ekran parlaklığı kontrol ediliyor. |
TYPE_LINEAR_ACCELERATION |
Yazılım veya Donanım | Yer çekimi kuvveti hariç üç fiziksel eksende (x, y ve z) bir cihaza uygulanan ivme kuvvetini m/s2 cinsinden ölçer. | Tek bir eksendeki hızlanmayı izleme. |
TYPE_MAGNETIC_FIELD |
Donanım | Üç fiziksel eksenin de (x, y, z) μT cinsinden ortam jeomanyetik alanını ölçer. | Pusula oluşturuluyor. |
TYPE_ORIENTATION |
Yazılım | Bir cihazın üç fiziksel eksenin de (x, y, z) çevresinde yaptığı dönüş derecelerini ölçer.
API 3. seviyeden 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ın konumu belirleniyor. |
TYPE_PRESSURE |
Donanım | Ortam hava basıncını hPa veya mbar cinsinden ölçer. | Hava basıncı değişiklikleri izleniyor. |
TYPE_PROXIMITY |
Donanım | Bir nesnenin yakınlığını, cihazın görünüm ekranına göre cm cinsinden ölçer. Bu sensör, genellikle telefonun bir kişinin kulağına tutulup tutulmadığını belirlemek için kullanılır. | Arama sırasında telefonun konumu. |
TYPE_RELATIVE_HUMIDITY |
Donanım | Bağıl ortam nemini yüzde (%) cinsinden ölçer. | Çiy noktası, mutlak nem ve bağıl nem izleniyor. |
TYPE_ROTATION_VECTOR |
Yazılım veya Donanım | Bir cihazın yönünü ölçmek için cihazın dönme vektörünün üç öğesini sağlar. | Hareket algılama ve dönüş algılama. |
TYPE_TEMPERATURE |
Donanım | Cihazın sıcaklığını Santigrat (°C) cinsinden ölçer. Bu sensör uygulaması 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 izleniyor. |
Sensör Çerçevesi
Android sensör çerçevesini kullanarak bu sensörlere erişebilir ve ham sensör verileri elde edebilirsiniz.
Sensör çerçevesi, android.hardware
paketinin bir parçasıdır ve aşağıdaki sınıfları ve arayüzleri içerir:
SensorManager
- Bu sınıfı sensör hizmetinin bir örneğini oluşturmak için kullanabilirsiniz. Bu derste, sensörlere erişmek ve sensörleri listelemek, sensör etkinliği dinleyicilerini kaydetmek ve silmek, yön bilgisi edinmek için çeşitli yöntemler sunulmaktadır. Bu sınıf ayrıca sensör doğruluğunu raporlamak, veri edinme oranlarını ayarlamak ve sensörleri kalibre etmek için kullanılan çeşitli sensör sabitleri sağlar.
Sensor
- Bu sınıfı belirli bir sensörün örneğini oluşturmak için kullanabilirsiniz. Bu derste, bir sensörün yeteneklerini belirleyebilmenizi sağlayan çeşitli yöntemler sunulmaktadır.
SensorEvent
- Sistem, bu sınıfı sensör etkinliği nesnesi hakkında bilgi sağlayan bir sensör etkinliği nesnesi oluşturmak için kullanır. 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
- Sensör değerleri değiştiğinde veya sensör doğruluğu değiştiğinde bildirim (sensör olayları) alan iki geri çağırma yöntemi oluşturmak için bu arayüzü kullanabilirsiniz.
Tipik bir uygulamada iki temel görevi gerçekleştirmek için bu sensörle ilgili API'leri kullanırsınız:
- Sensörleri ve sensör özelliklerini belirleme
Uygulamanızın belirli sensör türlerine veya özelliklerine dayanan özellikleri varsa çalışma zamanında sensörlerin ve sensör özelliklerinin tanımlanması yararlı olur. Örneğin, bir cihazda bulunan tüm sensörleri tanımlamak ve mevcut olmayan sensörlere dayalı uygulama özelliklerini devre dışı bırakmak isteyebilirsiniz. Benzer şekilde, uygulamanız için optimum performansa sahip sensör uygulamasını seçmek amacıyla belirli bir türdeki tüm sensörleri tanımlamak isteyebilirsiniz.
- Sensör etkinliklerini izleme
Sensör etkinliklerini izlemek, ham sensör verilerini elde etme şeklinizdir. Bir sensör, ölçtüğü parametrelerde bir değişiklik algıladığında bir sensör etkinliği gerçekleşir. Sensör etkinliği size dört bilgi parçası sunar: etkinliği tetikleyen sensörün adı, etkinliğin zaman damgası, etkinliğin doğruluğu ve ham sensör verileri.
Sensör Kullanılabilirliği
Sensör kullanılabilirliği cihazdan cihaza farklılık gösterse de Android sürümleri arasında da değişiklik gösterebilir. Bunun nedeni, Android sensörlerinin çeşitli platform sürümlerinde kullanıma sunulmasıdır. Örneğin, birçok sensör Android 1.5'te (API Düzeyi 3) kullanıma sunulmuştur ancak bunlardan bazıları uygulanmamıştır ve Android 2.3'e (API Düzeyi 9) kadar kullanıma sunulmamıştır. Benzer şekilde, Android 2.3 (API Seviyesi 9) ve Android 4.0 (API Düzeyi 14) sürümlerinde de çeşitli sensörler kullanıma sunulmuştur. İki sensör kullanımdan kaldırıldı ve bunların yerini daha yeni, daha iyi sensörler aldı.
Tablo 2'de, her sensörün kullanılabilirlik düzeyi platform bazında özetlenmiştir. Burada yalnızca dört platform listeleniyor, çünkü bu platformlar sensör değişikliklerine dahil oluyor. Kullanımdan kaldırılmış olarak listelenen sensörler, Android'in ileriye dönük uyumluluk politikasına uygun olarak sonraki platformlarda kullanılabilir.
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'e (API Seviyesi 3) eklenmiştir ancak Android 2.3'e (API Düzeyi 9) kadar kullanıma sunulmamıştır.
2 Bu sensör kullanılabilir olsa da kullanımdan kaldırılmıştır.
Sensörleri ve Sensör Yeteneklerini Tanımlama
Android sensör çerçevesi, çalışma zamanında bir cihazda hangi sensörlerin olduğunu belirlemenizi kolaylaştıran çeşitli yöntemler sunar. API her bir sensörün maksimum menzil, çözünürlüğü ve güç gereksinimleri gibi yeteneklerini belirlemenizi sağlayan yöntemler de sunar.
Bir cihazdaki sensörleri tanımlamak için öncelikle sensör hizmetine referans almanız gerekir. Bunu yapmak için getSystemService()
yöntemini çağırıp SENSOR_SERVICE
bağımsız değişkenini ileterek SensorManager
sınıfının bir örneğini oluşturursunuz. Örnek:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Daha sonra, getSensorList()
yöntemini çağırıp TYPE_ALL
sabitini kullanarak bir cihazdaki 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 isterseniz TYPE_ALL
yerine başka bir sabit değer (ör. TYPE_GYROSCOPE
, TYPE_LINEAR_ACCELERATION
veya TYPE_GRAVITY
) kullanabilirsiniz.
Ayrıca, getDefaultSensor()
yöntemini kullanarak ve belirli bir sensör için tür sabitini geçirerek bir cihazda belirli bir sensör türünün olup olmadığını belirleyebilirsiniz. Bir cihazda belirli türde birden fazla sensör varsa sensörlerden biri varsayılan sensör olarak atanmalıdır. Belirli bir sensör türü için varsayılan sensör yoksa yöntem çağrısı null değerini döndürür. Bu, cihazda o 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 gerektirmez. Böylece, cihazlar çok çeşitli sensör yapılandırmalarına sahip olabilir.
Bir cihazdaki sensörleri listelemenin yanı sıra, bağımsız sensörlerin özelliklerini ve özelliklerini belirlemek için Sensor
sınıfındaki herkese açık yöntemleri kullanabilirsiniz. Uygulamanızın, bir cihazda hangi sensörlerin veya sensörlerin bulunduğuna bağlı olarak farklı şekilde davranmasını istiyorsanız bu yararlı bir özelliktir. Örneğin, bir sensörün çözünürlüğünü ve maksimum ölçüm aralığını elde etmek için getResolution()
ve getMaximumRange()
yöntemlerini kullanabilirsiniz. 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 yatırma ve sallama gibi kullanıcı hareketlerini izlemesi gerekiyorsa belirli bir tedarikçinin yerçekimi sensörüne sahip daha yeni cihazlar için bir veri filtreleme kuralları ve optimizasyon grubu, yerçekimi sensörü olmayan ve yalnızca ivme ölçere sahip cihazlar için başka bir veri filtreleme kuralları ve optimizasyonları grubu oluşturabilirsiniz. Aşağıdaki kod örneğinde, bunu yapmak için getVendor()
ve getVersion()
yöntemlerini nasıl kullanabileceğiniz gösterilmektedir. Bu örnekte, satıcı olarak Google LLC'yi listeleyen ve sürüm numarası 3 olan bir yerçekimi sensörü arıyoruz. Bu sensör cihazda yoksa ivme ölçeri kullanmaya çalışırız.
Kotlin
private lateinit var sensorManager: SensorManager private var mSensor: Sensor? = null ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) { val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY) // Use the version 3 gravity sensor. mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 } } if (mSensor == null) { // Use the accelerometer. mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) { sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) } else { // Sorry, there are no accelerometers on your device. // You can't play this game. null } }
Java
private SensorManager sensorManager; private Sensor mSensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensor = null; if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){ List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY); for(int i=0; i<gravSensors.size(); i++) { if ((gravSensors.get(i).getVendor().contains("Google LLC")) && (gravSensors.get(i).getVersion() == 3)){ // Use the version 3 gravity sensor. mSensor = gravSensors.get(i); } } } if (mSensor == null){ // Use the accelerometer. if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){ mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); } else{ // Sorry, there are no accelerometers on your device. // You can't play this game. } }
Yararlı bir diğer yöntem de getMinDelay()
yöntemidir. Bu yöntem, bir sensörün verileri algılamak için kullanabileceği minimum zaman aralığını (mikrosaniye cinsinden) döndürür. getMinDelay()
yöntemi için sıfır dışında bir değer döndüren tüm sensörler bir akış sensörüdür. Akış sensörleri, verileri düzenli aralıklarla algılar. Bu özellik Android 2.3'te (API Düzeyi 9) kullanıma sunulmuştur. getMinDelay()
yöntemini çağırdığınızda bir sensör sıfır döndürürse sensör, yalnızca algıladığı parametrelerde değişiklik olduğunda verileri raporladığı için akış sensörü değildir.
getMinDelay()
yöntemi, bir sensörün veri edinebileceği maksimum hızı belirlemenize olanak tanıdığından yararlıdır. Uygulamanızdaki bazı özellikler yüksek veri edinme hızı veya akış sensörü gerektiriyorsa bu yöntemi kullanarak bir sensörün bu gereksinimleri karşılayıp karşılamadığını belirleyebilir ve ardından uygulamanızdaki ilgili özellikleri buna uygun şekilde etkinleştirebilir ya da devre dışı bırakabilirsiniz.
Dikkat: Bir sensörün maksimum veri edinme hızı, sensör çerçevesinin uygulamanıza sensör verileri sağlama hızı değildir. Sensör çerçevesi, verileri sensör olayları aracılığıyla bildirir ve çeşitli faktörler uygulamanızın sensör etkinliklerini alma hızını etkiler. Daha fazla bilgi için Sensör Etkinliklerini İzleme bölümüne bakın.
Sensör Olaylarını İzleme
Ham sensör verilerini izlemek için SensorEventListener
arayüzü aracılığıyla açığa çıkan iki geri çağırma yöntemini uygulamanız gerekir: onAccuracyChanged()
ve onSensorChanged()
. Aşağıdaki durumlarda Android sistemi bu yöntemleri çağırır:
- Bir sensörün doğruluğu değişir.
Bu durumda sistem,
onAccuracyChanged()
yöntemini çağırarak değişenSensor
nesnesine 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
. - Bir sensör yeni bir değer bildiriyor.
Bu durumda sistem,
onSensorChanged()
yöntemini çağırarak size birSensorEvent
nesnesi sağlar. BirSensorEvent
nesnesi, yeni sensör verileriyle ilgili şunları içerir: verilerin doğruluğu, verileri oluşturan sensör, verilerin oluşturulduğu zaman damgası ve sensörün kaydettiği yeni veriler.
Aşağıdaki kod, ışık sensöründen gelen verileri izlemek için onSensorChanged()
yönteminin nasıl kullanılacağını göstermektedir. Bu örnekte, ham sensör verileri, main.xml dosyasında sensor_data
olarak tanımlanmış bir TextView
içinde gösterilmektedir.
Kotlin
class SensorActivity : Activity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var mLight: Sensor? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { // Do something here if sensor accuracy changes. } override fun onSensorChanged(event: SensorEvent) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. val lux = event.values[0] // Do something with this sensor value. } override fun onResume() { super.onResume() mLight?.also { light -> sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } }
Java
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor mLight; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. float lux = event.values[0]; // Do something with this sensor value. } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); } }
Bu örnekte, registerListener()
yöntemi çağrıldığında varsayılan veri gecikmesi (SENSOR_DELAY_NORMAL
) belirtilmiştir. Veri gecikmesi (veya örnekleme hızı), onSensorChanged()
geri çağırma yöntemi aracılığıyla sensör etkinliklerinin uygulamanıza gönderileceği aralığı kontrol eder. Varsayılan veri gecikmesi,tipik ekran yönü değişikliklerini izlemek için uygundur ve 200.000 mikrosaniyelik bir gecikme süresini 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 belirtebilirsiniz. Android 3.0 (API Düzeyi 11) sürümünden itibaren, gecikmeyi mutlak değer olarak da (mikrosaniye cinsinden) belirtebilirsiniz.
Belirttiğiniz gecikme yalnızca önerilen bir gecikmedir. Android sistemi ve diğer uygulamalar bu gecikmeyi değiştirebilir. En iyi uygulama olarak, sistem genellikle sizin belirttiğinizden daha kısa bir gecikme kullandığından mümkün olan en uzun gecikmeyi belirtmeniz gerekir (yani uygulamanızın ihtiyaçlarını yine de karşılayan en yavaş örnekleme hızını seçmeniz gerekir). Daha büyük bir gecikmenin kullanılması işlemciye daha düşük bir yük getirir 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 çeşitli etkinlikler üzerinden örnekleme hızını hesaplamak için her bir sensör olayıyla ilişkili zaman damgalarını kullanabilirsiniz. Örnekleme hızını (gecikme) ayarladıktan sonra değiştirmek zorunda kalmamalısınız. Herhangi bir nedenle gecikme süresini değiştirmeniz gerekirse sensör dinleyicisinin kaydını silip yeniden kaydetmeniz gerekir.
Bu örneğin, sensör etkinlik dinleyicisini kaydetmek ve kaydını silmek için onResume()
ve onPause()
geri çağırma yöntemlerini kullandığını da unutmayın. En iyi uygulama olarak, özellikle etkinliğiniz duraklatıldığında ihtiyaç duymadığınız sensörleri her zaman devre dışı bırakmanız gerekir. Bunu yapmazsanız, bazı sensörlerin önemli güç gereksinimleri olduğundan ve pil gücünü hızlı bir şekilde tüketebileceğinden, pilin birkaç saat içinde bitmesine neden olabilir. Ekran kapandığında sistem, sensörleri otomatik olarak devre dışı bırakmaz.
Farklı Sensör Yapılandırmalarını Yönetme
Android, cihazlar için standart bir sensör yapılandırması belirtmez. Diğer bir deyişle, cihaz üreticileri Android destekli cihazlarına istedikleri sensör yapılandırmasını dahil edebilir. Sonuç olarak, cihazlar çok çeşitli yapılandırmalarda çeşitli sensörler içerebilir. Uygulamanız belirli bir sensör türünü kullanıyorsa uygulamanızın başarılı bir şekilde çalışabilmesi için sensörün bir cihazda bulunduğundan emin olmanız gerekir.
Bir cihazda belirli bir sensörün olduğundan emin olmak için iki seçeneğiniz vardır:
- Çalışma zamanında sensörleri algılayın ve uygulama özelliklerini uygun şekilde etkinleştirin veya devre dışı bırakın.
- Belirli sensör yapılandırmalarına sahip cihazları hedeflemek için Google Play filtrelerini kullanın.
Her bir seçenek aşağıdaki bölümlerde ele alınmaktadır.
Çalışma zamanında sensörleri algılama
Uygulamanız belirli türde bir sensör kullanıyor ancak buna dayanmıyorsa, çalışma zamanında sensörü algılamak ve ardından uygulama özelliklerini uygun şekilde devre dışı bırakmak veya etkinleştirmek için sensör çerçevesini kullanabilirsiniz. Ö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ü, 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 bölümünü devre dışı bırakabilirsiniz. Örneğin, aşağıdaki kod cihazda basınç sensörü olup olmadığını kontrol eder:
Kotlin
private lateinit var sensorManager: SensorManager ... sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) { // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Java
private SensorManager sensorManager; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){ // Success! There's a pressure sensor. } else { // Failure! No pressure sensor. }
Belirli sensör yapılandırmalarını hedeflemek için Google Play filtrelerini kullanma
Uygulamanızı Google Play'de yayınlıyorsanız manifest dosyanızdaki <uses-feature>
öğesini kullanarak uygulamanızı, uygulamanız için uygun sensör yapılandırmasına sahip olmayan cihazlardan filtreleyebilirsiniz. <uses-feature>
öğesinde, uygulamaları belirli sensörlerin varlığına göre filtrelemenizi sağlayan ç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çere sahip 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 açıklayıcıyı uygulamanızın manifest dosyasına eklerseniz kullanıcılar uygulamanızı Google Play'de yalnızca cihazlarında ivme ölçer varsa görür.
Yalnızca uygulamanız tamamen belirli bir sensöre dayanıyorsa açıklayıcıyı android:required="true"
olarak ayarlamanız gerekir. Uygulamanız bazı işlevler için sensör kullanmasına rağmen sensör olmadan çalışıyorsa sensörü <uses-feature>
öğesinde listelemeniz ancak açıklayıcıyı android:required="false"
olarak ayarlamanız gerekir. Böylece, belirli bir sensöre sahip olmasalar bile cihazların uygulamanızı yükleyebilmeleri sağlanır. Bu aynı zamanda uygulamanızın kullandığı özellikleri takip etmenize yardımcı olan proje yönetimi en iyi uygulamalarından biridir.
Uygulamanız belirli bir sensörü kullanmasına rağmen sensör olmadan da çalışıyorsa çalışma zamanında sensörü tespit etmeniz 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. Koordinat sistemi, çoğu sensör için, cihaz varsayılan yönünde tutulduğunda cihazın ekranına göre tanımlanır (şekil 1'e bakın). Bir cihaz varsayılan yönünde tutulduğunda X ekseni yatay ve sağı, Y ekseni dikey ve yukarıyı, Z ekseni ise ekran yüzünün dışına işaret eder. Bu sistemde, ekranın arkasındaki koordinatlar negatif Z değerlerine sahiptir. Bu koordinat sistemini şu sensörler kullanıyor:
Bu koordinat sistemiyle ilgili anlaşılması gereken en önemli nokta, cihazın ekran yönü değiştiğinde eksenlerin değiştirilmemesidir. Diğer bir deyişle, cihaz hareket ederken 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. Çoğu tablet cihaz için doğal yön yataydır. Sensör koordinat sistemi ise her zaman cihazın doğal yönüne bağlıdır.
Son olarak, uygulamanız sensör verilerini ekrandaki ekranla eşleştirirse ekran dönüşünü belirlemek için getRotation()
yöntemini kullanmanız ve ardından sensör koordinatlarını ekran koordinatlarıyla eşlemek için remapCoordinateSystem()
yöntemini kullanmanız gerekir. Manifest dosyanız yalnızca dikey görüntüleme belirtiyor olsa bile bunu yapmanız gerekir.
Not: Bazı sensörler ve yöntemler, cihazın referans çerçevesi yerine, dünyanın referans çerçevesine göre bir koordinat sistemi kullanır. Bu sensörler ve yöntemler, cihazın dünyaya göre hareketini veya cihaz konumunu temsil eden veriler döndürür. Daha fazla bilgi için getOrientation()
yöntemini, getRotationMatrix()
yöntemini, Yön
Sensörü ve Rotasyon Vektör Sensörü'nü inceleyin.
Sensör Hız Sınırlaması
Uygulamanız Android 12 (API düzeyi 31) veya sonraki sürümleri hedefliyorsa kullanıcılar hakkındaki hassas olabilecek bilgileri korumak için sistem, belirli hareket sensörlerinden ve konum sensörlerinden gelen verilerin yenileme hızına bir sınır uygular. Bu veriler, cihazın ivme ölçer, jiroskop ve jeomanyetik alan sensörü tarafından kaydedilen değerleri içerir.
Yenileme hızı sınırı, sensör verilerine nasıl eriştiğinize bağlıdır:
- Sensör etkinliklerini izlemek için
registerListener()
yöntemini çağırırsanız sensör örnekleme hızı 200 Hz ile sınırlandırılır. Bu,registerListener()
yönteminin aşırı yüklenmiş varyantlarının tümü için geçerlidir. SensorDirectChannel
sınıfını kullanırsanız sensör örnekleme hızı, genellikle yaklaşık 50 Hz olanRATE_NORMAL
ile sınırlandırılır.
Uygulamanızın hareket sensörü verilerini daha yüksek bir hızda toplaması gerekiyorsa aşağıdaki kod snippet'inde gösterildiği gibi HIGH_SAMPLING_RATE_SENSORS
iznini beyan etmeniz gerekir. Aksi takdirde, uygulamanız bu izni beyan etmeden 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şmek ve Sensörleri Kullanmayla İlgili En İyi Uygulamalar
Sensör uygulamanızı tasarlarken bu bölümde açıklanan yönergeleri izlediğinizden 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 topla
Android 9 (API düzeyi 28) veya sonraki sürümleri çalıştıran cihazlarda arka planda çalışan uygulamalar aşağıdaki kısıtlamalara tabidir:
- İvme ölçer ve jiroskop gibi sürekli raporlama modunu kullanan sensörler etkinlik almaz.
- Değiştirilir veya tek çekim raporlama modlarını kullanan sensörler etkinlik almaz.
Bu kısıtlamalar göz önünde bulundurulduğunda, en iyi yöntem, sensör olaylarını uygulamanız ön plandayken veya bir ön plan hizmetinin parçasıyken tespit etmektir.
Sensör dinleyicilerinin kaydını iptal et
Sensörü kullanmayı bitirdiğinizde veya sensör etkinliği durakladığında sensörün dinleyici kaydını sildiğinizden emin olun. Bir sensör dinleyicisi kayıtlıysa ve etkinliği duraklatılırsa sensör, kaydını silmediğiniz sürece veri almaya ve pil kaynaklarını kullanmaya devam eder. Aşağıdaki kod, bir işleyicinin kaydını iptal etmek için onPause()
yönteminin nasıl kullanılacağını gösterir:
Kotlin
private lateinit var sensorManager: SensorManager ... override fun onPause() { super.onPause() sensorManager.unregisterListener(this) }
Java
private SensorManager sensorManager; ... @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); }
Daha fazla bilgi için unregisterListener(SensorEventListener)
başlıklı makaleyi inceleyin.
Android Emülatör ile test etme
Android Emülatör'de ivme ölçer, ortam sıcaklığı, manyetometre, yakınlık ve ışık gibi sensörleri test etmenizi sağlayan bir dizi sanal sensör kontrolü bulunur.
Emülatör, SdkControllerSensor uygulamasını çalıştıran bir Android cihazla bağlantı kullanır. Bu uygulamanın yalnızca Android 4.0 (API düzeyi 14) veya sonraki sürümleri çalıştıran cihazlarda kullanılabildiğini unutmayın. (Cihaz Android 4.0 çalıştırıyorsa 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. Daha sonra emülatör, cihazınızdaki sensörlerden aldığı yeni değerlere göre dönüştürülür.
SdkControllerSensor uygulamasının kaynak kodunu aşağıdaki konumda görüntüleyebilirsiniz:
$ your-android-sdk-directory/tools/apps/SdkController
Cihazınız ile emülatör arasında veri aktarmak için şu adımları uygulayın:
- Cihazınızda USB üzerinden hata ayıklamanın etkinleştirildiğinden emin olun.
- Cihazınızı bir USB kablosu kullanarak geliştirme makinenize bağlayın.
- Cihazınızda SdkControllerSensor uygulamasını başlatın.
- Uygulamada, emülasyonu 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 emülatöre dönüşüm uygulayabilmeniz gerekir.
$ 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 Emülatör kılavuzuna bakın.
onSensorChanged() yöntemini engelleme
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, onSensorChanged(SensorEvent)
yöntemini engellememek için mümkün olduğunca az işlem yapmaktır. Uygulamanızda veri filtreleme veya sensör verilerinin azaltılması gerekiyorsa bu işlemi onSensorChanged(SensorEvent)
yönteminin dışında gerçekleştirmeniz gerekir.
Kullanımdan kaldırılmış yöntemleri veya sensör türlerini kullanmaktan kaçının
Birçok yöntem ve sabit değer kullanımdan kaldırılmıştır.
Özellikle, TYPE_ORIENTATION
sensör türü kullanımdan kaldırılmıştır. Yön verilerini almak için bunun yerine getOrientation()
yöntemini kullanmanız gerekir. Benzer şekilde, TYPE_TEMPERATURE
sensör türü de kullanımdan kaldırılmıştır. Android 4.0 çalıştıran cihazlarda bunun yerine TYPE_AMBIENT_TEMPERATURE
sensör türünü kullanmalısınız.
Kullanmadan önce sensörleri doğrulayın
Cihazdan veri almaya çalışmadan önce cihazda sensörün var olduğunu her zaman doğrulayın. Bir sensörün sadece sık kullanılan bir sensör olduğu için var olduğunu varsaymayın. Cihaz üreticilerinin cihazlarında belirli sensörler sağlamaları gerekmez.
Sensör gecikmelerini dikkatlice seçin
registerListener()
yöntemiyle bir sensör kaydederken uygulamanıza veya kullanım alanınıza uygun bir iletim hızı seçtiğinizden emin olun. Sensörler çok yüksek hızlarda veri sağlayabilir. Sistemin ihtiyacınız olmayan ekstra verileri göndermesine izin vermek, sistem kaynaklarını boşa harcar ve pil gücünü harcar.