Android destekli çoğu cihazın hareketi, yönü ve çeşitli çevre koşullarını ölçen yerleşik sensörleri vardır. Bu sensörler, yüksek hassasiyet ve doğrulukla ham veriler sağlayabilir. Ayrıca üç boyutlu cihaz hareketini veya konumlandırmasını ya da cihazın yakınındaki ortam ortamında gerçekleşen değişiklikleri izlemek istediğinizde kullanışlıdır. Örneğin, bir oyun; yatırma, sallama, döndürme veya sallama gibi karmaşık kullanıcı hareketlerini ve hareketlerini anlamak için cihazın yerçekimi sensöründen gelen ölçümleri izleyebilir. Benzer şekilde, bir hava durumu uygulaması çiy noktasını hesaplamak ve raporlamak için cihazın sıcaklık sensörünü ve nem sensörünü kullanabilir ya da bir seyahat uygulaması pusula yönünü bildirmek için jeomanyetik alan sensörü ve ivme ölçeri kullanabilir.
Aşağıdaki ilgili kaynaklara bakı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çerler, yer çekimi sensörleri, jiroskoplar ve dönme vektör sensörlerini içerir.
- Çevre sensörleri
Bu sensörler ortam hava sıcaklığı ve basıncı, aydınlatma ve nem gibi çeşitli çevre parametrelerini ölçer. Bu kategori barometreleri, fotometreleri ve termometreleri içerir.
- Konum sensörleri
Bu sensörler bir cihazın fiziksel konumunu ölçer. Bu kategori yön sensörlerini ve manyetometreleri içerir.
Cihazda bulunan sensörlere erişebilir ve Android sensör çerçevesini kullanarak ham sensör verileri elde edebilirsiniz. Sensör çerçevesi, sensörlerle ilgili çok çeşitli görevleri gerçekleştirmenize yardımcı olan çeşitli sınıflar ve arayüzler sunar. Örneğin, şunları yapmak için sensör çerçevesini kullanabilirsiniz:
- Bir cihazda hangi sensörlerin kullanılabilir olduğunu belirleyin.
- Bağımsız bir sensörün maksimum menzili, üreticisi, güç gereksinimleri ve çözünürlük gibi özelliklerini belirleyin.
- Ham sensör verilerini edinme ve sensör verilerini elde ettiğiniz minimum hızı tanımlayın.
- Sensör değişikliklerini izleyen sensör etkinliği işleyicilerini kaydedin ve kayıtlarını silin.
Bu makalede, Android platformunda bulunan sensörlere genel bir bakış sunulmaktadır. Ayrıca sensör çerçevesine giriş niteliğindedir.
Sensörlere Giriş
Android sensör çerçevesi pek çok sensör türüne erişmenize olanak tanır. Bu sensörlerin bazıları donanım bazlı, bazıları ise yazılım tabanlıdır. Donanım tabanlı sensörler, telefon veya tablet cihazda yerleşik olarak bulunan fiziksel bileşenlerdir. İvme, jeomanyetik alan kuvveti veya açısal değişim gibi çevresel özellikleri doğrudan ölçerek verilerini türetirler. Yazılım tabanlı sensörler, donanım tabanlı sensörleri taklit etse de fiziksel cihazlar değildir. Yazılım tabanlı sensörler, verilerini donanım tabanlı bir veya daha fazla sensörden alır ve bazen sanal sensörler veya sentetik sensörler olarak da adlandırılır. Doğrusal ivme sensörü ve yerçekimi sensörü, yazılım tabanlı sensörlere örnektir. Tablo 1'de Android platformu tarafından desteklenen sensörler özetlenmiştir.
Her türde sensöre sahip olan Android destekli cihaz sayısı çok azdır. Örneğin, çoğu mobil cihaz ve tablette ivme ölçer ve manyetometre bulunurken daha az cihazda barometre veya termometre bulunur. Ayrıca, bir cihaz belirli bir türde birden fazla sensöre sahip olabilir. Örneğin, bir cihazda her biri farklı bir mesafeye sahip olan iki yer çekimi sensörü olabilir.
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) cihaza uygulanan ivme kuvvetini m/sn2 cinsinden ölçer. | Hareket algılama (titreme, yatırma vb.). |
TYPE_AMBIENT_TEMPERATURE |
Donanım | Odanın ortam sıcaklığını Santigrat (°C) cinsinden ölçer. Aşağıdaki nota bakın. | Hava sıcaklıkları izleniyor. |
TYPE_GRAVITY |
Yazılım veya Donanım | Üç fiziksel eksenin (x, y, z) üzerinde cihaza uygulanan yerçekimi kuvvetini m/s2 cinsinden ölçer. | Hareket algılama (titreme, yatırma vb.). |
TYPE_GYROSCOPE |
Donanım | Bir cihazın, üç fiziksel eksenin (x, y ve z) her biri etrafında rad/sn 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, üç fiziksel eksende (x, y ve z) bir cihaza uygulanan ivme kuvvetini m/sn2 cinsinden ölçer. | Tek bir eksen üzerinde ivmeyi izleme. |
TYPE_MAGNETIC_FIELD |
Donanım | Üç fiziksel eksenin (x, y, z) μT cinsinden ortam jeomanyetik alanını ölçer. | Pusula oluşturuluyor. |
TYPE_ORIENTATION |
Yazılım | Bir cihazın üç fiziksel eksenin (x, y, z) etrafında yaptığı dönüş derecelerini ölçer.
API seviyesi 3'ten itibaren, getRotationMatrix() yöntemiyle birlikte yerçekimi sensörü ve jeomanyetik alan sensörünü kullanarak bir cihazın eğim matrisini ve dönüş matrisini elde edebilirsiniz. |
Cihaz konumu belirleniyor. |
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 nesnenin yakınlığını cm cinsinden ölçer. Bu sensör, genellikle telefonun bir kişinin kulağına tutunup tutulmadığını belirlemek için kullanılır. | Çağrı sırasında telefonun konumu. |
TYPE_RELATIVE_HUMIDITY |
Donanım | Bağıl ortam nemini yüzde (%) cinsinden ölçer. | Çiy noktası, mutlak ve bağıl nem takip ediliyor. |
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öndürme algılama. |
TYPE_TEMPERATURE |
Donanım | Cihazın sıcaklığını Santigrat (°C) cinsinden ölçer. Bu sensör uygulaması cihaza göre değişir ve bu sensör, API Seviyesi 14'te TYPE_AMBIENT_TEMPERATURE sensörüyle değiştirildi |
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 örneğini oluşturmak için bu sınıfı kullanabilirsiniz. Bu sınıf, sensörlere erişme ve bunları listeleme, sensör etkinlik dinleyicilerini kaydedip silme ve yön bilgileri edinme için çeşitli yöntemler sunar. Bu sınıf ayrıca sensör doğruluğunu raporlamak, veri edinme hızlarını ayarlamak ve sensörleri kalibre etmek için kullanılan çeşitli sensör sabitleri 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ı bir sensör etkinliği nesnesi oluşturmak için kullanır. Bu nesne, sensör etkinliği hakkında bilgi sağlar. Bir sensör etkinlik nesnesi şu bilgileri içerir: ham sensör verileri, etkinliği oluşturan sensörün türü, verilerin doğruluğu ve etkinliğin zaman damgası.
SensorEventListener
- 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 bu arayüzü 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 tanımlama
Uygulamanızda belirli sensör türlerine veya özelliklerine dayanan özellikler varsa çalışma zamanında sensörleri ve sensör özelliklerini tanımlamak faydalı olur. Örneğin, bir cihazda bulunan tüm sensörleri tanımlamak ve mevcut olmayan sensörlere dayalı uygulama özelliklerini devre dışı bırakmak isteyebilirsiniz. Benzer şekilde, uygulamanız için optimum performansa sahip sensör uygulamasını seçmek için belirli bir türdeki tüm sensörleri tanımlamak isteyebilirsiniz.
- Sensör etkinliklerini izleme
Ham sensör verilerini elde etme yönteminiz, sensör etkinliklerini izlemedir. Bir sensör ölçtüğü parametrelerde değişiklik algıladığında bir sensör etkinliği oluşur. Bir sensör etkinliği size dört adet 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 cihazdan cihaza değişse de Android sürümleri arasında da değişiklik gösterebilir. Bunun nedeni, Android sensörlerinin birkaç platform sürümünde kullanıma sunulmasıdır. Örneğin, birçok sensör Android 1.5'te (API Düzeyi 3) kullanıma sunulmuştu, ancak bazıları uygulanmadı ve Android 2.3'e (API Düzeyi 9) kadar kullanılamıyordu. Benzer şekilde Android 2.3 (API Düzeyi 9) ve Android 4.0'da (API Düzeyi 14) birkaç sensör kullanıma sunulmuştur. İki sensör kullanımdan kaldırıldı ve artık daha yeni ve daha iyi sensörlerle değiştirildi.
Tablo 2'de her bir sensörün kullanılabilirliği platform bazında özetlenmiştir. Sensör değişikliklerinin yapıldığı platformlar olduğu için yalnızca dört platform listelenmektedir. Kullanımdan kaldırıldı olarak listelenen sensörler, Android'in ileriye dönük uyumluluk politikasına uygun olarak sonraki platformlarda (sensörün bir cihazda bulunması şartıyla) kullanılmaya devam eder.
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 (API Düzeyi 3) sürümünde eklenmiş ancak Android 2.3'e (API Düzeyi 9) kadar kullanıma sunulmamıştı.
2 Bu sensör kullanılabilir ancak kullanımdan kaldırılmıştır.
Sensörleri ve Sensör Becerilerini Tanımlama
Android sensör çerçevesi, çalışma zamanında hangi sensörlerin cihazda olduğunu belirlemenizi kolaylaştıran çeşitli yöntemler sunar. API, her bir sensörün özelliklerini (ör. maksimum menzili, çözünürlüğü ve güç gereksinimleri gibi) belirlemenizi sağlayan yöntemler de sunar.
Bir cihazdaki sensörleri belirlemek 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 tüm sensörlerin 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 TYPE_GYROSCOPE
,
TYPE_LINEAR_ACCELERATION
veya TYPE_GRAVITY
gibi başka bir sabit değer kullanabilirsiniz.
Ayrıca getDefaultSensor()
yöntemini kullanarak ve belirli bir sensörün tür sabitini ileterek bir cihazda belirli türde bir sensörün olup olmadığını belirleyebilirsiniz. Bir cihaz belirli bir türde birden fazla sensöre sahipse 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, yani cihazda bu tür bir sensör yoktur. Ö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ürlerde sensörler oluşturmasını zorunlu kılmaz. Bu nedenle, cihazlar çok çeşitli sensör yapılandırmalarına sahip olabilir.
Bağımsız sensörlerin işlevlerini ve özelliklerini belirlemek için bir cihazdaki sensörleri listelemenin yanı sıra Sensor
sınıfının herkese açık yöntemlerini de kullanabilirsiniz. Bu, uygulamanızın bir cihazda hangi sensörlerin veya sensör özelliklerinin bulunduğuna bağlı olarak farklı davranmasını istiyorsanız faydalı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. 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 kullanışlıdır. Örneğin, uygulamanızın yatırma ve sallama gibi kullanıcı hareketlerini izlemesi gerekiyorsa belirli bir tedarikçinin yerçekimi sensörüne sahip yeni cihazlar için bir veri filtreleme kuralları ve optimizasyonları 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, tedarikçi olarak Google LLC'nin listelendiği ve sürüm numarası 3 olan bir yerçekimi sensörünü 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. } }
Faydalı 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 akış sensörüdür. Akış sensörleri verileri düzenli aralıklarla algılıyor ve 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 bu, sensörün bir akış sensörü olmadığı anlamına gelir. Çünkü yalnızca algıladığı parametrelerde bir değişiklik olduğunda verileri rapor eder.
getMinDelay()
yöntemi, bir sensörün veri alabileceği maksimum hızı belirlemenizi sağladığı için yararlı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 gereksinimleri karşılayıp karşılamadığını belirleyebilir ve ardından uygulamanızdaki ilgili özellikleri uygun şekilde etkinleştirebilir veya devre dışı bırakabilirsiniz.
Dikkat: Bir sensörün maksimum veri edinme hızı, kesinlikle sensör çerçevesinin uygulamanıza sensör verilerini ilettiği hız değildir. Sensör çerçevesi, verileri sensör etkinlikleri aracılığıyla bildirir. Uygulamanızın sensör etkinliklerini alma hızı çeşitli faktörlerden etkilenir. Daha fazla bilgi için Sensör Etkinliklerini İzleme bölümüne bakın.
Sensör Etkinliklerini İzleme
Ham sensör verilerini izlemek için SensorEventListener
arayüzü üzerinden açığa çıkan iki geri çağırma yöntemi uygulamanız gerekir: onAccuracyChanged()
ve onSensorChanged()
. Aşağıdaki durum gerçekleştiğinde Android sistemi bu yöntemleri çağırır:
- Bir sensörün doğruluğunun değişmesi.
Bu durumda, sistem
onAccuracyChanged()
yöntemini çağırarak değişenSensor
nesnesine ilişkin bir referans ve sensörün yeni doğruluğunu sağlar. Doğruluk, dört durum sabitinden biriyle ifade 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.SensorEvent
nesnesi, yeni sensör verileri hakkında bilgi içerir. Bu bilgiler arasında verilerin doğruluğu, verileri üreten sensör, verilerin oluşturulduğu zaman damgası ve sensörün kaydettiği yeni veriler yer alır.
Aşağıdaki kodda, ışık sensöründen gelen verileri izlemek için onSensorChanged()
yönteminin nasıl kullanılacağı gösterilmektedir. Bu örnekte, ham sensör verileri main.xml dosyasında sensor_data
olarak tanımlanan bir TextView
içinde gösterilmektedir.
Kotlin
class SensorActivity : Activity(), SensorEventListener { private lateinit var sensorManager: SensorManager private var mLight: Sensor? = null public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.main) sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT) } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { // Do something here if sensor accuracy changes. } override fun onSensorChanged(event: SensorEvent) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. val lux = event.values[0] // Do something with this sensor value. } override fun onResume() { super.onResume() mLight?.also { light -> sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL) } } override fun onPause() { super.onPause() sensorManager.unregisterListener(this) } }
Java
public class SensorActivity extends Activity implements SensorEventListener { private SensorManager sensorManager; private Sensor mLight; @Override public final void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); } @Override public final void onAccuracyChanged(Sensor sensor, int accuracy) { // Do something here if sensor accuracy changes. } @Override public final void onSensorChanged(SensorEvent event) { // The light sensor returns a single value. // Many sensors return 3 values, one for each axis. float lux = event.values[0]; // Do something with this sensor value. } @Override protected void onResume() { super.onResume(); sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onPause() { super.onPause(); sensorManager.unregisterListener(this); } }
Bu örnekte, registerListener()
yöntemi çağrıldığında varsayılan veri gecikmesi (SENSOR_DELAY_NORMAL
) belirtilmiştir. Veri gecikmesi (veya örnekleme hızı), sensör etkinliklerinin onSensorChanged()
geri çağırma yöntemi aracılığıyla uygulamanıza gönderildiği aralığı kontrol eder. Varsayılan veri gecikmesi,tipik ekran yönü değişikliklerini izlemek için uygundur ve 200.000 mikrosaniyelik bir gecikmeyi kullanır. SENSOR_DELAY_GAME
(20.000 mikrosaniye gecikme), SENSOR_DELAY_UI
(60.000 mikrosaniye gecikme) veya SENSOR_DELAY_FASTEST
(0 mikrosaniye gecikmesi) 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. Sistem genellikle belirttiğinizden daha küçük bir gecikme kullandığından mümkün olan en büyük gecikmeyi belirtmeniz gerekir (yani uygulamanızın ihtiyaçlarını 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 oluşturur ve bu nedenle daha az güç kullanır.
Sensör çerçevesinin uygulamanıza sensör etkinliklerini gönderme hızını belirlemek için herkese açık bir yöntem yoktur. Ancak her bir sensör etkinliğiyle ilişkili zaman damgalarını kullanarak birkaç etkinlik üzerinden örnekleme hızını hesaplayabilirsiniz. Ayarladıktan sonra örnekleme hızını (gecikme) değiştirmeniz gerekmez. Herhangi bir nedenle gecikmeyi değiştirmeniz gerekirse sensörü iptal edip sensör dinleyiciyi yeniden kaydetmeniz gerekir.
Bu örneğin, sensör etkinliği işleyicisini kaydetmek ve kaydını iptal etmek için onResume()
ve onPause()
geri çağırma yöntemlerinin kullanıldığını da göz önünde bulundurun. 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. Bunu yapmazsanız bazı sensörlerin önemli güç gereksinimleri vardır ve pil gücünü hızlı bir şekilde tüketebilirler. Ekran kapandığında, sistem
sensörleri otomatik olarak devre dışı bırakmaz.
Farklı Sensör Yapılandırmalarını İşleme
Android, cihazlar için standart bir sensör yapılandırması belirtmez. Yani, cihaz üreticileri Android destekli cihazlarına istedikleri herhangi bir sensör yapılandırmasını dahil edebilirler. 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 ya da devre dışı bırakın.
- Belirli sensör yapılandırmaları olan cihazları hedeflemek için Google Play filtrelerini kullanın.
Bu seçenekler aşağıdaki bölümlerde ele alınmaktadır.
Çalışma zamanında sensörleri algılama
Uygulamanız belirli bir tür sensör kullanıyorsa ancak bu sensöre güvenmiyorsa ç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ığı, barometrik basıncı, konumu ve pusula yönünü göstermek için sıcaklık sensörü, basınç sensörü, GPS sensörü ve jeomanyetik alan sensörünü kullanabilir. Bir cihazda basınç sensörü yoksa çalışma zamanında basınç sensörünün olmadığını tespit etmek için sensör çerçevesini kullanabilir ve ardından uygulamanızın basıncı gösteren kullanıcı arayüzünün 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 uygulamanızı uygulamanıza uygun sensör yapılandırmasına sahip olmayan cihazlardan filtrelemek için manifest dosyanızda <uses-feature>
öğesini kullanabilirsiniz. <uses-feature>
öğesinin, uygulamaları belirli sensörlerin varlığına göre filtrelemenizi sağlayan çeşitli donanım tanımlayıcıları vardır. Listeleyebileceğiniz sensörler şunlardır:
ivme ölçer, barometre, pusula (jeomanyetik alan), jiroskop, ışık ve yakınlık. Aşağıda, ivme ölçeri olmayan uygulamaları filtreleyen bir manifest girişi örneği gösterilmektedir:
<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ürler.
Tanımlayıcıyı yalnızca uygulamanız tamamen belirli bir sensöre dayanıyorsa android:required="true"
olarak ayarlamalısınız. 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 tanımlayıcıyı android:required="false"
olarak ayarlamanız gerekir. Bu şekilde, cihazlar ilgili sensöre sahip olmasalar bile uygulamanızı yükleyebilirler. Uygulamanızda kullanılan özellikleri takip etmenize yardımcı olan bu en iyi proje yönetimi uygulamasıdır.
Uygulamanız belirli bir sensörü kullanmasına rağmen sensör olmadan da çalışıyorsa sensörü çalışma zamanında algılamanız ve uygulama özelliklerini uygun şekilde devre dışı bırakmanız veya etkinleştirmeniz gerekir.
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, cihaz varsayılan yönünde tutulduğunda koordinat sistemi cihazın ekranına göre tanımlanır (bkz. Şekil 1). Bir cihaz varsayılan yönünde tutulduğunda, X ekseni yatay olur ve sağa doğru, Y ekseni dikeydir 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 sistemi aşağıdaki sensörler tarafından kullanılır:
Bu koordinat sistemiyle ilgili anlaşılması gereken en önemli nokta, cihazın ekran yönü değiştiğinde eksenlerin değişmediği, yani cihaz hareket ettikçe sensörün koordinat sisteminin değişmediğidir. Bu davranış, OpenGL koordinat sisteminin davranışıyla aynıdır.
Unutulmaması gereken bir diğer nokta da uygulamanızın, cihazın doğal (varsayılan) yönünün dikey olduğunu varsaymamaktır. Birçok tabletin doğal yönü yataydır. Sensör koordinat sistemi her zaman cihazın doğal yönüne bağlıdır.
Son olarak, uygulamanız sensör verilerini ekrandaki ekranla eşleştiriyorsa 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ülemeyi belirtiyor 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 bağlı bir koordinat sistemi kullanır. Bu sensörler ve yöntemler, cihaz hareketini veya dünyaya göre cihaz konumunu temsil eden veriler döndürür. Daha fazla bilgi için getOrientation()
yöntemi, getRotationMatrix()
yöntemi, Yön Sensörü ve Döndürme 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 durum,registerListener()
yönteminin tüm aşırı yüklenmiş varyantları 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 daha yüksek bir hızda hareket sensörü verisi toplamaya çalışırsa SecurityException
hatası oluşur.
<manifest ...> <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/> <application ...> ... </application> </manifest>
Sensörlere Erişme ve Kullanmayla İlgili En İyi Uygulamalar
Sensör uygulamanızı tasarlarken bu bölümde açıklanan yönergeleri uyguladığınızdan emin olun. Bu kurallar, sensörlere erişmek ve sensör verileri elde etmek için sensör çerçevesini kullanan herkes için önerilir.
Yalnızca ön planda sensör verilerini topla
Android 9 (API düzeyi 28) veya sonraki sürümleri çalıştıran cihazlarda arka planda çalışan uygulamalar aşağıdaki kısıtlamalara sahiptir:
- İvme ölçer ve jiroskop gibi sürekli raporlama modunu kullanan sensörler etkinlik almaz.
- Değişim sırasında veya tek seferlik raporlama modlarını kullanan sensörler etkinlik almaz.
Bu kısıtlamalar doğrultusunda, uygulamanız ön plandayken veya bir ön plan hizmetinin parçası olarak sensör etkinliklerini tespit etmek en iyi seçenektir.
Sensör işleyicilerin kaydını sil
Sensörü kullanmayı bitirdiğinizde veya sensör etkinliği durakladığında sensör dinleyicisinin kaydını iptal ettiğinizden emin olun. Bir sensör dinleyici kayıtlıysa ve etkinliği duraklatılmışsa sensörün kaydını iptal etmediğiniz sürece sensör veri toplamaya 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 bilgiyi unregisterListener(SensorEventListener)
sayfasında bulabilirsiniz.
Android Emülatör ile test etme
Android Emulator, ivme ölçer, ortam sıcaklığı, manyetometre, yakınlık, ışık ve diğer sensörleri test etmenizi sağlayan bir dizi sanal sensör kontrolü içerir.
Emülatör, SdkControllerSensor uygulamasını çalıştıran bir Android cihazla bağlantı kullanır. Bu uygulamanın yalnızca Android 4.0 (API düzeyi 14) veya sonraki sürümleri çalıştıran cihazlarda kullanılabildiğini unutmayın. (Cihazda Android 4.0 çalışıyorsa Düzeltme 2 yüklü olmalıdır.) 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ızla emülatör arasında veri aktarmak için şu adımları izleyin:
- Cihazınızda USB üzerinden hata ayıklamanın etkin olduğundan emin olun.
- Bir USB kablosu kullanarak cihazınızı geliştirme makinenize bağlayın.
- Cihazınızda SdkControllerSensor uygulamasını başlatın.
- Uygulamada, emüle etmek istediğiniz sensörleri seçin.
Aşağıdaki
adb
komutunu çalıştırın:- Emülatörü başlatın. Artık cihazınızı taşıyarak emülatöre dönüşüm uygulayabilirsiniz.
$ adb forward tcp:1968 tcp:1968
Not: Fiziksel cihazınızda yaptığınız hareketler emülatörü 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 engellemeyin
Sensör verileri yüksek 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 mümkün olduğunca az işlem yapmalısınız. Uygulamanız, sensör verilerini azaltma veya filtreleme gibi işlemler yapmanızı gerektiriyorsa bu işlemleri onSensorChanged(SensorEvent)
yöntemi dışında gerçekleştirmelisiniz.
Desteği sonlandı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ı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ı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 her zaman cihazda bir sensörün olduğunu doğrulayın. Bir sensörün sadece sık kullanılan bir sensör olduğunu varsaymayın. Cihaz üreticilerinin, cihazlarında belirli sensörler sağlamaları gerekmez.
Sensör gecikmelerini dikkatli bir şekilde seçin
registerListener()
yöntemiyle bir sensörü kaydederken uygulamanız veya kullanım alanınız için 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 fazladan verileri göndermesine izin vermek, sistem kaynaklarını boşa harcar ve pil gücünü kullanır.