Merhaba arkadaşlar bu yazımızda Android’in bize sağlamış olduğu  bir kolaylık olan ve akıllı telefonlarımızda yada android destekleyen cihazlarımızda bulunan sensörleri nasıl kullanacağımızı öğreneceğiz. Android bizim telefonumuzdaki sensörlerimizi senkronize ederek destekleyen sensör bilgilerini gayet kolay bir şekilde bizim yerimize alıp bilgiyi bize ulaştırmaktadır. Bu konuda temel android bilgisine sahip olmanız yeterlidir. İlk olarak sensörlerimizi tanıtalım. Sensörlerimizi bir tip olarak tanıtacağım. Android sensor sayfasından aldığım bilgilerle sırasıyla : (http://developer.android.com/reference/android/hardware/Sensor.html)

TYPE_ACCELEROMETER   İvme Ölçer
TYPE_AMBIENT_TEMPERATURE   Ortam Sıcaklığı
TYPE_GRAVITY   Yerçekimi
TYPE_GYROSCOPE   Denge
TYPE_LIGHT   Işık
TYPE_LINEAR_ACCELERATION   Doğrusal İvme
TYPE_MAGNETIC_FIELD   Manyetik Alan
TYPE_ORIENTATION   Yön Belirleme
TYPE_PRESSURE   Basınç
TYPE_PROXIMITY   Yakınlık
TYPE_RELATIVE_HUMIDITY   Nem
TYPE_ROTATION_VECTOR   Dönme Vektörü
TYPE_TEMPERATURE    Sıcaklık

Bu tipler Android kod diziminde “Sensor” class’ı altında bulunmaktadır. Biz sensör bilgilerini alabilmemiz için ilk olarak sensör yöneticisi oluşturacağız. Daha sonra kullanacağımız sensörü oluşturduktan sonra bu iki yapıyı birbirine bağlayarak sonuç elde etmiş olacağız. Ben şimdi ilk olarak ışık seviyesini ölçen TYPE_LIGHT‘ı anlatacağım. Bu sensör düşük foton değerlerinde ( az ışık algıladığında ) düşük değerler , yüksek foton değerlerinde ( çok ışık algıladığında ) yüksek değerler geri döndürmektedir.İlk olarak sersör yöneticimizi sensör servisimize bağlayalım ve uygulama üzerinde durumu test etmiş , öğrenmiş olalım.

SensorManager mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);

Sıra geldi sensörümüzü belirlemeye ;


Sensor myLightSensor = mySensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

Şimdi sıra geldi bu sensörün veri alımını ne kadar sıklıkla yapacağımıza

mySensorManager.registerListener(lightSensorEventListener,myLightSensor,
                                 SensorManager.SENSOR_DELAY_FASTEST);

Burada SENSOR_DELAY gecikmemizi belirlemekte ancak bu durumun altında bazı sıklık çeşitleri bulunmaktadır.Bunda bizim daha çok kullandıklarımızı açıklayalım :
SENSOR_DELAY_FASTEST  : Sürekli
SENSOR_DELAY_GAME        : Sıklıkla ( daha çok ihtiyaç anlarında )
SENSOR_DELAY_NORMAL  : Normal aralıklarla

Ben burada sürekli olmasını istediğimden dolayı FASTEST‘ı seçtim bu sizin tercihinize bağlıdır. Devam edelim.Yöneticimizi ,sensörümüzü ve sıklığımızıda belirlediğimize göre artık dinleyicimizi oluşturabiliriz.

SensorEventListener lightSensorEventListener= new SensorEventListener(){

@Override
 public void onAccuracyChanged(Sensor arg0, int arg1) {
}

@Override
 public void onSensorChanged(SensorEvent event) {

 }};

Sensör dinleyicimizi SensorEventListener class’ı ile oluşturuyoruz. Override etmemiz gereken 2 adet fonksiyonu olduğunu görüyoruz peki nedir bu fonksiyonlar açıklayacak olursak :
onAccuracyChanged : Genelde log tutmak amacıyla kullanılır.
onSensorChanged    : Sensör üzerinden gelen bilgilerin tutultuğu fonksiyondur. SensorEvent class’ı altında bir bilgi alır bu bilgi bizim sensörümüzün tüm bilgilerini içermektedir.

