Windows Phone (10)


Adding speech recognition to your WP8 app

To add speech recognition to our app we will be using the newly released version of the Windows Phone toolkit (release June 2013) – which adds a nice new control called SpeechTextBox (that does exactly what you think). You can get the latest build using NuGet or you can download the source from CodePlex.

Once you’ve referenced the toolkit in you project all you are left to do is add the control:

<toolkit:SpeechTextBox SpeechRecognized="SpeechTextBox_SpeechRecognized" />

Handling the SpeechRecognized event is not necessary. I’ve left it there just to point out that you can choose what you want to do with the speech recognition result. The event comes with a SpeechRecognizedEventArgs parameter which allows you to check the level of confidence for the recognized phrase and also get details about the phrase semantics.




Periodically update your live tiles using ScheduledTaskAgent

I’ve covered in a previous post how to create wide tiles for your Windows Phone 7 application. Now it’s time to bring them to life. The easiest way to do so is by using a ScheduledTaskAgent. To create one go ahead and add a new project to your solution and from the project templates list choose ‘Windows Phone Scheduled Task Agent’.

Before we go any further – go ahead and add this new (task agent) project as a reference in the main application project.

This will create for you a class called ‘ScheduledAgent’ which inherits ‘ScheduledTaskAgent’. You can leave the constructor of the class and the exception handler as they are. The method that interests us is ‘OnInvoke’. This is the method that will be called for us periodically for as long as the agent is running.

This is the method in which we will update our live tile. Let’s say we update our tile from a RSS feed. So the first thing we need to do is download our feed.

