Category Archives: Windows Phone

Windows Phone

Windows Phone HTML5 hybrid

Introduction

When apps for mobile devices were first introduced by the launch of the iPhone, they were written natively for the platform. As time went, more platforms entered the arena namely Android and Windows Phone. All three platforms has a fair user base. When a company or organization wants to create an app they are faced with the choice “what platforms do you want to target? What platform is used by your customers?” Often the answer to that question is that the users are spread among the three platforms and the company wants to target as many of their customers as possible.
As always there are (most often) restrictions to the projects and the biggest restriction is budget. It can be very expensive to target all the platforms with native code, especially if you build big apps like mobile web shops. Decisions must be made in how to proceed. One option is to forget about the apps and go web. That can be a good decision sometimes but not always, for instance many companies’ wants to be published and exposed via the different app stores or when the phone characteristics is needed (GPS etc.). Fortunately there is another way – Hybrid apps. The app is native but the content is built with HTML and CSS. The content is the same for the different platforms but it is hosted in a native app shell – one for each platform.
This blog post will show how you can create a hybrid app on the Windows Phone platform. As always the demo project source will be available at the bottom of the post :)

How to do it

First of all, launch your Visual Studio and then go File->new project. In the project dialog, choose the Windows Phone HTML5 App.

project selection

The project template that is created is basically an app containing a Web Browser control (IE) with navigational buttons; forward and back.


    




    
        
        
        
            
        
    

 

Take a look at the project structure. You will notice that you got one more folder than when you are creating other types of Windows Phone apps, namely the folder called Html. This is where we will put our content.
project_structure

From the start you will see that the Html folder contains an index file. This is set in code to be the file that the app will navigate to when the app starts. This is set in the code behind;

        private string MainUri = "/Html/index.html";

        private void Browser_Loaded(object sender, RoutedEventArgs e)
        {
            // Add your URL here
            Browser.Navigate(new Uri(MainUri, UriKind.Relative));
            Browser.IsScriptEnabled = true;
        }

If we inspect the index.html file we see that it is just plain html;

 
        

MY APPLICATION

page title

Try to run the app and you will get;
first_run

So far so good. We have a running app that uses an html file. We can now add as many html files as we want to create our content. Our html files work just like they would on the web, with link navigation etc. Well this will not suffice in most cases, we want to use the cool features in the phone! So our next mission is to get connectivity from the phone to the web page and back!

Send data to and from a web page

The potential for an app to send data to and from a web page is great. The cases can be for instance to send GPS-coordinates, accelerometer data and other cool sensor information. The glue between the phone and the web is our old friend, JavaScript. To enable scripting between the page and the app shell we need to do two things. First we need to set IsScriptEnabled to true on the Browser object and then we need to add an event to the Browser control that handles notifications from the web page. The event handler for this event is where all calls from the web pages will end up.

ScriptNotify="Browser_ScriptNotify_1"

The first demo we are going to implement is a GPS-tracking web page. We will use the GPS-chip in the phone and let the web page decide when the tracking is on or off. When the tracking is on, the phone will send GPS-data to the web page that will be displayed.
First step is to create the web page for our demo. We call the page gpspage.html and we place it in our html folder. Then we add some basic html to our page.


    

HTML5 hybrid demo

gps location

You are here:

We add a few rows to our css file just to emphasize on the lat, long part and when we are at it, we add css for links for our index file as well.

a {
    color:#b6ff00;
    font-size:14pt;
}

.coordinates {
    color:#b6ff00;
}

After we added the nice css we will add our JavaScript for the page. Three methods is added to the page. One for starting the GPS-tracking, one for stopping it and one for setting the location. The first two methods are calling the app-native shell and sends a string as parameter. The windows.external.notify is the method used to send data to the native part and it is the “ScriptNotify” event handler described earlier that will handle the call. The third method setLocation is a method that we will use from the native shell to set GPS-updates when they occur.

    

