23 Ocak 2011

Windows Phone 7 Media Element

Windows Phone, ses ve görüntü dosyalarını oynatabilmek için de oldukça başarılı bir ortam sunmaktadır. Kullanımı kolay ve gelişmiş Silverlight mediaelement nesnesi ile phone uygulamalarımıza güçlü media özellikleri kazandırabiliriz. Bu makalemizde yeni bir Windows Phone 7 uygulaması oluşturarak, örneklerle mediaelement komponentini inceleyeceğiz.


Mediaelement komponenti ile, oynatacağımız .mp3 veya .wav uzantılı dosyaları projemize ekleyerek, ya da uzak bir sunucuda yayınlanan bir media kaynağına erişim sağlayarak da bu dosyaları oynatabiliriz. Uzak sunucuda yer alan media dosyasının Uri adresini mediaelement' in Source Property 'sine bağlamamız bunun için yeterli olacaktır. Eğer uzak sunucudaki bir dosyaya erişmek yerine bu dosyaları projemize eklemek istiyorsak, bu dosyaların BuildAction özelliğinin "Content" ve CopyToOutput özelliğinin de "Copy Always" 
olmasına dikkat edelim.



Dikkat edilmesi gereken önemli bir nokta da windows phone için hangi codec bileşenlerinin desteklendiğidir. Örneğimize başlamadan önce, desteklenen windows phone media codec listesini buradan (Supported 
Media Codecs for Windows Phone)  inceleyebilirsiniz.


Projemize content olarak ekleyeceğimiz bir mp3 dosyasını oynatarak örneğimize başlayalım. Tabii her zamanki gibi ilk iş olarak Visual Studio / File / New / Project / Visual C# / Silverlight For Windows Phone template'i seçip, yeni bir Windows Phone projesi oluşturalım. Toolbox penceresinden mediaelement ' i tutup sürükleyerek default olarak oluşturulmuş olan MainPage.xaml sayfamızın üzerine bırakalım.












Bilgisayarımda hazır bulunan örnek müziklerimden Sleep Away.mp3 dosyasını da projeme content olarak ekliyorum. Copy To Output Directory özelliğini Always True olarak seçiyorum. AutoPlay="True"  olarak 
seçip, ilk açılışta otomatik olarak mp3 dosyasının çalınmasını sağlayacağım.


XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="2,0,2,0">
     <MediaElement x:Name="myMediaElement" Margin="10" 
                   Source="/Sleep Away.mp3" AutoPlay="True"/>
</Grid>


Benzer bir şekilde, yukarıdaki mediaelement nesnesinin Source özelliğine uzak bir sunucuda yer alan dosyanın Uri adresini set edeceğim. Test amacıyla uzak sunucu olarak kendi bilgisayarımda bulunan iis dizini altına 
(inetpub/wwwroot) mymuzik isminde bir klasör oluşturup Kalimba.mp3 isimli dosyamı buraya kopyalıyorum. Bu yöntem ile media dosyalarının direk olarak IIS' den yayınlanması tabiki doğru bir çözüm değildir. Sağlıklı bir çözüm için Windows Media Services veya IIS Smooth Streaming yöntemleri kullanılabilir. Eğer 
Windows Media Sevis'i kurmak istiyorsak, http://daron.yondem.com/tr/PermaLink.aspx?guid=c44b96e8-e240-4ede-8c1f-7bdc000da97f linkinde yer alan makaleyi de inceleyebilirsiniz. (Ayrıca iis smoot streaming incelemek isteyenler http://www.iis.net/download/SmoothStreaming adresini ziyaret edebilirler.) Bu makalemizin konusu media dosyalarının yayınlanması olmadığı için kaldığımız yerden devam edelim.


XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="2,0,2,0">
    <MediaElement x:Name="myMediaElement" Margin="10" 
                  Source="http://localhost/mymuzik/Kalimba.mp3" 
                  AutoPlay="True"/>
</Grid>


MediaElement nesnesinin Source özelliğini direk olarak set ettiğimiz için ilgili media dosyasının yüklenmesi belirli bir zaman alabilir. Ya da oynatacağımız dosya içinde oluşmuş bozulmalardan kaynaklı yavaşlamaları 
engellemek için de öncelikle dosyayı telefonumuzun isolated storage alanına indirerek oynatmayı da deneyebiliriz. (Windows Phone Isolated Storage konusunuda ayrıca bir makalede inceleyebiliriz.) Isolated Storage alanı, adından da anlaşılacağı üzere uygulamamız tarafından kullanabileceğimiz, diğer uygulamalardan yalıtılmış bir yazma ve yazdıklarımızı okuma alnıdır. Uygulamamız için özel olarak tahsis edilmiş bir bellek alanıdır. Şimdi WebClient nesnesi ile uzak sunucumuzdaki Kalimba.mp3 dosyamıza okuma çağrısında bulunalım ve sonucu asenkron olarak elde edelim. Elde edeceğimiz result değeri Stream tipinde olacaktır. Gelen stream değerini bir döngü içerisinde öncelikle isolated storage alanına yazdıktan sonra mediaelement' 

imizin SetSource özelliğini kullanarak oynatalım.

XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="2,0,2,0">
    <MediaElement x:Name="myMediaElement" Margin="10" />
</Grid>

C#
public MainPage() {
  InitializeComponent();
  Loaded += MainPage_Loaded;
}
 
void MainPage_Loaded(object sender, RoutedEventArgs e) {
  WebClient web = new WebClient();
  web.OpenReadCompleted += web_OpenReadCompleted;
  Uri myAddress = new Uri("http://localhost/mymuzik/Kalimba.mp3");
  web.OpenReadAsync(myAddress);
}
 
void web_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) {
  if (e.Error == null) {
    using (var s = e.Result) {
      using (var isolatedFile = new IsolatedStorageFileStream("Kalimba.mp3",
      FileMode.Create, IsolatedStorageFile.GetUserStoreForApplication())) {
        int i;
        var buffer = new byte[10000];
        while ((i = s.Read(buffer, 0, buffer.Length)) > 0) {
          isolatedFile.Write(buffer, 0, i);
        }
        isolatedFile.Seek(0, SeekOrigin.Begin);
        this.myMediaElement.SetSource(isolatedFile);
      }
    }
  }
}

