Error | Engin Polat\'ın Windows 8 , Windows Phone 8 ve C# içerikli programcılık sitesi

Arşiv

Etiketlenen yazılar error

Windows Phone 8 uygulama arkaplan görselini Bing servislerinden almak

05 February 2014 1 yorum

Windows Phone 8 için geliştirdiğiniz uygulamanın veya Button, Image gibi nesnelerin arkaplan görselinin periyodik olarak değişmesini isteyebilirsiniz. Böylece uygulamanızın içerisinde sürekli olarak güncellenen bir bölüm oluşturabilirsiniz.

Microsoft‘un geliştirdiği arama motoru olan Bing, ana arama ekranının arkaplan görselini periyodik olarak arkaplan görselini değiştirir.

Öncelikle Bing‘in arkaplan görselini nasıl değiştirdiğini anlamamız lazım. Eğer Bing tarayıcınızda açıldıktan sonra yaptığı isteklere bakacak olursanız, http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1 adresine bir çağrı yaptığını görebilirsiniz.

Bu isteğin parametreleri;

format, bu parametre ile dönüş cevabının xml formatında olması sağlanıyor
idx, bu parametre ile Bing’in arkaplan görsellerinden kaçıncı sıradakinin alınacağı belirleniyor
n, bu parametre ile kaç görselin bilgisinin alınacağı belirleniyor

http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1 adresine yapacağımız istek ile Bing‘in ilk sıradaki arkaplan görsellerinin bilgilerini xml formatında elde edeceğiz.

Öncelikle MainPage.xaml dosyasını aşağıdaki gibi güncelleyelim;

<phone:PhoneApplicationPage
	x:Class="BingBackground.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
	xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	FontFamily="{StaticResource PhoneFontFamilyNormal}"
	FontSize="{StaticResource PhoneFontSizeNormal}"
	Foreground="{StaticResource PhoneForegroundBrush}"
	SupportedOrientations="Portrait" Orientation="Portrait"
	shell:SystemTray.IsVisible="True">

	<StackPanel>
		<StackPanel.Background>
			<ImageBrush x:Name="imgBackground"></ImageBrush>
		</StackPanel.Background>
	</StackPanel>

</phone:PhoneApplicationPage>

Böylece StackPanel nesnesinin arkaplanını imgBackground isimli ImageBrush nesnesi ile güncelleyebileceğiz.

MainPage.xaml.cs dosyasında yeralan MainPage class’ının constructor‘ında LoadBackgroundImage() method’unu çağıralım. LoadBackgroundImage() method’unda WebClient sınıfından yeni bir örnek oluşturup http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1 adresine istek yapacağız;

private async void LoadBackgroundImage()
{
	WebClient client = new WebClient();

	client.DownloadStringCompleted += (sender, e) =>
	{
		if (e.Error == null && !string.IsNullOrEmpty(e.Result))
		{
			var doc = XDocument.Parse(e.Result);

			var url = (from node in doc.Descendants("url") select node.Value).FirstOrDefault();

			var uri = new Uri("http://www.bing.com" + url);

			client.OpenReadCompleted += (s, args) =>
			{
				var image = new BitmapImage();
				image.SetSource(args.Result);

				imgBackground.ImageSource = image;
			};
			client.OpenReadAsync(uri);
		}
	};

	client.DownloadStringAsync(new Uri("http://www.bing.com/HPImageArchive.aspx?format=xml&idx=0&n=1"));
}

DownloadStringAsync() method’unu kullanarak yaptığımız isteğin cevabını DownloadStringCompleted event’i ile alabiliyoruz. string tipindeki cevabın boş veya hatalı olmadığını kontrol ettikten sonra XDocument sınıfının static Parse() method’unu kullanarak parse ediyoruz.

url isimli element‘in içinde yeralan arkaplan görseli adresinin başına http://www.bing.com bilgisini ekliyoruz, böylece Bing‘in arkaplan görselinin adresini tam olarak elde ediyoruz.

Aynı WebClient değişkenini kullanarak tam adresini elde ettiğimiz görsel dosyasına ulaşmak için OpenReadAsync() method’unu çağırıyoruz ve cevabı OpenReadCompleted event’i ile elde ediyoruz.

OpenReadCompleted event’i içerisinde elde ettiğimiz Stream ile yeni bir BitmapImage nesnesini dolduruyoruz ve MainPage.xaml içerisinde tanımladığımız imgBackground nesnesinin görseli olarak belirliyoruz.

Böylece Bing‘in arkaplan görseli değiştikçe bizim uygulamamızda ilgili alanın görseli değişecektir.

Windows Phone 8 için Radyo Frekansları uygulaması

19 December 2012 Yorum yapılmamış

Windows Phone 8 için şehir-şehir radyo frekanslarını görebileceğimiz bir uygulama geliştireceğiz.

Bu uygulamanın geliştirilmesi sırasında Pivot, PivotItem, LongListSelector, DataTemplate, WebClient gibi sınıfları kullandığımız kodlar yazacağız.

Öncelikle RadyoListe isimli yeni bir Windows Phone App projesi oluşturalım;

Windows Phone App Project

Proje oluşturduktan sonra gelen Windows Phone Platform versiyon seçim penceresinde Windows Phone OS 8.0 seçeneğinin seçili olduğundan emin olmalıyız;

Windows Phone 8.0 SDK

Uygulama ihtiyaç duyduğu veriyi internetten indireceği için WMAppManifest.xml dosyasında Network erişim izninin istenmiş olması gerekiyor;

<Capabilities>
	<Capability Name="ID_CAP_NETWORKING" />
</Capabilities>

