Windows 7'de Sensor and Location API ile Sensör kullanımı

0 dakikada yazıldı

9939 defa okundu

Düzenle

Windows 7 ile beraber gelen ve daha pek de hissedemediğimiz
değişiklikler biri de "Sensor and Location API" adını taşıyor.
Adından da anlaşılacağı üzere aslında yeni bir API topluluğundan
bahsediyoruz ve bu topluluğun biz .NET yazılım geliştiricilere sağladığı
şey ise işletim sistemi üzerinden donanım bağımsız olarak rahatlıkla
Konum (GPS) ve diğer farklı sensörlere ulaşma altyapısı. Tabi bunun
içinn elinizde söz konusu donanımın bulunması ve donanımın da Windows 7
sürücülerini taşıması veya Windows 7 uyumlu olması şart.

Ben bu makaleyi yazarken FreeScale tarafından üretilmiş deneme ve
yazılım geliştirme amaçlı kullanılabilecek bir Sensör kitinden
faydalandım. Bu tip sensörlerin çok yakında donanımsal olarak da
laptoplara entegre edilmesi ilginç sentaryolara olanak tanıyabilecek. Bu
durum ister laptoptaki bir accelerometer aracılığı ile laptopun fiziksel
durumunu anlamak olsun ister laptopun içerisinde bulunduğu ortamdaki
ışık miktarına bakarak otomatik olarak ekran parlaklığından tutun
uygulamaların içerisindeki yazıların punto ve renklerine kadar kendi
kendilerine ortam ışığına göre adapte etmelerine kadar farklı senaryolar
uygulanabilir.

FreeScale sensör kit ile Windows 7 denemeleri.
FreeScale sensör kit ile Windows 7 denemeleri.

Sensörlere ulaşmak için Windows 7'nin "Sensor and Locaiton API"larını
kullanmak durumundayız. Bu API'lar için gerekli .NET Wrapper'ları ise şu
ancak ayrı olarak bilgisayarınıza indirebileceğiniz bir paket. .NET
Framework 4.0 ile beraber bu Wrapper'lar Framework'e dahil edilecek ve
herhangi bir şekilde ayrıca downloada gerek kalmayacak. Fakat şimdilik
gerekli DLL'leri aşağıdaki adresten bilgisayarınıza indirmeniz şart.

http://code.msdn.microsoft.com/SensorsAndLocation/Release/ProjectReleases.aspx?ReleaseId=2359

Download işlemini tamamladıktan sonra gerekli projeyi de compile edince
karşınıza Windows7.SensorAndLocation.dll adında bir dosya
çıkacaktır. Bu dosya bizim Sensörlere ulaşmamız için gerekli wrapperları
sunacak. Artık yeni bir proje yaratarak hızlıca sensörlerimize
ulaşabiliriz.

Örnek olarak bir WPF projesi yaratarak XAML kısmına da basit bir
TextBlock koyalım. Bu örnekte hedefimiz sisteme bağlı bir ışık sensörüne
gelen ışık miktarını yakalayarak değişikliklere de göre sürekli durumu
takip edebilmek.

[XAML]

<Window
x
:Class="Window1"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Title="Window1"
Height
="300" Width="300">

    <Grid>

        <TextBlock
x
:Name="txtMiktar"
Text
="12" />

    </Grid>

</Window>

Yeni yarattığımız WPF projesine Windows7.SensorAndLocation.dll
DLL'imizi de referans aldıktan sonra hemen kod tarafına geçiş yapıyoruz.
İlk amacımız sisteme bağlı ışık sensörlerinin bir listesini almak.