protected override void OnInvoke(ScheduledTask task)
{
    WebClient client = new WebClient();
    client.DownloadStringCompleted += (s, e) =&gt;
        {
            DownloadStringCompleted(s, e);
            NotifyComplete();
        };
    client.DownloadStringAsync(new Uri(&quot;http://blogs.windows.com/windows_phone/b/windowsphone/rss.aspx&quot;));
}

Once downloaded, deserialize it, take the first (latest) item and use the title and image to update your live tile.

private void DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
    if (e.Error == null)
    {
        StringReader stringReader = new StringReader(e.Result);
        XmlReader xmlReader = XmlReader.Create(stringReader);
        SyndicationFeed feed = SyndicationFeed.Load(xmlReader);

        var latestArticle = feed.Items.FirstOrDefault();
        var tile = ShellTile.ActiveTiles.FirstOrDefault();
        if (tile != null)
        {
            var tileData = new FlipTileData();
            tileData.Title = &quot;Windows Phone Blog&quot;;

            var content = latestArticle.Title.Text + &quot; - &quot; + latestArticle.Summary.Text;
            var image = latestArticle.Links.FirstOrDefault(l =&gt; l.MediaType != null &amp;&amp; l.MediaType.Contains(&quot;image&quot;)).Uri;

            tileData.BackContent = content;
            tileData.BackgroundImage = image;

            tileData.WideBackContent = content;
            tileData.WideBackgroundImage = image;
            tile.Update(tileData);
        }
    }
}

Pay attention to where I call NotifyComplete()! This method releases all the resources used by the agent. It is important to call this method because otherwise the task will never end and thus will never start again. It is also very important to call it when everything is done – in this particular case in the DownloadStringCompleted event, after updating the live tiles.

This leaves us with only one thing left to do: registering the scheduled task. We will do this in the Application_Launching event (found in App.xaml.cs).

private void Application_Launching(object sender, LaunchingEventArgs e)
{
    var taskName = &quot;WindowsPhoneBlogSTA&quot;;
    PeriodicTask periodicTask = ScheduledActionService.Find(taskName) as PeriodicTask;
    if (periodicTask != null)
        ScheduledActionService.Remove(taskName);

    periodicTask = new PeriodicTask(taskName) { Description = &quot;Periodic task to update the tile of &lt;your app&gt;.&quot; };
    try
    {
        ScheduledActionService.Add(periodicTask);
        #if DEBUG
            ScheduledActionService.LaunchForTest(taskName, TimeSpan.FromSeconds(30));
        #endif
    }
    catch (InvalidOperationException) { }
}



Creating wide tiles for your Windows Phone 7 app

I’ve recently come across an article in the Nokia Developer Wiki about creating live tiles (including wide tile) for both Windows Phone 7 and Windows Phone 8 by writing a single piece of code that works in both versions of the OS.

To do this you will need to use the MangoPollo library which you can easily get from NuGet. The library uses reflection to create your live tiles depending on the OS version the app is running in. Creating your tiles is easy:

var tile = ShellTile.ActiveTiles.FirstOrDefault();
if (tile != null)
{
    var tileData = new FlipTileData();
    tileData.Title = "Start Debugging";

    tileData.BackContent = "switch to windows phone, we've got candy";
    tileData.BackgroundImage = new Uri("Assets/tileBackground.png", UriKind.Relative);
    tileData.BackBackgroundImage = new Uri("Assets/tileBackBackground.png", UriKind.Relative);

    tileData.WideBackContent = "switch to windows phone, we've got candy";
    tileData.WideBackgroundImage = new Uri("Assets/wideTileBackground.png", UriKind.Relative);
    tileData.WideBackBackgroundImage = new Uri("Assets/wideTileBackBackground.png", UriKind.Relative);

    tile.Update(tileData);
}

That’s all you need to do. Both the normal and wide live tiles should now be available when resizing the tile of your app. Now all that’s left for you to do is to update it.

Also, one thing that wasn’t so obvious for me – you can use absolute URIs for the tile images. eaning that you can give as a source a image directly from the internet and the OS will download and cache it for you.

tileData.WideBackgroundImage = new Uri("http://cdn.marketplaceimages.windowsphone.com/v8/images/0a539106-8940-4898-99c2-744cbc7a6097?imageType=ws_icon_small", UriKind.Absolute);



Insolated Storage Settings Helper for Windows Phone

Decided that I’d share a really simple helper class that I often use in my Windows Phone apps. It’s called IsolatedStorageSettingsHelper and it only has three methods:

  • T GetItem<T>(string key) – gets the object with the specified key from the IsolatedStorageSettings. If there isn’t an object with that key it will return null. If the object is not of the type specified then it will return a new instance of T.
  • void SaveItem(string key, object item) – saves the item passed as a parameter in the IsolatedStorageSettings using the specified key.
  • void SaveItems(Dictionary<string, object> items)  – used for saving multiple items at once. All the items in the dictionary are saved in the IsolatedStorageSettings with their respective keys.

This is not much, but that’s all I ever needed for my apps. Hope it will be of help. Code below.

public class IsolatedStorageSettingsHelper
{
   public static void SaveItem(string key, object item)
   {
      IsolatedStorageSettings.ApplicationSettings[key] = item;
      IsolatedStorageSettings.ApplicationSettings.Save();
   }

   public static void SaveItems(Dictionary<string, object> items)
   {
      foreach (var item in items)
         IsolatedStorageSettings.ApplicationSettings[item.Key] = item.Value;
      IsolatedStorageSettings.ApplicationSettings.Save();
   }

   public static T GetItem<T>(string key)
   {
      T item;
      try
      {
         IsolatedStorageSettings.ApplicationSettings.TryGetValue<T>(key, out item);
      }
      catch (InvalidCastException ice)
      {
         return default(T);
      }
      return item;
   }
}



Metro TimeBlock

Metro TimeBlock is a time display control that I’ve made which should allow you to display time in any color and with any background you want. Size is also adjustable and you can choose to display either the current time or a time of your own.

Metro TimeBlock

Properties of the control:

Time – takes in any DateTime object. The control will display the Time you provide within that DateTime object. Leave blank if you want to display the current time.

Spacer – this is the string to display between the hours and minutes and between the minutes and seconds. Use spacers like “:” or ” “.

Size – you can choose from Small, Normal, Medium, MediumLarge, Large, ExtraLarge, ExtraExtraLarge and Huge. Chose to do this instead of allowing FontSize because this way I can also control the way the background blocks look.

Foreground – tells the control what color to use to display the time.

Fill – sets the background color of the control (the square-like blocks).

That’s about it. If you got any problems with it / need help, leave a comment below. The download link is also below and it contains both the control and a couple of samples.

Download for Windows Phone




Metro and WinRT Webinar on February 2nd

Are you a Silverlight / WPF developer? Want to start developing for Windows 8 as well?  If that’s the case, this upcoming SilverlightShow webinar is guaranteed to give you a jump start. The webinar will teach you how to use your Silverlight / WPF experience to build amazing Windows 8 apps by presenting the similarities between Silverlight / WPF and XAML based Metro apps. This will be done by looking at a working Metro app containing most of the things you were used to in Silverlight / WPF.

Also, as usual, SilverlightShow is giving away 6 eBooks:

Good luck!

Presenter: Gill Cleer
Webinar registration page: Metro and WinRT for the Silverlight/WPF Developer
More details about the webinar: SilverlightShow




Windows Phone 7: Getting the current GPS location from the device

Getting the current GPS location on a Windows Phone device is rather easy. In order to start you will need to add a reference to System.Device in your project and then a using statement inside the class that you want to get the geo-location.

using System.Device.Location;

Next we would need to declare an object of type GeoCoordinateWatcher. For better access I will declare it as a class member and not as a local variable inside some method.

GeoCoordinateWatcher geoWatcher = null;

Next to do is: create an instance of GeoCoordinateWatcher, create an event handler for the position changed event and then start reading the data. So, to create an instance of GeoCoordinateWatcher go to the class constructor and copy the following code:

geoWatcher = new GeoCoordinateWatcher();

This will create a GeoCoordinateWatcher object in the variable we previously declared. In case the location you need has to have a certain accuracy, the class provides you with an overload for the contructor which takes your desired accuracy as a parameter.

geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);