Şimdi de yukarıdaki örneğimizden farklı olarak, uzak bir sunucu da bulunan örnek bir videoyu oynatarak medielement nesnemizin özelliklerini tanımaya çalışalım. Xaml kodlarımızı aşağıdaki gibi hazırlayalım. 
MediaElement'in Source'una Uri adresini C# kodu ile set edeceğiz. 


XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <MediaElement 
            Height="423" 
            Width="438"
            Margin="5" 
            Name="myMediaElement" 
            VerticalAlignment="Top"
            AutoPlay="True"/>
        <TextBlock 
            Height="34" 
            HorizontalAlignment="Left" 
            Margin="12,476,0,0" 
            Name="txtState" 
            Text="" 
            VerticalAlignment="Top" 
            Width="152" FontSize="24" />
        <TextBlock 
            Height="34" 
            HorizontalAlignment="Left" 
            Margin="175,476,0,0" 
            Name="txtPercentage" 
            Text="" 
            VerticalAlignment="Top" 
            Width="90" FontSize="24" />
    </Grid>
</Grid>

Videomuz otomatik olarak öncelikle telefonumuzun belleğine alınacaktır. Playing (Oynatma) başlamadan önce, buffering (arabelleğe alma) için gereken süreyi de dilersek belirtebiliriz. Bunun için mediaelement' in BufferingTime özelliğine TimeStamp türünde değer atanabilir. 
Şimdi C# ile uzuk sunucudaki video ile bağlantı kurarak, media element nesnemizde oluşacak state'leri (opening, buffering, playing), buffering olan miktarı ekranımıza yazdıralım.

C#
public MainPage()
{
    InitializeComponent();
    Loaded += MainPage_Loaded;
}
 
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    myMediaElement.CurrentStateChanged +=
      myMediaElement_CurrentStateChanged;
    myMediaElement.BufferingProgressChanged +=
      myMediaElement_BufferingProgressChanged;
    myMediaElement.Source =
      new Uri("http://mschannel9.vo.msecnd.net/o9/mix/09/wmv/key01.wmv");
}
 
void myMediaElement_BufferingProgressChanged(object sender, RoutedEventArgs e)
{
    double percent = myMediaElement.BufferingProgress;
    string str = percent == 1d ? "Ok." : string.Format("{0:P}", percent);
    txtPercentage.Text = str;
}
 
void myMediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    txtState.Text = myMediaElement.CurrentState.ToString();
}
 
F5 ile emulatör üzerinden uygulamamızı başlatalım, txtState TextBlock üzerinde o an ki durumu, txtPercentage TextBlock üzerinde ise yüzde olarak ne kadarlık buffer miktarının tamamlandığını göreceğiz.




































Buffering tamamlandıktan sonra video'nun oynamaya başladığını ve txtState TextBlock nesnesine "Playing", txtPercentage üzerine ise "Ok." yazılacağını göreceğiz. Media Element komponentimizin genel olarak ne tür de özelliklere ve methodlara sahip olduğunu bir tablo üzerinden inceleyerek makalemizi sonlandıralım.

Property (Özellik) Açıklama
Source Oynatılacak media dosyasının Uri adresidir.
Volume Oynayan dosyanın ses düzeyini belirlemek için kullanılır. Default
olarak 0.5'dir (Orta seviye).
Position TimeStamp türü ile oynayan media dosyasının zaman çizelgesinde,
hangi pozisyonda olduğu bilgisidir. Dilersek Position değerini set
ederek, istediğimiz pozisyondan başlatabiliriz.
NaturalDuration TimeSpan türünde oynayan dosyanın ne kadar uzunlukta olduğunu
belirtir.
IsMuted İstenirse oynayan dosya sessiz duruma getirilebilir. O an ki ses
durumu da (kapalı/açık) elde edilebilir.
DownloadProgress Yüzdelik olarak ne kadar download edildiği bilgisini tutar.
CanPause Oynayan media'nın pause olup, olamayacağı bilgisini verir.
ReadOnly'dir.
CanSeek Position değerine müdahale edilip edilemeyeceği bilgisini döner.
Methods
Pause Eğer CanPause property true ise Pause methodu ile media durdurulur.
Pause durumunda oynayan son film karesi görüntülenecektir.
Play Media dosyasını oynatır. Eğer durum stop veya pause ise tekrar
oynamaya başlayacaktır.
Stop Oynayan media dosyası durdurulacaktır. Bu durumda ilk film karesi
ekranda gösterilecektir.
SetSource Stream bir değeri parametre olarak set edebiliriz. Yukarıdaki
örneğimizde de yaptığımız gibi Isolated Storage alanına depolanmış bir media' yı oynatmak için oldukça kullanışlıdır.


Bir sonraki makalemizde görüşmek üzere.
Kolay gelsin.

2 Ocak 2011

Windows Phone 7 de Touch, Multi-Touch Inputs (Dokunmatik-Girişler)

Teknolojik bir gelişme ya da buluş, bereberinde çok farklı alanların da gelişmesinin tetikleyicisi olmuştur. Bu gelişme, özellikle insan duyu organları ile daha çok hissedilebilir türden bir gelişme ise son kullanıcılar tarafından yaygınlaşması ve popüleritesi de o oranda çok olmaktadır. Son yıllarda touch screen (dokunmatik ekran) ya da özellikle multi-touch screen 'in (çoklu-dokunmatik ekran) gelişmesi ile birlikte telefon dünyasına da bu özelliklerin hızla girdiğini ve bu tür özellikleri destekleyen uygulamaların da gün geçtikçe çoğaldığını gözlemlemekteyiz. Bu makalemizde bir Windows Phone 7 uygulaması ile touch ve multi-touch ekran özelliklerini incelemeye çalışacağız. Öncelikle hangi tür touch ve multi-touch özelliklerin kullanıldığına göz atalım. (Bu özelliklere literatürde geçtiği gibi Gestures (el hareketleri) olarak adlandıracağız.)

Tap Gesture
Kullanıcının ekrana dokunması ve hemen elini çekmesiyle elde edilir. Ekran üzerindeki pek çok kontrol bu event ile çalışmaktadır. Mouse ile sıkça kullandığımız click event'ıyla aynı özelliktedir. Kullanıcı tarafından
bilinen en temel dokunma türüdür.