[VB]

    Private Sub Window1_Loaded(ByVal sender As Object,
ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Dim IsikSensorleri =
SensorManager.GetSensorsByType(Of
Sensors.Light.AmbientLightSensor)()

        Dim IlkSensor =
IsikSensorleri(0)

        AddHandler
IlkSensor.DataUpdated, AddressOf
Sensor_VeriGeldi

    End Sub

Kodumuzun daha ilk satırında Generic bir metod kullanıyoruz.
GetSensorsByType metoduna uygun Senör tipi olarak
AmbientLightSensor verdiğimizde geriye sisteme bağlı ışık
sensörlerinin bir listesi dönüyor. Bu listeden hemen ilk sensörü
yakalayarak devam edebiliriz. Tabi siz farklı durumlarda birden çok
sensör ile beraber işlem de yapabiliriz hatta bu koda "sistemde
gerçekten ışık sensörü var mı?" gibi kontrolleri de eklemek gerek.
Şimdilik makaleyi amacından şaşırmamak ve çok uzatmamak adına bu gibi
kontrolleri konu dışı bırakıyorum.

Son satırda elimizdeki sensörün DataUpdated event'ını yakalıyoruz. Bu
noktada önemli olan detaylardan biri bu event'ın ayrı bir Thread'de
çalışacak olması. O nedenle bir sonraki adımda bu event'ı yakaladığımız
kodumuzdan tekrar UIThread'e dönebilmek için ufak bir takla atacağız.

[VB]

    Private Sub Sensor_VeriGeldi(ByVal sensor As Windows7.Sensors.Sensor, ByVal dataReport As Windows7.Sensors.SensorDataReport)

        Dim IsikMiktar =
dataReport.GetDataFields().ToList(2).Value

        Dim Zaman =
dataReport.GetDataFields().ToList(1).Value

 

        Dim Parametreler
As New
List(
Of Object)

        Parametreler.Add(IsikMiktar)

        Parametreler.Add(Zaman)

        Me.Dispatcher.BeginInvoke(New
Aktar(
AddressOf VeriGeldi), Parametreler.ToArray())

    End Sub

Sensöre her veri geldiğinde yukarıdaki method çalışacak ve bahsettiğimiz
gibi bu method UIThread'e değil! İlk olarak dataReport parametresi
üzerinden sensördeki ışık miktarını ve bu raporun bize aktarıldığı tam
zaman dilimini ayrı ayrı değişkenlere alıyoruz. GetDataFields metodu
bize bu sensör ile ilgili tüm verileri bir Key/Value Pair Dictionary
olarak aktarıyor. Key'ler biraz karışık olduğu için hemen listeye
çevirip index üzerinden istediğimizi yakalamak daha kolay olabilir. Ne
de olsa bu listelerdeki Field sayıları sensör tipine spesifik ve sabit.

[VB]

    Private Sub Sensor_VeriGeldi(ByVal sensor As Windows7.Sensors.Sensor, ByVal dataReport As Windows7.Sensors.SensorDataReport)

        Dim IsikMiktar =
dataReport.GetDataFields().ToList(2).Value

        Dim Zaman =
dataReport.GetDataFields().ToList(1).Value

 

        Dim Parametreler As New
List(Of Object)

        Parametreler.Add(IsikMiktar)

        Parametreler.Add(Zaman)

        Me.Dispatcher.BeginInvoke(New Aktar(AddressOf VeriGeldi),
Parametreler.ToArray())

    End Sub

Gelelim eventımızı yakaladığımızda ve verileri aldığımızda bunları
UIThread'e aktarmanın yoluna. WPF'de Dispatcher üzerinden UIThread'e
ulaşabiliriz. Bunun için ayrıca bir Delegate ve bir de Method yaratmak
şart. Bu methodlar iki ayrı parametre alacaklar, biri IsikMiktar
diğeri ise Zaman. Eldeki parametre değerlerini de bir Array olarak
gönderiyoruz.

[VB]

    Delegate Sub Aktar(ByVal IsikMiktar As Object,
ByVal Zaman As Object)

 

    Sub VeriGeldi(ByVal IsikMiktar As Object,
ByVal zaman As Object)

        txtMiktar.Text = IsikMiktar.ToString & ", " & zaman.ToString

    End Sub

Yukarıda gördüğünüz VeriGeldi kodumuz artık Dispatcher sayesinde
UIThread'de çalışıyor. Yani rahatlıkla UIElement'lerimize ulaşabiliriz.
Gelen parametreleri şimdilik alıp ilk aşamada ekrana yerleştirdiğimiz
TextBlock üzerine yazdırıyoruz.

Gördüğünüz gibi bir sensöre ulaşarak değişiklikleri takip etmek bu kadar
kolay. Tabi bu noktadan sonra tüm bu değişikliklere göre nasıl işlemler
yapacağınız size kalmış. Örneğin bu şekilde bir sensör bağladığınız
ortamdaki ışık miktarı arttıkça Windows 7 ekran parlaklılığını da
arttıyor. Ortamdaki ışık miktarı azalınca ise ekran parlaklığı azalıyor.
Böylece gözünüz çok daha rahat bir şekilde ekrandaki içeriği
algılayabiliyor.

Kullanmanız olası tüm diğer farklı sensör tiplerinde de veri
değişikliğini yakalama ve UIThread'e atkarma mekanizması bire bir aynı.
Değişen tek şey DataFields Collection'ında gelecek bilgilerin sayıca
artması veya azalması olacaktır.

Hepinize kolay gelsin.