So now we have the interface. There are a few things left to do before we have a runnable demo. First of all, since we wants to use the GPS, we need to add that capability in the manifest file.
locationCapability

Then we will need to write some native code for the GPS to work. This is done in the MainPage.cs file. First we add a field for our GeoCoordinateWatcher and then we initialize it in the constructor of the page.

        private GeoCoordinateWatcher coordinateWatcher;
        
        public MainPage()
        {
            InitializeComponent();
            coordinateWatcher = new GeoCoordinateWatcher();
            coordinateWatcher.PositionChanged += coordinateWatcher_PositionChanged;
        }

Next thing is to add the handler for the position changed event. First we need to check to see if the page we are navigated to in the Browser has the script that we wants to access. Since we only added it to the gpspage we check to see that that is the current page. Otherwise we skip the location update. If we don’t do this, the browser will throw an exception. Note the InvokeScript method returns and object. This is good since our JavaScript methods could be implemented to return a value.

 void coordinateWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs e)
 {
      //Check to see that we only send GPS-data to our page that can handle it
      if (Browser.Source.OriginalString == "/Html/gpspage.html")
      {
         var result = Browser.InvokeScript("setLocation", new string[] { e.Position.Location.Latitude.ToString(), e.Position.Location.Longitude.ToString() });
       }
  }

Next we need to implement the start and stop. First we navigate to our method for handling notifies from the web pages and add a switch for where we are. This is to keep our code nice and tidy. And then we add a handling method for the GPS page.

        private void Browser_ScriptNotify_1(object sender, NotifyEventArgs e)
        {
            switch(((WebBrowser)sender).Source.ToString())
            {
                case "/Html/gpspage.html": ManageGPSPage(sender, e); break; 
            }
        }

        private void ManageGPSPage(object sender, NotifyEventArgs e)
        {
            if (e.Value == "startGpsTracking")
            {
                coordinateWatcher.Start();
            }
            else if (e.Value == "stopGpsTracking")
            {
                coordinateWatcher.Stop();
            }
        }

Final step before we run our app is to add a link to our index file so we can navigate to our GPS tracking page.

GPS-Demo

No we will run our app, navigate and start our tracking and it will look like this;
first run  tracking

For the fun of it and to demonstrate how easy it is to use the phone resources we are going to add another demo. This time we will use the case where you have some contact info and the desire is for the user to make a quick call from the app. First we adds a new web page to the html folder called contact.html and set it up with html and JavaScript as follows;




    
    
    
    


    

HTML5 hybrid demo

contact

Contact information

Name: John Doe

Division: Sales

Now we have html for the layout, a button for the calling and a JavaScript method that will call the native shell and provide a phone number for the contact. Next we will add the code for handling this. First stop is to extend our ScriptNotify event handler and adding a method for handling the call where we will use a PhoneCallTask for the actual phone call. If you are new to the launchers and choosers concept, please read my previous post on that topic. http://www.bjarneryd.se/?p=134

private void Browser_ScriptNotify_1(object sender, NotifyEventArgs e)
{
    switch(((WebBrowser)sender).Source.ToString())
    {
        case "/Html/gpspage.html": ManageGPSPage(sender, e); break;
        case "/Html/contact.html": ManageContactPage(sender, e); break;
    }
}

private void ManageContactPage(object sender, NotifyEventArgs e)
{
    var pct = new PhoneCallTask();
    pct.PhoneNumber = e.Value;
    pct.Show();
}

Since we are going to use the dialer we need to add the capability for that or the app will throw an exception. So navigate to the manifest and add the capability;

dialer

Finally we need to add a new link in our index file.

Contact Demo

Running the app and making a call will now look like;

mainpage contact page

prompt call phone call

Handling back behavior

So now we have created a hybrid app with two nice features that uses the native shell. The only thing is that the navigation is a bit odd. If the user tries to navigate back using the hardware button after selecting a new web page, the app will close. This is because the navigation is done in the browser and not in the app itself. This can create frustration among the users since they expect the app to navigate back. To add a feeling of being more native, you can override the default back behavior for the button. To do this, add the following method in the code behind.

protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
    if (Browser.CanGoBack)
    {
        Browser.GoBack();
        e.Cancel = true;
    }
    else
    {
        base.OnBackKeyPress(e);
    }
}

What we do in the code above is to see if the browser has back entries. If it does and therefore can go back, we navigate in the browser. If not, meaning we are back at the index file or we never navigated away, we will adapt the default approach and exit the app. By doing it like this we add the same navigational pattern as all native apps.

Download the source code below.

download source code

Windows Phone text to speech

In Windows Phone there are great features to communicate with an app using voice. In previous post I have described how to command your app using your voice. In this post I will cover on how the app can respond using text to speech. The feature text to speech can be used in various scenarios to give the user feedback and is definitely a great tool to optimize your apps accessibility. The entire source code can be downloaded at the end of the post.

Windows Phone have support for 15 languages (sadly, not Swedish) and each language comes with two voices, one male and one female. The phone has one voice set as default. This can be viewed and changed in the phone settings. The default voice is the one to be used if not the app say otherwise.

windows phone settings

windows phone settings
speech settings

speech settings

First of all we create a simple UI with three buttons supporting our three scenarios. Add event handlers to the buttons.

main ui

main ui

Now we need to add speech recognition capability to the app. If not, we will get a security error when we try to speak any text. Open the app manifest and add the capability as shown in the picture below.

Speech recognition capability

Speech recognition capability

Now we will dig into the code and start with scenario number 1. The crazy thing here is that only two lines of code are needed to speech text with the default voice. First of all we create a new method and in that we create a SpeechSynthesizer object that will be used to speak the text we will provide for it. Then we will use the method SpeakTextAsync on the synthesizer-object and send in the text. Note that this method is async so we need to decorate our method with the async keyword.

 
        private async void GreetInEnglish()
        {
            //Fist create the synth that will be playing the sound
            SpeechSynthesizer synth = new SpeechSynthesizer();
            //await the synth while it speaks the text of your choice. This will use the default voice.
            await synth.SpeakTextAsync("Hello man! How are you today? Well i'm just fine myself!");
        }

Run the app and hear it greet you! :)

Now for scenario no 2 we will start out as in scenario 1 with a new method. Now we will tell the phone to use a female French voice. This is easily done by querying the InstalledVoices.All for a voice that is of culture “fr-FR” and female. Then we will tell the SpeechSynthesizer-object to use that voice. I have used Google-translate to translate the text from the previous sample to French. This will make the speech sound more natural J

 
        private async void GreetInFrench()
        {
            //Create the synth that will be playing the sound
            SpeechSynthesizer synth = new SpeechSynthesizer();

            //Find the voice of your choice. In this case french woman
            var voice = (from x in InstalledVoices.All
                     where x.Language == "fr-FR" &&
                     x.Gender == VoiceGender.Female
                     select x).FirstOrDefault();

            //Tell the synth to use the selected voice
            synth.SetVoice(voice);

            //await the synth while it speaks the text of your choice with the selected voice
            await synth.SpeakTextAsync("Bonjour homme! Comment allez-vous aujourd'hui? Eh bien, je suis juste moi-même très bien!");
        }

For our final scenario we will create a method that will loop through all the installed voices and let them say “Hello World”. Just as in the previous example we will use the installed voices, but this time we will loop over them and let each and one of them speak the text.

 
        private async void LoopAllVoices()
        {
            //Create the synth that will be playing the sound
            SpeechSynthesizer synth = new SpeechSynthesizer();

            //Loop all the installed voices
            foreach (var voice in InstalledVoices.All)
            {
                //Tell the synth to use the selected voice
                synth.SetVoice(voice);
                //await the synth while it speaks the text with the current voice
                await synth.SpeakTextAsync("Hello world!");
            }
        }