Double-Tap Gesture
Çok kısa bir zaman dilimi içerisinde Tap gesture'ın tekrar etmesi ile elde edilen harekettir. Çoğu zaman bu gesture da kullanılmaktadır. Ard arda hızlıca iki kez dokunma da diyebiliriz. 2 dokuma arası yaklaşık olarak 1sn veya daha az bir süre olmalıdır.

Pan Gesture
Ekrana parmağımızı koyup parmağın hareket ettirilmesi ile sağlanan harekettir. Örneğin bir resmin touch screen üzerindeki hareketi/yer değiştirmesi bu event'ın yakalanması ile sağlanabilir. Ya da windows phone giriş ekranında bulunan bir tile, öncelikle seçilir daha sonra da pan gesture ile yeri değiştirilebilir. Desktop
uygulamalarında mouse ile kullandığımız Drag and Drop ile benzer işlevdedirler.

Flick Gesture
Parmağımızı touch-screen üzerinde belirli bir yönde hızlıca hareket ettirerek elde edilen harekettir. Örneğin bir Windows Phone list kontrol üzerinde parmağımızı aşağı veya yukarı yönde hareket ettirdiğimizde list box item'ların da o yönde hareket ettiğini hatta parmağımızı çektiğimizde bir süre daha list box item'ların o yönde hareket ettiğini görebiliriz.

Tap and Hold Gesture
Kullanıcı ekrana dokunur, aynı noktada belirli bir süre parmağını bekletir, bir süre sonra bir context menünü açılır. Windows Mobile işletim sistemli cihazlardan da anımsayacağımız gibi bu event mouse sağ click event'ı elde etmek için kullanılır.

Multi-Touch Gesture (Pinch and Stretch)
Kullanıcının ekranın birden fazla yerine aynı anda dokunarak elde ettiği harekettir. Örneğin yaygın olarak kullanımı bir içeriği veya resmi zoom-in veya zoom-out yapmak için kullanılır.





Windows Phone 7 Developer Tools ile Gestures yakalayabilmenin oldukça kolay olduğunu birazdan örnek kodlarla inceleyeceğiz. Şimdi örneklerle en temel gesture'dan başlayarak incelemeye başlayalım.

Tap Gesture Örneği
Windows Phone Developer Tools ile birlikte gelen component'lerin tümünde click event'ı yer almadığı için bu örneğimizde click event'ı olmayan bir component üzerinden kendi TapEvent'ımızı oluşturacağız. Tabiki bu component için mouse-down ve mouse-up gibi eventlardan faydalanacağız. İlk örneğimizi geliştirmeye başlayalım. Şimdi Visual Studio / File / New Project / Silverlight for Windows Phone / Windows Phone Application seçerek phone projemizi oluşturalım. Default olarak gelen MainPage.xaml içeriğini aşağıdaki gibi
oluşturalım. Örnek nesne olarak bir button ve bir de border nesnelerini kullanacağız.Button nesnesi kendi içerisinde click event'a sahip durumda fakat border için custom bir sınıf oluşturacağız. Bu sınıfı daha sonra yalnızca border nesnesi ile değil dilediğimiz kontrol'e bir Behavior olarak ekleyebilir olacağız.
Sınıfımızı TapAction olarak isimlendirelim ve base sınıf olarak Behavior jenerik sınıfından türetelim. Jenerik tip olarak tabiki UIElement kullanacağız.

Dikkat etmemiz gereken önemli bir nokta da Behavior base sınıfını kullanabilmek için referans olarak eklememiz gereken System.Windows.Interactivity.dll dir.























C#
public class TapAction : Behavior<UIElement>
{
    public event EventHandler Tap;
    protected bool MouseDown { getset; }
 
    protected override void OnAttached()
    {
        base.OnAttached();
        this.AssociatedObject.MouseLeftButtonDown +=AssociatedObject_MouseLeftButtonDown;
        this.AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
    }
 
    protected override void OnDetaching()
    {
        this.AssociatedObject.MouseLeftButtonDown -= AssociatedObject_MouseLeftButtonDown;
        this.AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
        base.OnDetaching();
    }
 
    private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        MouseDown = true;
    }

    private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (MouseDown)
        {
            OnTap();
        }
        MouseDown = false;
    }
 
    protected virtual void OnTap()
    {
        if (Tap != null)
        {
            Tap(this.AssociatedObject, EventArgs.Empty);
        }
    }
}
Yukarıdaki kod satırlarını inceleyecek olursak base sınıfımızın OnAttached methodunu override ederek mouse-down ve mouse-up event handler'larını ekliyoruz. Tap isimli event'ımız da mouse-down olduğunda tetiklenecektir. TapAction sınıfımızı oluşturduktan sonra MainPage.xaml içerisine nesnelerimizi ve ilişkili 
olacakları behavior tanımlamalarını ekleyelim.

XAML
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Border x:Name="border_1" 
          BorderBrush="#FFF5C013" BorderThickness="10" 
          HorizontalAlignment="Left" VerticalAlignment="Top"
          Margin="39,42,0,0" Height="111" Width="142">
                <i:Interaction.Behaviors>
                   <local:TapAction x:Name="myTapAction" Tap="myTapAction_Tap"/>
                </i:Interaction.Behaviors>
        </Border>
        <Button Name="button_1" 
                    Content="Button" 
                    Height="72" 
                    HorizontalAlignment="Left" 
                    Margin="235,63,0,0"  VerticalAlignment="Top" Width="160" Click="button_1_Click" />
        </Grid>

Yukarıdaki xaml kodlarına dikkat edecek olursak button nesnesinin Click event'ı Border nesnesinin ise kodsal olarak oluşturduğumuz Tap event'ı kullanılacak. TapAction behavior'ı da Expression Blend tarafına geçerek de ekleyebiliriz.






MainPage.cs içerisinde myTapAction_Tap ve button_1_Click event handler içerisine örnek messagebox görüntüleyecek kod satırlarımızı da ekledikten sonra F5 ile uygulamamızı çalıştırarak sonuçlara birlikte göz atabiliriz.

C#
public partial class MainPage : PhoneApplicationPage
{
    public MainPage()
    {
        InitializeComponent();
    }
    private void button_1_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Tap Event Button üzerinden gerçekleşti.");
    }
 
    private void myTapAction_Tap(object sender, EventArgs e)
    {
        MessageBox.Show("Tap Event Border üzerinden gerçekleşti.");
    }
}