Next create an event handler for the PositionChanged event. You can do this by typing geoWatcher.PositionChanged += and then press the TAB key twice; this will automatically create the event handler for you. After creating the event handler, all you need to do is use geoWatcher.Start() to start reading coordinates. Now your code should look like this:

GeoCoordinateWatcher geoWatcher = null;
public MainPage()
{
   InitializeComponent();
   geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
   geoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcher_PositionChanged);
   geoWatcher.Start();
}

void geoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
   throw new NotImplementedException();
}

Next we want to get the coordinates for our location. That is really simple. You can get them in a GeoCoordinate object by accesing e.Position.Location in the event handler, or if you want to get them as individual values you can save e.Position.Location.Latitude, e.Position.Location.Longitude and e.Position.Location.Altitude in three double variables. Example below:

void geoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
   GeoCoordinate currentLocation = e.Position.Location;
   double currentAltitude = e.Position.Location.Altitude;
   double currentLongitude = e.Position.Location.Longitude;
   double currnetLatitude = e.Position.Location.Latitude;
}

That’s it. Now if you want to get rid of the object and stop reading the current location after reading the first set of values you can simply add the following lines of code to the event handler. Otherwise you can create a method for it and call it whenever you wish.

geoWatcher.Stop();
geoWatcher.Dispose();
geoWatcher = null;

In order to test the code I just wrote I will add three textboxes to my application in which I will write the data I read in them. You can do the same. Anyways that’s it. If you got any questions leave a comment and I’ll answer them asap.

You can get the project from here:Download for Windows Phone




31 Days of Windows Phone Metro Design

Those of you wanting to learn more about metro design and how to make your apps look as metro-ish as possible should know that a new series of articles called “31 Days of Windows Phone Metro Design” has just started.

The first article in the series (about the metro design principles) is already up. A link to the post and to all the upcoming ones can be found here.

Articles will pop up once a week, maybe twice so be sure to check them out.




Leveraging Windows Azure for the Windows Phone Developer – Webinar

Just letting you know that there’s an upcoming webinar on the 4th of this month about Windows Azure and how we can benefit from it in Windows Phone. The webinar will be presented by Samidip Basu and has the following agenda:

  • Introduction to Cloud Computing & Windows Azure
  • Push Notifications for Windows Phone
  • Push Notifications from Azure, including deep-linked secondary Live Tiles & Toasts for Windows Phone Mango
  • Why consider OData while leveraging the cloud in cross-platform Mobile solutions
  • Usage of SQL Azure & OData through Windows Phone
  • Usage of Azure-hosted WCF Services for Windows Phone
  • How to use Azure Toolkit for Windows Phone

Date and time: January 4th at 10 AM PDT (check your local time)
Registration link: https://www1.gotomeeting.com/register/386800777

By tweeting about this webinar using the tag #webinarsilverlightshow you get the chance to win the Windows Phone 7 Silverlight Cookbook and at the end of the webinar by giving a constructive feedback you can also get for free the  OData & Cloud Augmentation of Windows Phone Applications ebook.

For more details about the webinar and the free ebooks feel free to visit SilverlightShow.NET




Transparent TextBox for Windows Phone

Below you have a style which applied to your textbox will make it fully transparent. The difference between applying this style and simply setting the Background property of your textbox to transparent or removing it completely is that the style also removes the focus effect the textbox gets when tapped. I mean no matter what background color you set when the textbox gets focused the background turns white.

So here’s the style (you need to add this to your app/page/user control resources):

<ControlTemplate x:Key="PhoneDisabledTextBoxTemplate" TargetType="TextBox">
	<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
