Ana Sayfa | English Blog | Seminer TV | Dil Cookie Sil  Blog'u Mail ile takip et!  
Daron Yöndem - Windows 7'de Sensor and Location API ile Sensör kullanımı
bir yazılımcının tasarıları...
 Wednesday, November 04, 2009

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.

Wednesday, November 04, 2009 4:57:54 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Windows 7  | 
Copyright © 2010 Daron Yöndem. Tüm hakları saklıdır.