Double-Tap Gesture Örneği
Yukarıda kullandığımız örneğe benzer şekilde DoubleTapAction sınıfını da TapAction sınıfından miras alarak kolaylıkla yazabiliriz. Double-Tap Action yazarken 2 Tap arasında geçen kısa zaman dilimi (1 sn) kontrol edilerek geliştirilmelidir. 2 tap arasındaki sürenin 1 sn olduğunu kontrol edebilmek için öncelikle 1. Tap Action gerçekleştiğinde ne zaman gerçekleştiğini bir değişken de tutarak eğer yeni bir Tap Action gerçekleşir ise değişken de tutuğumuz zaman ile karşılaştırıp 1sn'den küçük ise DoubleTap event'ı oluşturabiliriz.

C#
public class DoubleTapAction : TapAction
{
    public event EventHandler DoubleTapEvent;
    protected DateTime? FirstTapTimeValue { getset; }
    public int DoubleTapTimeoutInMilliseconds
    {
        get { return (int)GetValue(DoubleTapTimeoutInMillisecondsProperty); }
        set { SetValue(DoubleTapTimeoutInMillisecondsProperty, value); }
    }
    public static readonly DependencyProperty
    DoubleTapTimeoutInMillisecondsProperty = DependencyProperty.Register("DoubleTapTimeoutInMilliseconds"typeof(int),typeof(DoubleTapAction),new PropertyMetadata(1000));
    protected override void OnTap()
    {
        base.OnTap();
        if (FirstTapTimeValue.HasValue && FirstTapTimeValue.Value.AddMilliseconds(DoubleTapTimeoutInMilliseconds) > DateTime.Now)
        {
            OnDoubleTap();
            FirstTapTimeValue = null;
        }
        else
        {
            FirstTapTimeValue = DateTime.Now;
        }
    }
    protected virtual void OnDoubleTap()
    {
        if (DoubleTapEvent != null)
        {
            DoubleTapEvent(this.AssociatedObject, EventArgs.Empty);
        }
    }
}
Pan, Flick, TouchAndHold Gestures Örnekleri (Silverlight for Windows Phone Toolkit ile)


Şimdiye kadar örneklendirdiğimiz Tap ve DoubleTap'den farklı olarak Pan, Flick ve Hold Gesture' ları yakalayabilmek içim daha fazla kod ve sınıf eklemeden Silververlight for Windows Phone Toolkit' den faydalanacağız. Bu Toolkit indirilip kurulduktan sonra Gestures ile ilgili örnek kaynak kodlara da erişilebilir. İlgili Toolkit'i indirmek için http://silverlight.codeplex.com/ adresinden download silverlight on WP7 tıklanarak erişilebilir.

Silverlight on Windows Phone Toolkit kurulumu tamamlandıktan sonra projemize ilgili dll referansını da eklemeyi unutmayalım.







XAML
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"

XML namespace bölümüne yukarıdaki xaml kod satırında olduğu gibi toolkit olarak isimlendirdiğimiz namespace'i ekliyoruz. Toolkit Controls altında bulunan GestureListener isimli sınıfdan faydalanacağız.
Şimdi MainPage.xaml içerisine bir Canvas kontrol ekleyerek Pan, Flick ve Hold event' ları yakalamaya çalışalım.

XAML
<Canvas Background="Aqua"
        Height="124" 
        HorizontalAlignment="Left" 
        Margin="76,256,0,0" 
        Name="canvas1" 
        VerticalAlignment="Top" 
        Width="218">
    <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener DragDelta="GestureListener_DragDelta"
                                 Flick="GestureListener_Flick"
                                 Hold="GestureListener_Hold" 
                                  />
    </toolkit:GestureService.GestureListener>
</Canvas>

C#
private void GestureListener_DragDelta(object sender, DragDeltaGestureEventArgs e)
{
    double horizontalChange = e.HorizontalChange;
    canvas1.Margin = new Thickness(canvas1.Margin.Left + horizontalChange, canvas1.Margin.Top, canvas1.Margin.Right, canvas1.Margin.Bottom);
}
 
private void GestureListener_Hold(object sender, GestureEventArgs e)
{
    resultText.Text = "Hold: Canvas üzerinde bir süre basılı tutuldu.";
}
 
private void GestureListener_Flick(object sender, FlickGestureEventArgs e)
{
    resultText.Text = string.Format("{0} Flick: Angle {1} Velocity {2},{3}",
        e.Direction, Math.Round(e.Angle), e.HorizontalVelocity, e.VerticalVelocity);
}
Uygulamamızı F5 ile çalıştırarak sonucu emulatör üzerinden mouse yardımıyla izleyelim. Öncelikle Hold hareket için, Aqua renk olan Canvas kontrol üzerinde mouse pointer'ı bir süre basıl tutalım, ardından tekrar mouse yardımıyla Flick hareketleri yakalayacağız. Bu iki denemeden sonra DragDelta içindeki kod satırlarının çalışması için Pan hareket ile canvas1 isimli Canvas nesnemizi yatay eksende hareket ettireceğiz.


























Yukarıdaki resimlerde de görüleceği üzere en son yaptığımız Pan hareketle canvas nesnesinin yerini yatayda soldan sağa doğru kaydırdık fakat aynı zamanda Pan hareketinin sonlanması ile birlike Horizantal Flick hareketinde oluştuğunu gözlemleyebiliriz. Buradan şu sonucu çıkarabiliriz: 2 tür Flick hareket vardır.
Bunlardan ilki Pan hareketin sonunda otomatik olarak oluşan Flick, diğeride kendimizin bilinçli olarak oluşturduğu Flick hareketi.

Multi-Touch Gestures Örnekleri

Windows Phone 7 cihazımız var ise Pinch hareket başladığında, hareket halindeyken ve hareket sonlandığında hız, açı ve x,y pozisyonu değerlerini elde etmek oldukça kolay olacaktır. Multi-touch özelliği Windows Phone Emulatör üzerinden de simule etme şansımız var. Simulasyon için öncelikle bilgisayarımızın işletim sisteminin Windows 7 olması gerekiyor. Ekranınız multi-touch özellikte ise ayrıca yeni bir yapılandırmaya gerek kalmadan emulatör üzerinden deneyebilirsiniz. Eğer ekranınız multi-touch özelliğe sahip değilse de
bilgisayarınızın diğer usb girişine de mouse takarak multi-touch simulasyonu gerçekleştirme
şansımız olacak.