onSensorChanged altında SensorEvent class’ı altındaki event float tipinde dönmektedir. Gelen bilgiyi okuyabilmemiz için
event.value[0];
yazmamız gerekmektedir. Bu değer bize ışık seviyesini bildirmektedir.Ben burada TextViewe aktarmak istedim.
Bunları açıkladığımıza göre kendi telefonumda ışık sensörü aşağıdaki yerde bulunmaktadır. Sizde kendi telefonunuzun (destekleyen telefonlarda)
tam olarak nerde olduğunu araştırırsanız bu uygulamanın gerçekleşebildiğini göreceksiniz. :

1 adet TextView uygulamayı gerçekleyebilmek için yeterlidir.

[codesyntax lang=”java” container=”pre_valid” title=”MainActivity.java”]
package com.example.sicaklik;

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

SensorManager sensorYoneticisi;
Sensor isikSensoru;
TextView sensorBilgisi;

@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

sensorBilgisi = (TextView)findViewById(R.id.textView2);
sensorBilgisi.setText(“Sensor bilgisi alınıyor..”);

sensorYoneticisi = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
isikSensoru = sensorYoneticisi.getDefaultSensor(Sensor.TYPE_LIGHT);

sensorYoneticisi.registerListener(sensorDinleyicisi,isikSensoru,
SensorManager.SENSOR_DELAY_FASTEST);

}

SensorEventListener sensorDinleyicisi = new SensorEventListener(){

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}

@Override
public void onSensorChanged(SensorEvent event) {

if(event.sensor.getType()==Sensor.TYPE_LIGHT){
sensorBilgisi.setText(“Işık Sensör Seviyesi:”+ String.valueOf(event.values[0]));
}

}};
}
[/codesyntax]
[codesyntax lang=”xml” title=”activity_main.xml”]
RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”
xmlns:tools=”http://schemas.android.com/tools”
android:layout_width=”match_parent”
android:layout_height=”match_parent” >

<TextView
android:id=”@+id/textView2″
android:layout_width=”wrap_content”
android:layout_height=”wrap_content”
android:layout_centerVertical=”true”
android:layout_marginBottom=”78dp”
android:layout_marginLeft=”26dp”
android:text=”Small Text”
android:textAppearance=”?android:attr/textAppearanceSmall” />

</RelativeLayout>

[/codesyntax]

[codesyntax lang=”xml” title=”AndroidManifest.xml”]
<manifest xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
package=”com.example.sicaklik”
android:versionCode=”1″
android:versionName=”1.0″ >

<uses-sdk
android:minSdkVersion=”8″
android:targetSdkVersion=”15″ />

<application
android:icon=”@drawable/ic_launcher”
android:label=”@string/app_name”
android:theme=”@style/AppTheme” >
<activity
android:name=”.MainActivity”
android:label=”@string/title_activity_main” >
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
</application>

</manifest>
[/codesyntax]

ve şimdide Run’lıyoruz sonuçları gözlemliyoruz.

Şimdi sıra geldi ivme sensörümüze :

Sensörümüzü kullanmak için ilk başta tanıtalım. Bu sensörümüz belirli yönlerde  cihazın bulunduğu eksen üzerinde bilgi vermesiyle daha çok  bilinmektedir. Eksenlerimiz X –  Y  –  Z olmaktadır ve kullanımı kolay ve programlaması , geliştirilmesi sizin hayal gücünüze kalmaktadır.

Yine ışık sensöründe olduğu gibi  sensör yöneticimizi tanıtıyoruz.


SensorManager sensorYoneticisi = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

Işık sensöründe olduğu gibi bu sensörümüzde ve  diğer sensörler için ortak yöneticimiz olmaktadır.
Sıra geldi sensorumuze

Sensor ivmeSensoru = sensorYoneticisi.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

arkadaşlar gördüğünüz üzere Sensor.TYPE_ACCELEROMETER olarak seçtik bu yön sensörünü tabir etmektedir.Yazımızın başında bunu açıklamıştık.

Şimdide sensörümüzün sıklığını ve çalışıp çalışmadığını kontrol eden komutumuzu görelim.

if(!sensorYoneticisi.registerListener(this, ivmeSensoru, SensorManager.SENSOR_DELAY_GAME)){
      tx1.setText("Sensor çalışmıyor..");
}

Gördüğünüz üzere SensorManager.SENSOR_DELAY_GAME yazıyor. Burada yazan şey aslında sensörümüzden gelen verileri ne kadar sıklıkla alacağını belirtiyoruz. Action ( hareket ) halinde bu sensörden veri alınacaktır.
registerListener fonksiyonu true yada false geri döndürmektedr. if ile bunu kontrol ediyoruz burada “!” işareti eğer değilse , yani sensör çalışmıyor ise text‘imize “Sensör çalışmıyor” yazısını yazmış oluyoruz. Böylece tek satırda hem hızımızı hem sensorumuzu hemde calışıp çalışmadığını öğrenmiş oluyoruz.