Download the source code and have fun! :)

download source code

Send speech commands to your Windows Phone 8 app

In Windows Phone 7.x users can already interact with their phone using the voice. This is done by pressing and holding the Windows key and giving the phone a voice command e.g. “Start [appname]” or “Open [appname]“. In Windows Phone 8 you can extend this and add additional phrases that a user can say which opens up new opportunities allows users to launch to a specific page in an app and launch an app and initiate an action. This post will cover how easy you can implement voice commands in your app. Source code is provided at the end.

Note; this post covers start up commands. Speech recognition within the app will be covered in a later post.

So, we start of with a new Windows Phone 8 project.
The first step is to open the WMAppManifest.xml-file located in the Properties-folder. Switch to the Capabilities-tab. Here we will give the app the necessary capabilities to be able to handle the voice commands. Check the ID_CAP_SPEECH_RECOGNITION-capability.
speech capability

For our demo purpose, before we start with the commands, we add another page to the solution so we have something to navigate to. We can call the page Target.xaml.

Now we are going to add a new item to our project. Select Add->New Item in the context menu for the project and select Voice Command Definition. Lets name it VCDFile.
Add VCD file

The VCD-file will give you an example of how to setup your commands. So lets digg into the file and make it our own. Let’s start at the top with the Command Prefix and Example. The value in the prefix tag is what the app will look for as a prefix to the command. So the user will say “SpeechDemo” followed by the commands. The value in the example tag will be displayed by the help for this app as an example of the commands the app supports.

SpeechDemo
 navigate to target

Next we are going to add a command that the app will act upon.
First we will give our command a name. In this case “Navigate”.
Then we will provide an example for this command. “navigate to target”. This will be displayed to the user by the phone as help.
Then we will specify what the phone will actually listen for. “[and] navigating to target”. The square brackets indicates that the word is optional. The reason why we use it this way is because it can give the user a more natural way of speaking. To explain this we will first take a look at two different ways of starting the app;
“SpeechDemo navigate to target” –> Here the “and” would sound weird.
“Start SpeechDemo and navigate to target” –> Without the “and” the user would feel that the command sounded weird.
Then we will provide feedback. This is what the phone will read back to the user and write on the screen.
Navigate is where you can, if you want, specify where the app should navigate when it receives the command. Here we insert our previously added page, “Target”. If you don’t specify a target you will land on your main page where you parse the incomming command and take action in code.
The whole thing wraps up like;

    
       navigate to target 
       [and] navigate to target 
       Navigating to target page... 

    

If you like, you can also specify options to a command with a “PhraseList”. The phrase list can be extended over time and is can be used for e.g. level selction in a game. To use a phrase list you insert the name of the phrase list in curly brackets. Here is an example we will use later on;

    
       show message one 
       [and] show message {number} 
       Showing message 

    

       one 
       two 
       three

We are now finished with the VCD-file. Now we need to install the VCD file. The file needs to be installed the first time the app runs. Before the install, no commands will work with the app, since the commands are registered with the speech system on the user’s phone. In this demo we will install the file when the app starts. Go to the code behind for MainPage.xaml and add the following lines;

        public MainPage()
        {
            InitializeComponent();
            SetupVoice();
        }

        public async void SetupVoice()
        {
            await VoiceCommandService.InstallCommandSetsFromFileAsync(new Uri("ms-appx:///VCDFile.xml", UriKind.RelativeOrAbsolute));
        }

This will install the file. Note that the VCD-file can loaded from any URI and not only from the app and that it can be changed by the app when it is running.

Now we can start the app for the for the first time and then begin sending voice commands.
Start the app and then press and hold the Windows key and say; “SpeechDemo navigate to target”. The app will give feedback and then navigate to the target page in the app.