</ControlTemplate>
<Style x:Key="TransparentTextBoxStyle" TargetType="TextBox">
	<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
	<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeMediumLarge}"/>
	<Setter Property="Background" Value="{StaticResource PhoneTextBoxBrush}"/>
	<Setter Property="Foreground" Value="{StaticResource PhoneTextBoxForegroundBrush}"/>
	<Setter Property="BorderBrush" Value="{StaticResource PhoneTextBoxBrush}"/>
	<Setter Property="SelectionBackground" Value="{StaticResource PhoneAccentBrush}"/>
	<Setter Property="SelectionForeground" Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}"/>
	<Setter Property="BorderThickness" Value="{StaticResource PhoneBorderThickness}"/>
	<Setter Property="Padding" Value="2"/>
	<Setter Property="Template">
		<Setter.Value>
			<ControlTemplate TargetType="TextBox">
				<Grid Background="Transparent">
					<VisualStateManager.VisualStateGroups>
						<VisualStateGroup x:Name="CommonStates">
							<VisualState x:Name="Normal"/>
							<VisualState x:Name="MouseOver"/>
							<VisualState x:Name="Disabled">
								<Storyboard>
									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
										<DiscreteObjectKeyFrame KeyTime="0">
											<DiscreteObjectKeyFrame.Value>
												<Visibility>Collapsed</Visibility>
											</DiscreteObjectKeyFrame.Value>
										</DiscreteObjectKeyFrame>
									</ObjectAnimationUsingKeyFrames>
									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
										<DiscreteObjectKeyFrame KeyTime="0">
											<DiscreteObjectKeyFrame.Value>
												<Visibility>Visible</Visibility>
											</DiscreteObjectKeyFrame.Value>
										</DiscreteObjectKeyFrame>
									</ObjectAnimationUsingKeyFrames>
								</Storyboard>
							</VisualState>
							<VisualState x:Name="ReadOnly">
								<Storyboard>
									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="EnabledBorder">
										<DiscreteObjectKeyFrame KeyTime="0">
											<DiscreteObjectKeyFrame.Value>
												<Visibility>Collapsed</Visibility>
											</DiscreteObjectKeyFrame.Value>
										</DiscreteObjectKeyFrame>
									</ObjectAnimationUsingKeyFrames>
									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility" Storyboard.TargetName="DisabledOrReadonlyBorder">
										<DiscreteObjectKeyFrame KeyTime="0">
											<DiscreteObjectKeyFrame.Value>
												<Visibility>Visible</Visibility>
											</DiscreteObjectKeyFrame.Value>
										</DiscreteObjectKeyFrame>
									</ObjectAnimationUsingKeyFrames>
									<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="DisabledOrReadonlyContent">
										<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneTextBoxReadOnlyBrush}"/>
									</ObjectAnimationUsingKeyFrames>
								</Storyboard>
							</VisualState>
						</VisualStateGroup>
						<VisualStateGroup x:Name="FocusStates">
							<VisualState x:Name="Focused"/>
							<VisualState x:Name="Unfocused"/>
						</VisualStateGroup>
						<VisualStateGroup x:Name="ValidationStates">
							<VisualState x:Name="InvalidFocused"/>
							<VisualState x:Name="Valid"/>
							<VisualState x:Name="InvalidUnfocused"/>
						</VisualStateGroup>
					</VisualStateManager.VisualStateGroups>
					<Border x:Name="EnabledBorder" BorderThickness="{TemplateBinding BorderThickness}" Margin="{StaticResource PhoneTouchTargetOverhang}">
						<ContentControl x:Name="ContentElement" BorderThickness="0" HorizontalContentAlignment="Stretch" Margin="{StaticResource PhoneTextBoxInnerMargin}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="Stretch"/>
					</Border>
					<Border x:Name="DisabledOrReadonlyBorder" BorderThickness="{TemplateBinding BorderThickness}" Margin="{StaticResource PhoneTouchTargetOverhang}" Visibility="Collapsed">
						<TextBox x:Name="DisabledOrReadonlyContent" Foreground="{StaticResource PhoneDisabledBrush}" FontWeight="{TemplateBinding FontWeight}" FontStyle="{TemplateBinding FontStyle}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" IsReadOnly="True" SelectionForeground="{TemplateBinding SelectionForeground}" SelectionBackground="{TemplateBinding SelectionBackground}" TextAlignment="{TemplateBinding TextAlignment}" TextWrapping="{TemplateBinding TextWrapping}" Text="{TemplateBinding Text}" Template="{StaticResource PhoneDisabledTextBoxTemplate}"/>
					</Border>
				</Grid>
			</ControlTemplate>
		</Setter.Value>
	</Setter>
</Style>

Now that you’ve got the style, all you need to do is apply it to your textbox like so:

<TextBox Style="{StaticResource TransparentTextBoxStyle}"/>

And that’s all. Your textbox should be 100% transparent now. Also, in case you want to try it out before using it I’ve made a sample project you can download below.

Download Transparent TextBox Sample