Devam edecek olursak bu seferde implements yapısına değinmek istedim. Temel seviye C C++ bilen kişilerin bu konuda biraz sıkıntı çektikleri kısım olmaktadır. Java ile gelen bir özelliktir . İmplements yapısı kısaca aslında bir class’ı birden çok class çağırdığı zaman ve o class’ın fonksiyonlarını kullanacak ise kullanıyoruz. Extends in zayıf noktası birden çok class tarafından çağırılamamasıdır.
Extends ‘i bir seri devre gibi düşünelim. Implements ‘ i paralel devre gibi hayal edip aklınızda tutabilirsiniz. Listener’lar genellikle implements olarak çağırılır.
Bildiğiniz üzere bir önceki seferde Listener’ımızı direk sınıf içinde çağırmıştık bu sefer ekstrem bir durum yapacak olursak direk class name’imiz içinde gösterelim.

SensorEventListener sensorDinleyicisi = new SensorEventListener(){

Bu kod yerine direk class’ımıza eklemiş oluyoruz ve Override’larımız direk oluşuyor.

public class MainActivity extends Activity implements SensorEventListener{

gördüğünüz üzere kod kısmında dahada azalmış olmaktadır. Ve sensörü çağırırken

sensorYoneticisi.registerListener(sensorDinleyicisi,....

yerine

sensorYoneticisi.registerListener(this,...

dememiz yeterli olmaktadır.
Sıra geldi yön değerlerini göstermeye. Yön değerleri onSensorChanged fonksiyonu altında (SensorEvent event) altında gelmekte ve event float olarak dönmektedir. 3 değer getirmektedir .
0 – X
1 – Y
2 – Z
bu değerleri çağırabilmemiz için
event.value[a];
şeklinde çağırmalıyız. ‘a’dediğimiz kısma çağırmak istediğimiz değeri giriyoruz.
Artık kodumuzun tamamını koyacak olursak

[codesyntax lang=”java” container=”pre_valid” title=”MainActivity.java”]
package com.example.sensor;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener{

TextView tx1;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

SensorManager sensorYoneticisi = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

Sensor yonSensoru = sensorYoneticisi.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

tx1 = (TextView)findViewById(R.id.textView1);

if(!sensorYoneticisi.registerListener(this, yonSensoru, SensorManager.SENSOR_DELAY_GAME)){
tx1.setText(“Sensor çalışmıyor..”);
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

@Override
public void onSensorChanged(SensorEvent event) {

tx1.setText(“X : ” + event.values[0] + “\nY : ” + event.values[1] + “\nZ : ” + event.values[2]);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}

[/codesyntax]

[codesyntax lang=”php” title=”activity_main.xml”]

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <AbsoluteLayout
        android:id="@+id/absoluteLayout1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" >
    </AbsoluteLayout>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/absoluteLayout1"
        android:layout_marginTop="21dp"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

[/codesyntax]

[codesyntax lang=”php” title=”AndroidManifest.xml”]

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.sensor"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-sdk
android:minSdkVersion=”8″
android:targetSdkVersion=”15″ />

<application
android:icon=”@drawable/ic_launcher”
android:label=”@string/app_name”
android:theme=”@style/AppTheme” >
<activity
android:name=”.MainActivity”
android:label=”@string/title_activity_main” >
<intent-filter>
<action android:name=”android.intent.action.MAIN” />

<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
</application>

</manifest>
[/codesyntax]
Sonuç olarak Run’liyoruz.

_________________________________________________

Evet arkadaşlar bunları öğrendik ama ne yapabiliriz kısmınıda paylaşmak istedim. İstediğiniz herhangi bir cihazı kontrol edebilirsiniz.
Bende sizlere daha çok yardımcı olmak amacıyla bir uygulama geliştirdim.

Uygulamanın amacı hangi eksende telefonumu döndürürsem o yönü belirten bir kod yazmak istedim siz bunları daha da ilerletebilirsiniz. Belki bir başka projede bir arabayı bu yöntem ile yönetebiliriz. Bu tip uygulamaları yapıp elinizin daha yatkın , fikrinizin daha hızlı düşünür olmasını sağlayabilirsiniz.

Uygulamaya başlayacak olursak ben ekranımı yatay olarak olmasını istedim bunun için onCreate(Bundle savedInstanceState ) içine

this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

yazdığımız zaman ekranımız yan dönmektedir. Bunun sebebi Orientation kısmında saklı dikkat ettiyseniz setRequestedOrientation olarak çağırmışız bu görüntümüz hakkında birşeyler yapacağımızı belirtmemekte ancak set etme ile görüntüyü ayarlayabileceğimiz fonksiyondur. SCREEN_ORIENTATION_LANDSCAPE ekranı yan çevirme görevi üstlenmektedir. ActivityInfo da bu özelliği barındıran bir class olup set ettiğimiz taktirde bu durumu uygulaması gerektiğini söylüyoruz.
Tabi ekranı sadece dik yapabilmekte mümkündür. Bunun için ise SCREEN_ORIENTATION_ PATRIOT ‘u seçmeniz yeterlidir.

Devamında ekranı yatay tuttuğumuz zaman ;

bedenimden ileri yönlendirdiğim zaman : -x 
bedenime yaklaştırdığımz zaman               : +x
sağ tarafıma yönlendirdiğim zaman          : +y
sol tarafıma yönlendirdiğim zaman           : -y

yönleri olduğunu farkedeceğiz bir önceki uygulamamızda bende şöyle dedim. Eğer bu yönleri veriyorsa o zaman sensör bilgileri bana geldiğinde süzüp temiz hale getirip bunları değerlendireyim .
Kendimce yönleri azami değerler vererek okumasını sağladım.

İleri : -3     <-  -x yönünde
Geri :  9     <-  +x yönünde
Sol   : -5    <-   -y yönünde
Sağ  :  5     <-  +y yönünde

Herzamanki gibi kodumu onSensorChanged fonksiyonumun içine yazıyorum ve  gelen kodu ayrıştırma işlemi yapıyorum öncelikle.Yaptığım işlem tamamen şöyle ;

float xFloat = event.values[0] ;
String xString = Float.toString(xFloat);
char xChar = xString.charAt(0);
char xChar1 = xString.charAt(1);

İlk gelen değeri bir float‘a atıyorum. Daha sonra String dönüşümü yapıyorum. Bu String’i char’lara bölüyorum böylelikle parçalara bölmüş oluyorum. Burada dikkat etmeniz gereken şey +x yönünde iken ‘+’ sembolünün gelmemesidir. O yüzden if döngünüzde bunu kullanmamanız.
Aynı işlemi y içinde yapıyoruz ancak event.values[1] yapıyoruz.

 ve Kodumun tamamı burada sadece bir önceki uygulamada olan MainActivity.java ‘yı değiştirmeniz yetecektir.

[codesyntax lang=”java” container=”pre_valid” title=”MainActivity.java”]
package com.example.yonbulmauygulama;

import com.example.yonbulmauygulama.R;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener {

TextView tx1;

@Override
protected void onCreate(Bundle savedInstanceState) {
//yatay cevirme kodu.
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

SensorManager sensorYoneticisi = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

Sensor yonSensoru = sensorYoneticisi.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

tx1 = (TextView)findViewById(R.id.textView1);

if(!sensorYoneticisi.registerListener(this, yonSensoru, SensorManager.SENSOR_DELAY_GAME)){

tx1.setText(“Sensor çalışmıyor..”);

}
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub

}

@Override
public void onSensorChanged(SensorEvent event) {

float xFloat = event.values[0] ;
String xString = Float.toString(xFloat);
char xChar = xString.charAt(0);// – +7
char xChar1 = xString.charAt(1);//2

float yFloat = event.values[1] ;
String yString = Float.toString(yFloat);
char yChar = yString.charAt(0); // – +3
char yChar1 = yString.charAt(1);// 4

if(xChar == ‘-‘ && xChar1 == ‘3’){
tx1.setText(“ileri!!! “+xChar+xChar1);
}else if(xChar == ‘9’){
tx1.setText(“geri!!! ” + xChar);
}else if(yChar == ‘-‘ && yChar1 == ‘5’){
tx1.setText(“sola!!! ” + yChar+yChar1);
}else if(yChar == ‘5’){
tx1.setText(“sağa!!! “+yChar);
}

}

}

[/codesyntax]

Ve uygulamamızı birde görsel olarak görecek olursak.

Yazımı takip edip okuduğunuz için teşekkür ederim sorunlarınız için mail yada yorum yazmanız yeterlidir.İsteğinize göre android hakkında bilgi paylaşımıda yapabilir , yazı yazabilirim.

İyi çalışmalar

______
Gökhan TARIM
tarim.gokhan@gmail.com