Bu simulasyon için öncelikle codeplex.com adresinden Multi-Touch Vista projesini download etmemiz gerekiyor. Sitenin ana sayfasındaki örnek video ile kurulum adımlarını inceleyebilirsiniz.

Multi-Touch Vista http://multitouchvista.codeplex.com/ adresinden ulaşılabilir.















Multi-Touch Vista'yı bilgisayarınıza indirdikten sonra yapılması gerekenleri kısaca sıralamak gerekirse;

1. Command Prompt'u administrator modda açın.
2. İndirilen klasörü açıp işlemcinize göre Driver\32x veya Driver\64x klasörüne gidin.
3. Install Driver komut dosyasını çalıştırın. Güvenlik ile ilgili adımda Install this driver seçeneğini seçiniz.
4. Bilgisayarınızın Aygıt Yöneticisi / İnsan Arabirim Aygıtları / Universal Software HID device'ı görün. Disable ve tekrar Enable yapın.
5. Start menüden "kalem ve dokunma" (pen and touch) olarak arayın. Bu uygulamayı
çalıştırın. Gelen pencerenin "Dokun" (Touch) sekmesine geçerek "Dokunma işaretçisini göster" checkbox seçeneğini seçiniz ve Tamam diyerek bu pencereyi kapatalım.
6. İndirilen klasörü tekrar açıp Multitouch.Service.Console.exe'yi çift tıklayarak çalışır durumda bırakalım.
7. Aynı klasörde bulunan Multitouch.Driver.Console.exe'yi çift tıklayarak çalışır durumda bırakalım. USB'den takdığımız mouse kadar kırmızı nokta göreceğiz.
8. Son olarak Multitouch.Configuration.WPF.exe'yi de çalıştırarak "configurasyon" butonunu seçiniz. Default mouse işaretçisini de burada kaldırıyoruz. Artık multi-touch simulasyonumuz hazır durumda. :)




Kalem ve Dokunma uygulaması içerisinden "Dokun" sekmesine geçin.








































Dokunma işaretçisi seçildikten sonra "Tamam" butonu ile çıkalım. Multi-Touch Vista console uygulamalarının da aşağıdaki gibi açık durumda olması gerekecektir.






Bilgisayarımızda Multi-Touch özelliği simule ettikten sonra tekrar Windows Phone 7 projemize geri dönerek kaldığımız yerden devam edelim. Multi-Touch hareketleri 2 adet usb mouse kullanarak Emulatör üzerinden yakalayacağız. Öncelikle MainPage.xaml'da bulunan Canvas nesnemizi aşağıdaki gibi yeniden düzenleyelim.

XAML
<Canvas Background="Aqua"
        Height="124" 
        HorizontalAlignment="Left" 
        Margin="76,256,0,0" 
        Name="canvas1" 
        VerticalAlignment="Top" 
        Width="218">
    <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener DragDelta="GestureListener_DragDelta"
                                 Flick="GestureListener_Flick"
                                 Hold="GestureListener_Hold" 
                                 PinchStarted="GestureListener_PinchStarted"
                                 PinchDelta="GestureListener_PinchDelta"
                                 PinchCompleted="GestureListener_PinchCompleted"/>
    </toolkit:GestureService.GestureListener>
    <Canvas.RenderTransform>
        <CompositeTransform x:Name="myTransform"/>
                </Canvas.RenderTransform>
</Canvas>

Multi-Touch hareketleri PinchStarted, PinchDelta ve PinchComplated event handler ile elde edeceğiz.

C#
private double initialAngle;
private double initialScale;
 
private void GestureListener_PinchStarted(object sender, PinchStartedGestureEventArgs e)
{
    canvas1.Background = new SolidColorBrush(Colors.Green);
    initialAngle = myTransform.Rotation;
    initialScale = myTransform.ScaleX;
}
private void GestureListener_PinchDelta(object sender, PinchGestureEventArgs e)
{
    myTransform.Rotation = initialAngle + e.TotalAngleDelta;
    myTransform.ScaleX = myTransform.ScaleY = initialScale * e.DistanceRatio;
}
private void GestureListener_PinchCompleted(object sender, PinchGestureEventArgs e)
{
    canvas1.Background = new SolidColorBrush(Colors.Blue);
}
Tekrar F5 ile Emulatör üzerinden projemizi çalıştırarak multi-touch özelliği Pinch hareket ile elde etmeye çalışalım.


































Dokunmatik giriş türlerini kullanmak, cihaza özgü donanımsal özelliklerden faydalanmak hem uygulamalarımızı daha güçlü ve farklı bir hale getirecek hem de son kullanıcılar tarafından daha çok tercih edilir yapacaktır. Kendi özel uygulamalarımız dışında da Windows Phone 7 ile internet explorer üzerinden gezindiğimizde de otomatik olarak touch özelliklerin aktif durumda olduğunu gözlemleyebiliriz.
Bu makalemizde, kullanımı son derece basit olan GestureListener mekanizmasını ve Behavior sınıfından türeyen örnek TapAction ve DoubleTapAction sınıfları yardımıyla dokunmaları yakaladık. Windows Phone için ayrıca XNA Touch Panel ve Silverlight'ın kendi manipulasyonlarıyla da Touch girişler kullanılmaktadır. Dilerim faydalı bir makale olmuştur.. Bir sonraki makalemizde görüşmek üzere.
Kolay gelsin.

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.touch.gesturetype.aspx

http://msdn.microsoft.com/en-us/library/gg490775.aspx
http://multitouchvista.codeplex.com/
http://silverlight.codeplex.com/


Gökhan Manduz
gokhanmanduz.blogspot.com

gokhanmanduz@hotmail.com
gmanduz@gmail.com

19 Aralık 2010

Windows Phone 7 Push Notification Types

Bu makalemizde Windows Phone 7 işletim sistemli telefonlarda kullanılan Push Notification (Türkçede 'bildirim itme' ya da 'dürtme' anlamında) konusunu 3 farklı bildirim tipi (notification types) ile ele alacağız.
Bu bildirim tiplerini sırasıyla;

1. Tile Notification
2. Toast Notification
3. Raw Notification


olarak 3 farklı gruba ayırarak inceleyelim. Öncelikle, kısaca ve ekran görüntüleri ile bu bildirim tiplerinin ne olduğunu anlamaya çalışalım.