If you wish to inspect the translated query-string for the command this can be done in the “OnNavigatedTo”-method. This is useful when you need to see what phrase that was used or if you wish to have all the commands on one page without navigating away. We are gonna use our command “ShowMessage” from before to show how this can be done. Insert the following code in the MainPage.xaml and try the saying “SpeechDemo show message one”.

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            if (e.NavigationMode == System.Windows.Navigation.NavigationMode.New)
            {
                if (NavigationContext.QueryString.ContainsKey("voiceCommandName")) //voice command in querystring
                {
                    var command = NavigationContext.QueryString["voiceCommandName"]; //voice command in querystring
                    switch (command)
                    {
                        case "ShowMessage": //The name of the VCD-command
                                var phrase = NavigationContext.QueryString["number"]; //get the phrase
                                DemoText.Text = string.Format("ShowMessage command {0} activated", phrase);
                            break;
                        default:
                            DemoText.Text = "Couldn't find the command";
                            break;
                    }
                }
            }
        }

Now you have everything you need to create cool apps with voice commands!

Download the source code and have fun! =)

download source code

Use Prism data template selector in Windows Phone app

Quite often you would like to have a Collection in your view model that supports multiple types that derives from the same base type. Along with the different subclasses, you might want different data templates in your view, one for each type. Microsoft Prism can help you do this in an easy way and automatically select correct template for each type. This post will show how to do it on Windows Phone and you can also download the source code for the demo project (Windows Phone 7.1 for compatability) at the bottom of the page.

First of all, use Nuget to install Prism Phone to your project.
nuget prism phone

Now, lets play with an example where we want to present a Schedule that contains meetings and trips. This gives us a solution that looks like this.

We edit our simple models so they look like this;

namespace PrismTemplateSelector.Models
{
    public class ScheduleItem
    {
        public DateTime StartDate
        {
            get;
            set;
        }

        public DateTime StopDate
        {
            get;
            set;
        }
    }
}
namespace PrismTemplateSelector.Models
{
    public class Meeting : ScheduleItem
    {
        public string MeetingOrganizer
        { 
            get; 
            set; 
        }
    }
}
namespace PrismTemplateSelector.Models
{
    public class Trip : ScheduleItem
    {
        public string Destination
        {
            get;
            set;
        }
    }
}

Now we will add some code to our view model to add some demo data for our view.

namespace PrismTemplateSelector.ViewModels
{
    public class MainPageViewModel
    {
        public MainPageViewModel()
        {
            Items = new ObservableCollection();
            LoadDemoData();
        }

        public ObservableCollection Items { get; set; }

        private void LoadDemoData()
        {
            Items.Add(new Meeting()
            {
                StartDate = DateTime.Now.AddHours(1),
                StopDate = DateTime.Now.AddHours(4),
                MeetingOrganizer = "Todd Schmidt"
            });
            Items.Add(new Trip()
            {
                StartDate = DateTime.Now.AddDays(4),
                StopDate = DateTime.Now.AddDays(14),
                Destination = "New York"
            });
            Items.Add(new Meeting()
            {
                StartDate = DateTime.Now.AddDays(3),
                StopDate = DateTime.Now.AddDays(3).AddHours(1),
                MeetingOrganizer = "Gilian Pearson"
            });
        }
    }
}

Now when that is all set up, lets look at the magic in our xaml. First of all we will add namespace for Prism into our xaml-view.

xmlns:prism="clr-namespace:Microsoft.Practices.Prism.ViewModel;assembly=Microsoft.Practices.Prism"

After this we will start to write our data template and add them to our resources on the page. Note that the DataTemplate x:key shall be the name of the type you wish to bind to the template.

    
        

        
            
                
                    
                        
                            
                                
                                
                                
                            
                            
                                
                                
                            
                            
                            
                            
                            
                            
                            
                        
                    

                    
                        
                            
                                
                                
                                
                            
                            
                                
                                
                            
                            
                            
                            
                            
                            
                            
                        
                    
                
            
        

    

So finally we will tie Everything together and apply the templateselector to our listbox.


The result will now be;
prism result

download source code