Radyo listesi için json formatında hazırladığım veriyi kendi sunucuma radyolar.json ismi ile yükledim.

Json formatında okuyacağımız bu veriyi işlemek için References içerisine Newtonsoft Json.Net (4.5.11) Nuget paketini eklemeliyiz;

Newtonsoft Json.Net Nuget Package

Models isminde bir dizin ekleyip, içerisinde LiveData, City, Channel, Frequency isimli sınıflar oluşturalım;

LiveData.cs

public class LiveData
{
	public IEnumerable<City> Cities { get; private set; }

	public IEnumerable<Channel> Channels { get; private set; }

	public IEnumerable<Frequency> Frequencies { get; private set; }

	public LiveData()
	{
		this.Cities = new List<City>();
		this.Channels = new List<Channel>();
		this.Frequencies = new List<Frequency>();
	}

	public LiveData(string LiveDataResponse)
	{
		var LiveDataResult = JsonConvert.DeserializeObject<LiveData>(LiveDataResponse);

		this.Cities = LiveDataResult.Cities;
		this.Channels = LiveDataResult.Channels;
		this.Frequencies = LiveDataResult.Frequencies;
	}
}

City.cs

public class City
{
	public int ID { get; set; }

	public string Name { get; set; }
}

Channel.cs

public class Channel
{
	public int ID { get; set; }

	public string Name { get; set; }
}

Frequency.cs

public class Frequency
{
	public int CityID { get; set; }

	public int ChannelID { get; set; }

	public float No { get; set; }
}

Uygulama ilk açıldığında çalıştırılan App (App.xaml.cs) sınıfına aşağıdaki kodları ekleyelim;

public static Action DataLoaded;

public static LiveData ViewModel = null;

public async static void LoadData()
{
	WebClient wc = new WebClient();

	wc.DownloadStringCompleted += (s, e) =>
	{
		if (e.Error == null)
		{
			ViewModel = new LiveData(e.Result);

			if (DataLoaded != null)
			{
				DataLoaded();
			}
		}
	};

	wc.DownloadStringAsync(new Uri("http://www.enginpolat.com/application-data/radyolar.json"));
}

App sınıfının constructor’ında LoadData() method’unu çağıralım;

LoadData();

Kodları inceleyecek olursak;

Sınıf seviyesinde tanımlanan LiveData tipindeki ViewModel değişkeni, LoadData() method’u içerisinde asenkron olarak doldurulur. ViewModel değişkenine değer ataması yapıldıktan sonra DataLoaded action‘ını dinleyen bir method varsa tetiklenir.

Bu sayede uygulamanın açılışı esnasında internetten verinin indirilmesi ve deserialize edilmesi asenkron olarak yapılmış olur.

MainPage.xaml dosyasında ekranda sadece bir Pivot kontrolünün gösterilmesini sağlayalım;

<Grid x:Name="LayoutRoot" Background="Transparent">
	<Grid.RowDefinitions>
		<RowDefinition Height="*"/>
	</Grid.RowDefinitions>
	<phone:Pivot Margin="0,10,10,10" Title="Radyo Listesi" Name="pvtSehirListesi" Grid.RowSpan="1" />
</Grid>

Artık MainPage.xaml.cs dosyasındaki constructor‘a giderek ekranı dolduracak kodları yazabiliriz;

App.DataLoaded = () =>
{
	foreach (City Sehir in App.ViewModel.Cities)
	{
		PivotItem pi = new PivotItem();
		pi.Header = Sehir.Name;

		LongListSelector list = new LongListSelector();
		list.ItemTemplate = Application.Current.Resources["FrequencyListItemTemplate"] as DataTemplate;
		list.ItemsSource = (from Frekans in App.ViewModel.Frequencies
			join Kanal in App.ViewModel.Channels on Frekans.ChannelID equals Kanal.ID
			where Frekans.CityID == Sehir.ID
			select new { ChannelName = Kanal.Name, Frequency = Frekans.No.ToString("00.0") }).ToList();

		pi.Content = list;

		pvtSehirListesi.Items.Add(pi);
	}
};

Böylece App sınıfında, ViewModel değişkenine değer yükledikten sonra tetiklediğimiz Action içerisinde bir foreach döngüsü çağırmış oluyoruz.

Döngü içerisinde ilk önce yeni bir PivotItem tipinde değişken oluşturuyoruz ve Header özelliğine döngü değişkeninden elde ettiğimiz şehir ismi bilgisini atıyoruz.

PivotItem tipindeki değişkenin Content özelliğine, LongListSelector tipinde yeni bir değişken atıyoruz.

LongListSelector tipindeki değişkenin ItemsSource özelliğine App.ViewModel değişkenindeki değerlerden LINQ Expression ile oluşturduğumuz listeyi atıyoruz.

Aynı şekilde LongListSelector tipindeki değişkenin ItemTemplate özelliğine

Application.Current.Resources["FrequencyListItemTemplate"] as DataTemplate;

değerini atıyoruz.

Son olarak, App.xaml dosyasına FrequencyListItemTemplate ismindeki Resource‘u ekliyoruz;

<Application.Resources>
	<DataTemplate x:Name="FrequencyListItemTemplate">
		<StackPanel Margin="0,0,0,17">
			<TextBlock Text="{Binding ChannelName}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
			<TextBlock Text="{Binding Frequency}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
		</StackPanel>
	</DataTemplate>
</Application.Resources>

Uygulamayı çalıştırdığımızda aşağıdaki ekran görüntüsünü görüyor olmamız lazım;

Radyo Liste Windows Phone 8 Application

Projenin kodlarını buradan indirebilirsiniz.