1. Tile Notification


Windows Phone 7 açılış ekranında gösterimi yapılacak olan bildirim tipidir. Görsel olarak dikkat çekici konumdadır ve uygulamaları çalıştırdığımız ana ekranda yer alacaktır. Windows Phone 7 içerisinde her uygulama için ana ekranda bir 'Tile' (giriş ekranında yer alan ve application quick launchers olarak adlandırılan ekran ) bulunabilir.













Bir Tile Backgraund Image, Count ve Title'dan oluşur. Backgraund Image: Arka plan resmi için local veya bir uzak sunucuda bulunan imaj dosyası kullanılabilir. Tabiiki burada daha fazla performans istiyorsak local dosyada olması tercih nedeni olacaktır. Count: Integer sayıdır. Bildirim sayısını göstermek için kullanacağız. Title: Alt kısımda yer alan ve yalnızca bir satırlık string bilgi gösterilebilecek alandır. Bu sebepten dolayı tile genişliğini aşmayacak uzunlukta string bildirimler gönderilmesi gerekecektir.



2. Toast Notification (Tost :)

Bir bildirim geldiğinde ekranın üst kısmında belirecektir. Aşağıdaki resimde de görüleceği gibi turuncu arka plan renginde bir title ve bir de sub-title'dan oluşur. Title bold font, sub-title ise normal font olacaktır.







3. Raw Notification


Eğer yukarıda belirttiğimiz Tile ve Toast bildirimde bulunmak yerine direk olarak uygulamıza bildirimde bulunmak istiyorsak raw notification kullanacağız. Eğer gönderim sırasında uygulamamız kapalı ise Microsoft Push Notification servisinde bu bildirim iptal edilecektir ve cihaza iletilmeyecektir.

