Windows Phone 7'de Multitasking

0 dakikada yazıldı

9565 defa okundu

Düzenle

Şu ana kadar bildiklerimize dayanarak Windows Phone 7'nin multitasking
desteklemeyeceğini rahatlıkla söyleyebiliriz. Bu durum birer yazılım
geliştirici olarak çok işimize gelmese de aslında son kullanıcı
açısından bunun birçok faydası var. Cihazların pil ömründen tutun
performansına kadar çoğu noktada multitasking aslında cebimizde bu minik
cihazların kaldıramayacağı bir yük gibi duruyor. Son kullanıcı
tarafından baktığımızda sadece kabaca bu duruma iPhone ile herkes
alışkın. İşin bir diğer komik yanı ise aslında hiçbir son kullanıcının
pek de bu durumu önemsemiyor olması. Yani biz yazılımcılar kadar konuya
teknik açıdan bakıp endişelenen pek yok gibi :)

Bir son kullanıcı için önemli olan aslında çalıştırdığı programın arkada
çalışıp çalışmadığı bilmekten öte istediği işin yapılıp yapılmadığını
veya daha sık karşılaştığımız senaryolarda herhangi bir işin takibinin
yapılıp yapılmadığını bilmek. Daha somut bir örnek vermek gerekirse
varsayalım ki bir mail istemcisi kullanıyorsunuz. Normalde
bilgisayarımızda mail programını açık tutmamızın nedeni mail geldiğinde
haberdar olmaktır. Oysa bunun için koca mail programının açık olmasına
gerçekten gerek var mı? Yani daha ufak bir yapı arkada mail geldiğinde
haberdar olsa da bize ufak bir uyarı mesajı verse? Sonra gerekiyorsa ben
mail programını çalıştırıp istediğimi yapsam olmaz mı? İşte Windows
Phone 7 içerisinde yer alan PushNotification sistemi de tam olarak
bunu çözüyor.

Olayın işleyişine bir göz atalım...

Push mesajlarının gönderiminde toplam üç farklı kimlik bulunuyor
diyebiliriz. Bunlardan biri mesajı dinlemede olan telefon, diğeri mesajı
gönderen servis, bir diğeri ise iki servisin birbirine ulaşabilmesini
sağlayan bir anlamda router görevi gören Microsoft servisi. Her telefon
dinleme moduna geçerken bir kanal ismi tanımlayarak kendini "Microsoft
Push Notification Service" üzerinde tanımlıyor.

Push Notification Service'inden cihaza özel ulaşım adresi alıyoruz.
Push Notification Service'inden cihaza özel ulaşım adresi alıyoruz.

Yukarıdaki şemada da görebileceğiniz üzere telefon kendi dinleme kanal
adı ile servise başvurarak bir adres talep ediyor. Bu adres farklı
servislerin telefona push notification gönderirken kullanacakları adres
olacak. Böylece rahatlıkla bu adrese sahip her tür yazılım bu adres
üzerinden notification gönderebilecek. Söz konusu notification'lar
uygulamanız kapalı olsa da işletim sistemi tarafından dinleneceği için
uyarılar her zaman kullanıcılara gösterilebilecek. Tabi bu sistemin
çalışması için daha önce de bahsettiğimiz üzere bizim de push
notificationları sağlayacak bir servise ihtiyacımız var ve bu servisin
de telefonun adresine sahip olması gerekiyor.

Push Notification telefona gönderiliyor.
Push Notification telefona gönderiliyor.

İlk aşamada telefon bizim yazacağımız bir servise kendi adresini
aktarıyor. Böylece servis artık telefona ulaşabileceği adresi bildiğine
göre Push Notification yollmaya hazır. Aslında telefon verdiği adres tam
olarak kendi adresi de değil :) Unutmayın bu adres Microsoft Push
Notification Service'in verdiği adres. Telefon Microsoft Push
Notification Service'den aldığı adresi bizim servise veriyor ve artık
bizim servis de bu adrese istediği mesajı gönderiyor. Gönderilen bu
mesaj özünde yine Microsoft Push Notification Service'e gidiyor ve
Microsoft Push Notification Service'de mesajı telefona iletiyor. Böylece
MSPush Notification Service ile cihaz bir Socket bağlantısına sahipken
bizim servisimiz sadece istediğinde MS Push Notification Service ile
bağlantı kurarak mesaj gönderebiliyor.

Peki nasıl yapacağız bu işleri?

Biz kendi servisimizi temsil etmek üzere bir WPF uygulaması yazalım.
Böylece WPF uygulaması kendi içerisinden telefona PUSH mesaj
yollayabilir olsun. Uygulamamızın içerisinde telefondan gelecek adres
bilgisini alabilecek bir servis olması gerek. Bu servise gelen adrese
sonrasında gönderim yaparak telefonu PUSH data yollamış olacağız. 

[VB]

Public Class Service1

    Implements IService1

 

    Public Sub SetURL(ByVal URL As System.Uri) Implements IService1.SetURL

        MainWindow.URL =
URL.AbsoluteUri.ToString()

    End Sub

End Class

Gördüğünüz gibi servisimiz epey basit. Tek yaptığı adresi alıp WPF
uygulamamızın içerisinde başka bir sınıfta tanımlı shared bir obeye
atamak. Herhangi bir sorunla karşılaşmamak adına servisi
basicHttpBinding olarak ayarlamanızı tavsiye ederim. Servisin default
gelen design adresini kullanarak WP7 uygulamamıza referans olarak
ekleyebiliriz hemen. WPF uygulamasında App.Config içerisinde
http://localhost:8732/Design_Time_Addresses/WpfApplication1/Service1/
gibi bir adres göreceksiniz. Uygulamamız örnek amaçlı olduğu için
doğrudan bu adresi kullanarak WP7 uygulamanıza service reference
ekleyebilirsinzi. Tabi onun öncesinde bu servisin host edilmesini de
sağlamamız gerek.