( Önemli Not : Tüm bu bildirimlerle ilgili UI tasarlamadan önce Microsoft' un belirttiği UI Guidelines'ı bir sıkıntı yaşamamak için (Phone Marketplace için) incelemekte fayda var. İlgili Guidelines'ı buradan indirebilirsiniz. )

Bildirim türlerinden kısaca bahsettikten sonra şimdi de bir örnek ile notification türlerini daha yakından
incelemeye çalışalım. Örneğimiz için 2 farklı proje oluşturacağız. Öncelikle bir WPF projesi ile Notification Sender tarafını daha sonrada Windows Phone projesi ile bildirimlerin cihaza nasıl ulaştığını ve cihazda nasıl gösterildiğinden bahsedeceğiz.

Notification Sender Side (WPF Application)


Visual Studio 2010 / File / New / Project / Visual C# / Windows / WPF Application seçeneği ile yeni bir proje oluşturarak notification göndereceğimiz tarafı oluşturmaya başlayalım. MainWindows ekranımızı aşağıdaki gibi oluşturalım.

MainWindows XAML
<Window x:Class="SenderApplication.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="Sender Application" Height="433" Width="563">
  <Grid>
      <Border BorderBrush="#FF8AC0C0" BorderThickness="1" Height="43"
              HorizontalAlignment="Left" Margin="13,10,0,0" Name="border1" VerticalAlignment="Top" Width="507">
          <TextBlock Height="21" Name="textBlock1" Text="Windows Phone 7 URI" Width="133" HorizontalAlignment="Left" Margin="5" />
      </Border>
      <TextBox Height="23" HorizontalAlignment="Left" Margin="152,21,0,0" Name="txtUri" VerticalAlignment="Top" Width="357" />
      <GroupBox Header="Tile Notification" Height="100" HorizontalAlignment="Left"
                Margin="13,59,0,0" Name="groupBox1" VerticalAlignment="Top" Width="513">
          <Grid>
              <TextBox Height="23" HorizontalAlignment="Left" Margin="133,6,0,0" 
                     Name="txtTileTitle" VerticalAlignment="Top" Width="142" />
              <TextBlock Height="21" HorizontalAlignment="Left" Margin="10,8,0,48" 
                         Name="txt" Text="Title" Width="91" />
              <TextBox Height="23" HorizontalAlignment="Left" Margin="133,35,0,0" 
                       Name="txtTileBackgraundimage" VerticalAlignment="Top" Width="252" />
              <TextBlock Height="21" HorizontalAlignment="Left" Margin="10,35,0,21" 
                         Name="textBlock3" Text="Basckbraund Image" Width="109" />
              <TextBox Height="23" HorizontalAlignment="Left" Margin="331,5,0,0" 
                       Name="txtCount" VerticalAlignment="Top" Width="54" />
              <TextBlock Height="21" HorizontalAlignment="Left" Margin="281,7,0,49" 
                         Name="textBlock4" Text="Count" Width="44" />
              <Button Content="Gönder" Height="23" HorizontalAlignment="Left" Margin="415,48,0,0" 
                      Name="btnSendTile" VerticalAlignment="Top" Width="75" Click="btnSendTile_Click" />
          </Grid>
      </GroupBox>
      <GroupBox Header="Toast Notification" Height="100" HorizontalAlignment="Left" Margin="13,165,0,0" 
                Name="groupBox2" VerticalAlignment="Top" Width="513">
          <Grid>
              <TextBox Height="23" HorizontalAlignment="Left" Margin="133,10,0,0" 
                       Name="txtToastValue1" VerticalAlignment="Top" Width="252" />
              <TextBlock Height="21" HorizontalAlignment="Left" Margin="10,10,0,46" 
                         Name="textBlock2" Text="String Value" Width="124" />
              <TextBox Height="23" HorizontalAlignment="Left" Margin="133,39,0,0" 
                       Name="txtToastValue2" VerticalAlignment="Top" Width="252" />
              <TextBlock Height="21" HorizontalAlignment="Left" Margin="10,39,0,17" 
                         Name="textBlock5" Text="Sub-String Value" Width="124" />
              <Button Content="Gönder" Height="23" HorizontalAlignment="Left" Margin="415,48,0,0" 
                      Name="btnSendToast" VerticalAlignment="Top" Width="75" Click="btnSendToast_Click" />
          </Grid>
      </GroupBox>
      <GroupBox Header="Raw Notification" Height="100" HorizontalAlignment="Left" Margin="13,271,0,0"
                Name="groupBox3" VerticalAlignment="Top" Width="513">
          <Grid>
              <TextBox Height="23" HorizontalAlignment="Left" Margin="133,10,0,0" 
                       Name="txtRawValue" VerticalAlignment="Top" Width="252" />
              <TextBlock Height="21" HorizontalAlignment="Left" Margin="10,10,0,46" 
                         Name="textBlock6" Text="String Value" Width="124" />
              <Button Content="Gönder" Height="23" HorizontalAlignment="Left" Margin="415,48,0,0" 
                      Name="btnSendRaw" VerticalAlignment="Top" Width="75" Click="btnSendRaw_Click" />
          </Grid>
      </GroupBox>
  </Grid>
</Window>






























UI hazırladıktan sonra Tile, Toast ve Raw buttonların click eventları altına ilgi notification gönderim kodlarını ekleyelim. Tile notification özelliklerine uygun olacak şekilde bir title, count ve arkaplanda çıkacak imaj adresini parametre olarak olan methodumuzu hazırlayalım. Imaj olarak ApplicationIcon.png dosyasını kullanabiliriz. "ApplicationIcon.png" dışında client windows phone uygulamamız tarafına content olarak eklenmiş farklı bir imaj dosyası da kullanabilirdik. (Windows Phone projesine eklenecek imaj dosyasının build action özelliğinin content olmasına dikkat edelim.)

Tile Notification Sender Method ve Button Click Event;

private void sendTile(Uri phoneUri, string title, int count, string backgroundImage)
{
    string xmlMsg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                    "<wp:Notification xmlns:wp=\"WPNotification\">" +
                    "<wp:Tile>" +
                    "<wp:BackgroundImage>" + backgroundImage + "</wp:BackgroundImage>" +
                    "<wp:Count>" + count.ToString() + "</wp:Count>" +
                    "<wp:Title>" + title + "</wp:Title>" +
                    "</wp:Tile>" +
                    "</wp:Notification>";
    byte[] data = new UTF8Encoding().GetBytes(xmlMsg);
 
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(phoneUri);
    request.Method = WebRequestMethods.Http.Post;
    request.ContentLength = data.Length;
    request.Headers["X-MessageID"] = Guid.NewGuid().ToString();
 
    request.Headers["X-WindowsPhone-Target"] = "token";
    request.ContentType = "text/xml";
    request.Headers["X-NotificationClass"] = "1";

    Stream requestStream = request.GetRequestStream();
    requestStream.Write(data, 0, data.Length);
    requestStream.Close();
    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
}
private void btnSendTile_Click(object sender, RoutedEventArgs e)
{
    int count = Convert.ToInt32(txtCount.Text);
    sendTile(new Uri(txtUri.Text), txtTileTitle.Text, count ,txtTileBackgraundimage.Text);
    count++;
    txtCount.Text = count.ToString();
}
Yukarıdaki sendTile methoduna parametre olarak vereceğimiz phoneUri değerinin de önceden WindowsPhone tarafından verilmiş olması gerekiyor. uri adresinin nasıl elde edileceğini Windows Phone Application tarafında göreceğiz. Şimdi de Toast notification gönderecek olan methodumuzu ve click event'ımızı ekleyelim.

private void sendToast(Uri phoneUri, string str, string subStr)
{
    string msg =
        "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<wp:Notification xmlns:wp=\"WPNotification\">" +
        "<wp:Toast>" +
        "<wp:Text1>" + str + "</wp:Text1>" +
        "<wp:Text2>" + subStr + "</wp:Text2>" +
        "</wp:Toast>" +
        "</wp:Notification>";
    byte[] data = new UTF8Encoding().GetBytes(msg);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(phoneUri);
    request.Method = WebRequestMethods.Http.Post;
    request.ContentLength = data.Length;
    request.Headers["X-MessageID"] = Guid.NewGuid().ToString();
    request.Headers["X-WindowsPhone-Target"] = "toast";
    request.ContentType = "text/xml";
    request.Headers["X-NotificationClass"] = "2";
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(data, 0, data.Length);
    requestStream.Close();
    HttpWebResponse response = request.GetResponse() as HttpWebResponse;
}
private void btnSendToast_Click(object sender, RoutedEventArgs e)
{
    sendToast(new Uri(txtUri.Text), txtToastValue1.Text, txtToastValue2.Text);
}
Yukarıdaki kod satırlarında görüleceği gibi Toast gönderime uygun olacak şekilde sendToast parametre değerine bir string ve sub-string değer gönderiyoruz. Tile gönderimde olduğu gibi burada da uri adresini windows phone tarafında elde ediyor olacağız.

HttpWebResponse response = request.GetResponse() as HttpWebResponse

HttpWebResponse dönen kod satırında ise eğer dilerseniz gönderim sonrası durum bilgilerini ekrana yazdırabilirsiniz. Örneğin response.Header["X-DeviceConnectionStatus"] ile cihaz bağlantı durum bilgisi elde edilebilir. Raw Notification gönderimi için de aşağıdaki kod satırlarını ekleyelim;

private void sendRaw(Uri phoneUri, string str)
{
    MemoryStream stream = new MemoryStream();
    BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8);
    writer.Write(str);
    byte[] data = stream.ToArray();
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(phoneUri);
    request.Method = WebRequestMethods.Http.Post;
    request.ContentLength = data.Length;
    request.Headers["X-MessageID"] = Guid.NewGuid().ToString();
    request.Headers["X-NotificationClass"] = "3";
    Stream requestStream = request.GetRequestStream();
    requestStream.Write(data, 0, data.Length);
    requestStream.Close();
}
private void btnSendRaw_Click(object sender, RoutedEventArgs e)
{
    sendRaw(new Uri(txtUri.Text), txtRawValue.Text);
}
Raw notification gönderiminde de benzer şekilde string değerimiz ile windows phone kanal adresimizi parametre olarak gönderiyoruz. Şimdi de Windows Phone tarafında yeni bir bağlantı kanalı oluşturarak sender
uygulamıza verelim. Hemen ardından bildirimlerin nasıl gözükeceğine göz atalım.

Windows Phone Application Side


Öncelikle private kanal değişkenimizi, kanala vereceğimiz adı ve constractorümüz içerisinde Loaded event ekleyerek başlayalım. HttpNotificationChannel using Microsoft.Phone.Notification namespace altında bulunmaktadır. bu namespace default olarak projemize eklenen Microsoft.Phone.dll altında bulunmaktadır.