[VB]

    Public Shared URL As String

 

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

        Dim SHost As New
ServiceHost(GetType(Service1))

        SHost.Open()

    End Sub

İşte bu kadar basit. Uygulamamız açıldığı anda bu servisi host edecek ve
böylece bizim WP7 uygulaması da bunu referans alıp kullanabilecek.
İsterseniz şimdi de gelin WP7 uygulaması tarafındaki
PushNotificationService tanımına bakıp Microsoft Push Notification
Service üzerinden adres alıp bizim WPF uygulamasına göndermeye
çalışalım.

[C#]

        private void button1_Click(object sender, RoutedEventArgs e)

        {

            var Kanal = new HttpNotificationChannel("UygulamaKanali15");

            Kanal.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(Kanal_ChannelUriUpdated);

            Kanal.Open();

            Kanal.BindToShellNotification();

        }

Kodumuzda yarattığımız HttpNotificationChannel sınıfı
Microsoft.Phone.Notification assembly'si altında olduğu için söz konusu
DLL'i projeye referans olarak eklemeyi unutmayın. Sonrasında
HttpNotificationChannel nesnemizi yaratarak kendi tanımladığımız bir de
kanal ismi veriyoruz. Nesnemize ait ChannelUriUpdated event'ı
Microsoft Push Notification Service'den cihazın adresi geldiğinde
çalışıyor. Özünde biz şu anda hem Push Listener tanımlayıp bunun için
Microsoft Push Notification Service'den adres isteyerek elimizdeki Push
Notification Service'i de BindToShellNotification ile işletim
sistemine aktarıyoruz. Adres geldiğinde söz konusu adresi bizim WPF
uygulamasındaki servise aktaracağız.

[C#]

        ServiceReference1.Service1Client Servis = new ServiceReference1.Service1Client();

 

        void
Kanal_ChannelUriUpdated(object
sender, NotificationChannelUriEventArgs e)

        {

            Servis.SetURLAsync(e.ChannelUri);

        }

WPF uygulamamızdaki servisi reference aldığımıza göre içerisindeki
SetURL metodunu kullanarak ChannelUriUpdated eventinden gelen
adresi gönderebiliriz. Böylece WP7 uygulamamız kendi adresini alıp bizim
servise göndermiş oldu. Bir sonraki adımda bizim bu adrese yani
Microsoft Push Notification Services'a bir mesaj yollamamız gerekiyor ki
mesaj telefona iletilsin ve kullanıcıya gösterilsin. Bu nedenle
geçiyoruz yine WPF uygulamamıza.

[VB]

        Dim MesajXML = <?xml version="1.0"
encoding="utf-8"?>

                       <wp:PushNotification xmlns:wp="WindowsPhonePushNotification">

                           <wp:Toast>

                              
<wp:Text1>Mesaj1</wp:Text1>

                              
<wp:Text2>Mesaj2</wp:Text2>

                           </wp:Toast>

                       </wp:PushNotification>

 

        Dim Mesaj As String
= "X-WindowsPhone-Target: toast" &
vbCrLf & vbCrLf & MesajXML.ToString()

Yukarıdaki gördüğünüz XML paketi Microsoft Notification Service'e
göndermemiz gereken paket. Bu paketin otomatik hazırlanması ile ilgili
bir helper sınıfı eminim ki yakında yayınlanacaktır. Fakat şimdilik elle
yapmamız gerekiyor. Paketin içerisinde iki adet String data var. Bu
dataları istediğiniz gibi değiştirebilirsiniz. Son olarka hazırladığımız
bu paketi daha önce servisimize iletilmiş olan adrese gönderiyoruz.

[VB]

        Dim Gonder As HttpWebRequest = WebRequest.Create(URL)

        Gonder.Method = "POST"

        Gonder.Headers = New WebHeaderCollection()

        Gonder.ContentType = "text/xml"

        Gonder.Headers.Add("X-NotificationClass", "2")

 

        Dim ByteArr = New UTF8Encoding().GetBytes(Mesaj)

        Gonder.ContentLength = ByteArr.Length

        Dim GStream =
Gonder.GetRequestStream

        GStream.Write(ByteArr, 0, ByteArr.Length)

ToastNotificaton olarak adlandırılan ve telefonun ekranının üst
kısmında bir uyarı olarak çıkan bu mesajlar için üç farklı aciliyet
seviyesi belirleyebiliyorsunuz. Yukarıdaki kod içerisinde 2 değeri
anında teslimat yapılması gerektiğini belirtliyor. 12 ve 22 gibi değer
vererek mesajınızın ToastNotification'lar harici farklı Push
Notification mesajları arasında da nasıl önceliklendirilebileceğini
belirtebiliyorsunuz. Eh artık herşey hazır. WPF uygulamamızı çalıştırıp
WP7 uygulamamızı da başlatabiliriz. WP7 uygulaması ilk olarak Microsoft
Notification Services'a bağlanıp kendine bir adres yarattıracak.
Sonrasında bu adresi bizim WPF uygulamamıza verecek. WPF uygulamamız da
artık istediği zaman bu adres mesaj gönderebilecek. Burada önemli olan
nokta telefonda uygulamanız kapalı olsa da mesaj işletim sistemi
tarafından alınarak kullanıcıya gösterilebilecek.

ToastNotification sahnede.
ToastNotification sahnede.

Hepinize kolay gelsin.