private HttpNotificationChannel httpChannel;
const string channelName = "MyPushChannel";
const string serviceName = "MyPushServis";
public MainPage()
 {
     InitializeComponent();
     this.Loaded += MainPage_Loaded;
 }

MainPage Loaded event handler altında çalışacak kod satırlarımızı ekleyelim. Tanımladığımız isimle yeni bir notification kanalı oluşturulmasını sağlayalım. Eğer bu isimde bir kanal tanımlı ise hazır durumda olan kanalımızı debug modda iken output penceremize yazdıracağız(Debug.WriteLine ile). Bu event handler içerisinde, yeni bir kanal oluşturma ve mevcut kanalın kontrol edilmesi Microsoft Push Notification Servisi tarafından
verilmektedir. Bu servisin nasıl çalıştığı konusunda bilgi almak isteyenler buradan ulaşabilirler.

private  void MainPage_Loaded(object sender, RoutedEventArgs e)
{
    httpChannel = HttpNotificationChannel.Find(channelName);
    if (null == httpChannel)
    {
        Debug.WriteLine("Yeni kanal oluşturuldu.");
 
        httpChannel = new HttpNotificationChannel(channelName, serviceName);
        httpChannel.ChannelUriUpdated += 
            new EventHandler<NotificationChannelUriEventArgs>(httpChannel_ChannelUriUpdated);
        httpChannel.Open();
    }
    else
    {
        Debug.WriteLine("Var olan kanal : " +
                        httpChannel.ChannelUri.ToString());
    }
 
    // Raw event handler ekleniyor
    httpChannel.HttpNotificationReceived += httpChannel_HttpNotificationReceived;
           
    // Toast event handler ekleniyor
    httpChannel.ShellToastNotificationReceived += httpChannel_ShellToastNotificationReceived;
 
    // Hata için event handler
    httpChannel.ErrorOccurred += httpChannel_ErrorOccurred;
}
ChannelUriUpdated event handler Microsoft Push Notification servisinden gelen yanıtları yakalayacaktır;

private void httpChannel_ChannelUriUpdated(object sender, NotificationChannelUriEventArgs e)
{
    Debug.WriteLine("Güncellenen kanal:" + httpChannel.ChannelUri.ToString());
    httpChannel.BindToShellToast();
    httpChannel.BindToShellTile();
}
Şimdide sırasıyla Raw ve Toast bildirimleri yakalayan event handler kod satırlarımızı ekleyelim. Gelen bildirimler asenkron olarak çalışacağı için Windows Phone ekranına koyacağımız bir textblock'da görüntüleyebilmek için textblock'un Dispatcher.BeginInvoke methodundan faydalanacağız.


private void httpChannel_HttpNotificationReceived(object sender, HttpNotificationEventArgs e)
{
    BinaryReader reader = new BinaryReader(e.Notification.Body, System.Text.Encoding.UTF8);
    string ntext = reader.ReadString();
    txtMessageBox.Dispatcher.BeginInvoke(new Action(delegate() {
        txtMessageBox.Text += "Raw Notification" + Environment.NewLine;
        txtMessageBox.Text += ntext + Environment.NewLine;
     } ) );
}
 
private void httpChannel_ShellToastNotificationReceived(object sender, NotificationEventArgs e)
{
    txtMessageBox.Dispatcher.BeginInvoke(new Action(delegate() {
        txtMessageBox.Text += "Toast Notification:" + Environment.NewLine;
    }));
    if (e.Collection != null)
    {
        Dictionary<stringstring> collection = (Dictionary<stringstring>)e.Collection;
        foreach (string elementName in collection.Keys)
        {
            txtMessageBox.Dispatcher.BeginInvoke(new Action(delegate() {
              txtMessageBox.Text += elementName + " - " + collection[elementName] + Environment.NewLine;
            }));
        }
    }
}
ErrorOccured event handler da bir hata oluşması durumunda, hatayı yakalayacak ve kanalı kapatıp açarak tekrar bağlantının kurulmasını deneyecektir.

private void httpChannel_ErrorOccurred(object sender, NotificationChannelErrorEventArgs e)
{
    Debug.WriteLine("Hata oluştu: " + e.Message);
    Debug.WriteLine("Kanal tekrar açılacak...");
    httpChannel.Close();
    httpChannel.Open();
}
Windows Phone kod satırlarımızı da eklediğimize göre, şimdi debug modda F5 ile projemizi çalıştırıp, olup biteceklere göz atalım. Windows Phone 7 Emulatör seçili durumda ve debug modda uygulamamızı çalıştıralım.  MainWindows Loaded event handler altına eklediğimiz Debug.WriteLine kod satırları ile gönderdiğimiz bilgilere output penceresinden bakıyoruz.















Output penceresinden Microsoft Push Notification Servisinin gönderdiği kanal adresini kopyalayarak sender programımızı çalıştırıp ilgili URI alanına, kanal adresini kopyalayalım.






























Raw Notification string alanına "Merhaba Dünya :)" yazarak Gönder butonu ile bildirimimizi gönderelim. Windows Phone uygulamamız açık ve ilgili event handler eklenmiş olduğu için gönderilen bildirim aşağıdaki ekran görüntüsünde olduğu gibi ekrana yansıyacaktır.








































Raw notification ile gönderdiğimiz bildirim mesajı yalnızca uygulama ekranı açık olduğunda iletilecektir. Toast ve Tile notification'lar için uygulama ekranının açık olmasına gerek yoktur. İlgili bildirim Toast ise ekranın üst
kısmında belirecek, Tile ise quick launch ekranında uygulama tile alanında yazdırılacaktır.



























Aşağıdaki ekranda Windows Phone Toast notification görüntüsü yer alıyor. Phone uygulamamızın icon özelliğini project properties'den "warning.png" olarak değiştirdiğimiz için bir ünlem işareti ile toast bildirimi almış olduk ve ilgili bildirim mesajıyla "Ekmek Almayı unutma :)" mesajını göndermiş olduk.








































Kolay gelsin.
Faydalı Linkler:
http://msdn.microsoft.com/en-us/library/ff941124(v=vs.92).aspx
http://msdn.microsoft.com/en-us/wp7trainingcourse_usingpushnotificationslab_topic1
http://create.msdn.com/en-US/education/catalog/sample/push_notifications

Gökhan Manduz
http://gokhanmanduz.blogspot.com/
gmanduz@gmail.com