Windows Phone 8.1 for Newbies – The complete reference of Map Control in Windows Phone 8.1 WinRT

As Windows Phone came up with Windows Phone 8.1 update last year it came up with 2 different platforms to work on , silverlight and WinRT, thus making it a bit tough to keep up with the latest api documentation and maps are not different.

As I have written before how to use Maps following MVVM on Windows Phone 8, I’m going to keep today’s one as a bit of a reference to that and will just post segments that you can use as a code sample.

Instantiating a Map in Windows Phone 8.1:

Quiet frankly this is the easiest job here to do actually. Let’s go ahead and start taking things on screenshot. First we need to open a new project targeting Windows Phone 8.1 and name it MapTest. Then I went to my Toolbox and dragged a MapControl in the middle of the Main Grid. I have already changed my map controls HorizontalAlignment and VerticalAlignment to “stretch’ thus allowing the MapControl to be stretched out to the fullest for the whole app.


<Maps:MapControl HorizontalAlignment="Stretch"  VerticalAlignment="Stretch"/>

Usually a map driven app needs an AuthenticationToken to authenticate the map services but we will focus on it later. Let’s go ahead to solution explorer and open Package.appxmanifest and go to Capabilities tab and make sure Location and Internet both of the checkboxes are checked just to make it sure that your app is map capable.

Map -1

Now we have a green light to use Maps. If you are  a fella from Windows Phone 8 development you’ll see now, you don’t have ID_CAP_MAP here to make an app enable to use maps. You only need it to have location capability.

Getting Your Own Location:

Getting your own location is still as straightforward as it was before in Windows Phone 8 era. All you have to do is use the same Geolocator class and it looks like the following:

Geolocator locator = new Geolocator();
Geoposition position = await locator.GetGeopositionAsync();

Now the question remains now is how would you be able to show it on a Map. Now, Windows Phone 8.1 gives you a lot of  options to choose from actually here. You can use three specific things here:

  1. MapIcon
  2. XAML controls
  3. Shapes

Using MapIcon:

The first trial we are going to make is using the MapIcon as it is most straight forward. MapIcon is essentially derived from MapElement class, it can be configured by providing a new image to it or it provides a default one. And the declaration is pretty straight forward too.


MapIcon icon = new MapIcon();
icon.Location = position.Coordinate.Point;
icon.Title = "My Location";
MyMap.MapElements.Add(icon);

Now, if you want to provide a specific Image as your MapIcon, include the image in the Assets folder and let’s assume the image name is MapIcon.png. All you have to do is change the Image property of your MapIcon object.

icon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/MapIcon.png"));

What people actually misinterpret here is usually they compare PushPin with MapIcon and they do have a valid reason to do so because you can achieve the same result by using both of them but in actuality it doesn’t work like so. MapIcons are actually a set of Icons that define different purposes on the map. These are lightweight, so please chose one if you want to use these to show a specific purpose. Now our purpose was to show our current location.

Now let’s put together a method named GetMyLocation() and put all these together and see what happens.


private async void GetMyLocation()
        {
            Geolocator locator = new Geolocator();
            Geoposition position = await locator.GetGeopositionAsync();

            MapIcon icon = new MapIcon();
            icon.Location = position.Coordinate.Point;
            icon.Title = "My Location";
            icon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/ImageIcon.png"));
            MyMap.MapElements.Add(icon);

            MyMap.Center = position.Coordinate.Point;
            MyMap.DesiredPitch = 0;

            await MyMap.TrySetViewAsync(position.Coordinate.Point, 15);
           
        }

Now, as this goes, you’ll see Ive done some more works too. I’ve changed the center property of the map control because after adding the MapIcon you need your map to focus on that point and this is how you change the center of your map. And the next thing I did is setting DesiredPitch to 0. We will see more on this property later. You definitely have noticed by now that the method is an asynchronous method because the process of locating your position is asynchronous and we’re using our favourite await keyword to make locator.GetGeopositionAsync() to work synchronously inside the method. The last thing you want is to focus to the selected location (My Location) on the map. So Im setting the map view in an async manner using  MyMap.TrySetViewAsync function and it takes two parameters, the first one being the point (the geolocation of you) you want to set your view into and the second is a zoom level of the map. It is actually setting the MyMap.ZoomLevel property that ranges from 1 – 20. Higher number means you’re more zoomed thus more closer to the ground. I’ve also used a custom MapIcon.png with a size of 65×65 pixels. Please be careful on this one as the size you chose is the size you get on the Map. Please choose a size that looks good for your purpose. Now lets put the GetMyLocation() method OnNavigatedTo method and thus you get a smooth zooming animation.

Map -2

Now, couple of things that are missing here is a progress bar showing that the location is being detected and a try catch that detects any exception detecting the location. Plus we need to put our location detection invocation in a button so we can tap it anytime to load our current location anytime. For that we are going to take help of Application Bar.

Now Let’s add an app bar in the bottom like below:


<Page.BottomAppBar>
<CommandBar ClosedDisplayMode="Minimal" Opacity="0.7">
<AppBarButton Label="Find Me!" Icon="Target" />
</CommandBar>
</Page.BottomAppBar>

Now on the AppBarButton_Tapped event handler put GetMyLocation call. It would possibly look like the following:


private void AppBarButton_Tapped(object sender, TappedRoutedEventArgs e)
{
GetMyLocation();

}

Now, let’ wrap up the location detection process under a try-catch just to make sure that if anything goes wrong, you’re covered. And as we’d need to show progress please put the following method in MainPage.xaml too.


private async void ToggleProgressBar( bool toggle, string message="")
{
StatusBarProgressIndicator progressbar = StatusBar.GetForCurrentView().ProgressIndicator;
if(toggle)
{
progressbar.Text = message;
await progressbar.ShowAsync();
}
else
{
await progressbar.HideAsync();
}

}

Now all you have to do is call it to show ProgressIndicator in StatusBar, you can even provide the message in the method call.

Now GetMyLocation would look like the following:

private async void GetMyLocation()
        {
            ToggleProgressBar(true,"Getting your location...");

            try
            {
                Geolocator locator = new Geolocator();
                Geoposition position = await locator.GetGeopositionAsync();

                MapIcon icon = new MapIcon();
                icon.Location = position.Coordinate.Point;
                icon.Title = "My Location";
                icon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/ImageIcon.png"));
                MyMap.MapElements.Add(icon);

                MyMap.Center = position.Coordinate.Point;
                MyMap.DesiredPitch = 0;

                await MyMap.TrySetViewAsync(position.Coordinate.Point, 15);
            }
            catch (Exception ex)
            {
                MessageDialog ErrorDialog = new MessageDialog(ex.Message);
                ErrorDialog.ShowAsync();
            }

            ToggleProgressBar(false);
        }

Using XAML Controls/Shapes on Map:

Using XAML controls over Map is something I really love because I was pretty fond of the PushPin control provided in Windows Phone Toolkit for Windows Phone 8. Usually this approach is more suitable for MVVM approached apps though. And as per this tutorial goes, we’d not got over MVVM just yet (We will cover that too). So, let’s see how you add XAML controls or shapes in a map from codebehind.

Instead of using MapIcon all you have to do know is generate a XAML control/Shape in background and add it on the children list of the map control rather than the MapElements list.

So, just take off the MapIcon Segment and use this instead:


private async void GetMyLocation()
        {
            ToggleProgressBar(true,"Loading");

            try
            {
                Geolocator locator = new Geolocator();
                Geoposition position = await locator.GetGeopositionAsync();

                var pushpin = new Windows.UI.Xaml.Shapes.Ellipse();
                pushpin.Fill=new SolidColorBrush(Colors.Red);
                pushpin.Height=50;
                pushpin.Width=50;

                MyMap.Children.Add(pushpin);
     
                MyMap.DesiredPitch = 0;

                MapControl.SetLocation(pushpin,position.Coordinate.Point);
                MapControl.SetNormalizedAnchorPoint(pushpin, new Point(0.5, 0.5));

                await MyMap.TrySetViewAsync(position.Coordinate.Point, 15,0,0,MapAnimationKind.Bow);
            }
            catch (Exception ex)
            {
                MessageDialog ErrorDialog = new MessageDialog(ex.Message);
                ErrorDialog.ShowAsync();
            }

            ToggleProgressBar(false);
 
        }

Now, before moving to the next topic,  I’d like to address some points in this approach.

  1. You can create your control in codebehind as you want to build it, you can use possibly any XAML control starting from containers like Grid and StackPanels to Shapes like rectangle and Ellipse.
  2. Select a proper size of the shape if you want to use it and it’s better than MapIcons in one sense is that MapIcons are not guaranteed to be viewed.
  3. MapIcon objects are usually added in the MapElements list but this is added in the Map Children collection.
  4. You can define your datatemplate behind and even hook events (We will see this on MVVM approach

You have to select a proper anchor point for your Xaml/Shape pushpin too. It’s actually nothing but a point object in a 2d space. I want my anchor point to be in the center of the sphere. So if I put my sphere in a 2d space and 1 is the max limit in both X and Y axis, you’d find out that (0.5, 0.5) is the center of the sphere. But this 2d co-ordinate system is actually a tad different. Kindly allow me to demonstrate in the following picture:

Map -4

So, according to this rule, now you can set your anchor point properly according to your xaml control. Just put it on an imaginary 2d grid and find your desired point. left bottom would be (0,1) and right bottom would be (1,1).

If you look closely you will also see we have changed our TrySetViewAsync invocation with some more parameters. Those are heading, pitch (We kept both of them at 0) and the last one is MapAnimationKind that allows you to define what kind of animation you want when setting the view. I personally love the Bow one thus I used that one and it looks like below:

Map -3

Changing The Map Properties:

The map control itself comes with a lot of properties equipped, let’s see how we can change these for a chance. The first two things we’d love to change is the pitch/tilt and the rotation/heading. For that we’d need to change our layout a bit. Let’s keep the map in the background and put 2 sliders (one horizontal and one vertical) for changing rotation and pitch of the map.

We have introduced 3 rows and columns in the main grid just to keep the whole map in the background and the sliders floating in the top. The horizontal slider would change the Maps rotation and the Vertical Slider would change the Maps pitch. Now the main grid looks like the following:


<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>

</Grid.ColumnDefinitions>

<Maps:MapControl Grid.RowSpan="3" Grid.ColumnSpan="3" x:Name="MyMap"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

</Maps:MapControl>

<Slider x:Name="RotationSlider" Grid.Row="0" Grid.Column="1" Maximum="360"></Slider>
<Slider x:Name="PitchSlider" Grid.Row="1" Grid.Column="2" Orientation="Vertical" Maximum="65"  ></Slider>
</Grid>

And it looks on the emulator like this:

Map -6

Now the first thing you’d notice here is I’ve named the sliders accordingly. The horizontal one is called RotationSlider and the vertical one is called PitchSlider. Now, usually what we do is invoke the ValueChanged event and change the Heading or the DesiredPitch of the map. But there is a smarter way to do that. You can create two element bindings to the MyMap and bind the value of the sliders to the specific properties. If you watch carefully you will see that I have set the RotationSlider maximum value to 360 as that is the maximum rotation value and PitchSlider Maximum to 65 as that is the maximum tilt the MapControl allows. Now replace your sliders with the following binding:


<Slider x:Name="RotationSlider" Grid.Row="0" Grid.Column="1" Maximum="360" Value="{Binding Heading, ElementName=MyMap, Mode=TwoWay}" ></Slider>
<Slider x:Name="PitchSlider" Grid.Row="1" Grid.Column="2" Orientation="Vertical" Maximum="65" Value="{Binding DesiredPitch, ElementName=MyMap, Mode=TwoWay}" ></Slider>

Please make it sure the Binding Mode is set to TwoWay so when the map updates the sliders updates too.  And without even writing a single backend code the feature is done!

Map -5

So, that’s a creative use of element binding. Now you could’ve done it even from code backend. All you had to do is go to properties of PitchSlider and RotationSlider and create the ValueChanged method stub.  The methods would’ve looked like the following:


private void PitchSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
MyMap.DesiredPitch = PitchSlider.Value;
}

private void RotationSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
MyMap.Heading = RotationSlider.Value;
}

Let’s move on and see some of the other features we’d like to test too. Let’s add two checkboxes in the bottom of the map to enable Traffic Flow and Land Marks. We added a horizontal stackpanel and added two checkboxes along with it.


<StackPanel Grid.Row="2" Grid.Column="1" Orientation="Horizontal">
<CheckBox x:Name="TrafficCheck" Content="Traffic Flow" Foreground="Green"></CheckBox>
<CheckBox x:Name="LandmarksCheck" Content="Land Marks" Foreground="Green"></CheckBox>
</StackPanel>

Now, we can use a bit more creative element binding or use Checked and Unchecked event to change the respective map control properties. Let’s see how we can bind it using element binding again.


<Maps:MapControl TrafficFlowVisible="{Binding IsChecked, ElementName=TrafficCheck, Mode=TwoWay}"
LandmarksVisible="{Binding IsChecked, ElementName=LandmarksCheck, Mode=TwoWay}"
Grid.RowSpan="3" Grid.ColumnSpan="3" x:Name="MyMap"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">

Now, watch carefully the binding written in TrafficFlowVisible property and LandMarksVisible property. All I did here is binded them with the appropriate checkbox IsChecked property and kept the binding mode two way. So, anytime these properties get changed even from codebehind we’ll see the change on the checkbox and vice versa. Traffic Flow is a cool feature actually. See the next gif to get an idea:

Map -7

Pretty cool huh!

Now you can even write it on the codebehind. You have to go to the properties of any of the checkbox and create the checked and unchecked property stub so you can toggle the maps TrafficFlowVisible feature. From code behind it will look like this:


private void TrafficCheck_Checked(object sender, RoutedEventArgs e)
{
MyMap.TrafficFlowVisible = true;
}

private void TrafficCheck_Unchecked(object sender, RoutedEventArgs e)
{
MyMap.TrafficFlowVisible = false;
}

and from the xaml:


<CheckBox x:Name="TrafficCheck" Content="Traffic Flow" Foreground="Green" Checked="TrafficCheck_Checked" Unchecked="TrafficCheck_Unchecked"></CheckBox>

I still prefer the Element binding because that is extremely easy. There’s one more property named PedestrianFeaturesVisible property. You can try that following the same way here.

Map Appearance:

Map Control is even cool enough to let you select the Map Appearance too! Let’s modify the bottom stackpanel so it can hold more buttons and added a grid with two columns. We added one combobox in each column so we can change map color scheme and map style.

So the bottom stackpanel looks like this now:


<StackPanel Grid.Row="2" Grid.Column="1">
<StackPanel  Orientation="Horizontal">
<CheckBox x:Name="TrafficCheck" Content="Traffic Flow" Foreground="Green"></CheckBox>
<CheckBox x:Name="LandmarksCheck" Content="Land Marks" Foreground="Green"></CheckBox>
</StackPanel>
<Grid Background="#00F9F9F9" >
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0" PlaceholderText="Map Color" x:Name="MapColorBox" Width="150"  Background="#FF23D1B1" SelectionChanged="MapColorBox_SelectionChanged" >
<ComboBoxItem  IsSelected="True" Content="Light" ></ComboBoxItem>
<ComboBoxItem Content="Dark" ></ComboBoxItem>
</ComboBox>
<ComboBox Grid.Column="1" PlaceholderText="Map Style" x:Name="MapStyleBox" Width="150"  Background="#FF23D1B1" HorizontalAlignment="Right" SelectionChanged="MapStyleBox_SelectionChanged" >
<ComboBoxItem  IsSelected="True" Content="None" ></ComboBoxItem>
<ComboBoxItem Content="Road" ></ComboBoxItem>
<ComboBoxItem Content="Aerial" ></ComboBoxItem>
<ComboBoxItem Content="AerialWithRoads" ></ComboBoxItem>
<ComboBoxItem Content="Terrain" ></ComboBoxItem>
</ComboBox>
</Grid>
</StackPanel>

We have added light and dark as the Map Color Scheme in the MapColorBox combobox and we have added 5 different Map Styles on MapStyleBox combobox. Each of the combobox has SelectionChanged event handler hooked up. Let’s see how MapColorBox_SelectionChanged looks like in MainPage.xaml.cs


        private void MapColorBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (MapColorBox!=null)
            {
                string selectedColor = ((ComboBoxItem)MapColorBox.SelectedItem).Content.ToString();

                switch (selectedColor)
                {
                    case "Light":
                        MyMap.ColorScheme = MapColorScheme.Light;
                        break;
                    case "Dark":
                        MyMap.ColorScheme = MapColorScheme.Dark;
                        break;
                    default:
                        MyMap.ColorScheme = MapColorScheme.Light;
                        break;
                }
            }

        }

You can see that based on the SelectedItem on MapColorBox combobox we have assigned MapColorScheme of MyMap to MapColorScheme.Light or MapColorScheme.Dark

Map -8

Now, let’s focus on the MapStyleBox_SelectionChanged in the MainPage.xaml.cs


        private void MapStyleBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (MapStyleBox != null)
            {
                string selectedStyle = ((ComboBoxItem)MapStyleBox.SelectedItem).Content.ToString();

                switch (selectedStyle)
                {
                    case "None":
                        MyMap.Style = MapStyle.None;
                        break;
                    case "Road":
                        MyMap.Style = MapStyle.Road;
                        break;
                    case "Aerial":
                        MyMap.Style = MapStyle.Aerial;
                        break;
                    case "AerialWithRoads":
                        MyMap.Style = MapStyle.AerialWithRoads;
                        break;
                    case "Terrain":
                        MyMap.Style = MapStyle.Terrain;
                        break;
                    default:
                        MyMap.Style = MapStyle.None;
                        break;
                }
            }
        }

This looks like the previous one too. All we did here is based on the MapStyleBox SelectedItem we have assigned MyMap.Style to appropriate MapStyle.

Map -9

Change Map Tile Source:

Now usually what we see is either bing or here maps on Windows Phone 8.1 Map Control. In some cases people might need to access different tile source like openstreet map. For the ones who doesn’t understand what a tilesource is, every map system is nothing but a series of square shaped images/tiles shown for a range of geo coordinate boundary.  It’s a grid of images shown based on the maps zoom level. When you zoom out or zoom in or roam around in the map, based on your X,Y and zoom level the map requests tiles of images to show you.

If you want to add/change a tiles layer, you have to change the TileSources collection of the map control. You can set the Zindex, tile pixel size and visibility. You can even forbid/allow stretching of the tiles while a higher resolution tile is being downloaded. You can define layer type of the tile source like BackgroundReplacement, BackgroundOverlay and RoadOverlay.

Let’s replace our default map tiles with openstreetmap tiles.


private void SetTileSourceToOSM()
{
var httpsource = new HttpMapTileDataSource("http://a.tile.openstreetmap.org/{zoomlevel}/{x}/{y}.png");
var tilesource = new MapTileSource(httpsource)
{
Layer = MapTileLayer.BackgroundReplacement
};
MyMap.Style = MapStyle.None;
MyMap.TileSources.Add(tilesource);
}

Now all we have to do is call this on our OnNavigatedTo method


protected override void OnNavigatedTo(NavigationEventArgs e)
{
SetTileSourceToOSM();
GetMyLocation();

}

And after the app is loaded, your map will look like this. But remember as we set our layer to BackgroundReplacement we will not have any kind of map styles or other features like TrafficFlow anymore.

You will also observe the loading of the map is pretty slow as the tiles are loaded from one source. So, we can balance the load by pointing to three different domains so the maps may load faster. All we have to do is rotate the subdomain of openstreet map in between a,b and c


private void SetTileSourceToOSM()
{
var next = "a";
var httpsource = new HttpMapTileDataSource("http://a.tile.openstreetmap.org/{zoomlevel}/{x}/{y}.png");

httpsource.UriRequested += (src, args) => {
next = GetNextDomain(next);
args.Request.Uri = new Uri("http://" + next + ".tile.openstreetmap.org/" +
args.ZoomLevel + "/" + args.X + "/" + args.Y + ".png");

};

var tilesource = new MapTileSource(httpsource)
{
Layer = MapTileLayer.BackgroundOverlay
};

MyMap.Style = MapStyle.None;
MyMap.TileSources.Add(tilesource);
}

private string GetNextDomain(string next)
{
string[] domains={"a", "b", "c"};

for(int count=0; count<domains.Length; count++)
{
if (domains[count] == next)
return domains[(count + 1) % domains.Length];
}

return next;
}

Here in the GetNextDomain method you will see that all it’s doing is it is actually rotating between the three subdomains of openstreet map.

And it looks like below:

Map -12

Map Events:

Maps in Windows Phone 8.1 comes with much easier touch events. Touch events now comes along with GeoPoint and local UI coordinates related to the touch point. All these comes along with MapTapped, MapDoubleTapped and MapHolding events.  To check if a location is visible on current map window you can use IsLocationInView().

We are going to try the MapTapped event for now. Select the MapControl, go over properties, go to event handlers and double click on the MapTapped event handler to create the method stub for that.

Now let’s go ahead and write the method down:


private async void MyMap_MapTapped(MapControl sender, MapInputEventArgs args)
{
Geopoint point = new Geopoint(args.Location.Position);

MapLocationFinderResult FinderResult =
await MapLocationFinder.FindLocationsAtAsync(point);

String format = "{0}, {1}, {2}";

if (FinderResult.Status == MapLocationFinderStatus.Success)
{
var selectedLocation=FinderResult.Locations.First();

string message= String.Format(format, selectedLocation.Address.Town, selectedLocation.Address.District, selectedLocation.Address.Country);
await ShowMessage(message);

}

}

Now here we have a sample reverse geocode query. And you can definitely see this is much easier here. You have to use MapLocationFinder class and it has a FindLocationsAtAsync method to get back with a geocoordinate based on your tap on the map. Actually it usually returns a list and we picked the first on the list and printed out the town, district and country on a messagedialog.

you can definitely check how the thing works on the phone

Map -11

 

 

Authenticating a Maps App:

The last thing that is left to do is authenticating a map app. You will see unless you provide a map control a map service AuthenticationToken it keeps asking it in the bottom of the map.

The details on that process is available here.

Our next tutorial would be on Routing , GeoFencing and Maps using MVVM.

The source code is uploaded here!

Stay frosty!

 

Reading and Writing to the Console

In the previous article we discussed about the basic structure of a C# program. Today we will see reading and writing operation to the console. We will see a little more interactive sample program than the previous today. Our program will ask the user his/her name and then print a welcome message with the name of the user which he/she just enter.

To write something to the console we have two methods under System namespace, one is Write and the other is WriteLine. Only the difference between these two is, if we use WriteLine then after writing something to the console it will print a new line also but in Write method it will just print something. No new line will be printed here.

For an example if we write in the main method Console.Write(“Hello World ”); then the output should be as follows-

Hello World press any key to continue

The line “press any key to continue” indicates that the program is terminated. Instead of this method if we use Console.WriteLine(“Hello World ”); then the output should be as follows-

Hello World

press any key to continue

Here we can see that the line “press any key to continue” is in a new line. So the method Writeline prints a new line after writing something to the console.

Similarly there are to methods for reading something in the console, one is Read and the other is ReadLine. The Read method read integer type from the console and the Readline method read string type from the console. So if we write Console.ReadLine() then we have to store the returned result in a string type variable so that we can use it later in the program.

Now let’s see the code our sample program. It is as follows-

using System;
class Program
{
   static void Main()
    {
        Console.WriteLine("What is your name?");
        string name = Console.ReadLine();
        Console.WriteLine("Welcome "+ name);
    }
}

Here we can see in the MAIN method first we are printing a message asking the user’s name. Then when our next line of code executed it waits for the user input that is our read operation from the console. When the user enters something and press the Enter button then Console.Readline methos reads what is entered in the console and return it as a string type. Here we store the returned string in a string type variable named name. So what user entered in the console now stored in the variable. Then in the next line we write in the console “Welcome “concatenated with the name of the user. Here we are concatenating two string- One is “Welcome ” and the other is string type variable called name with the “+” sign in the WriteLine method.
There are actually two ways of writing something in the console. They are-
• Concatenation
• Place holder syntax
We already have seen the concatenation method of writing something to the console. Now we will see the place holder syntax in the same program. If we want to use place holder syntax in the same program then the code should be as follows-

using System;
class Program
{
   static void Main()
    {
        Console.WriteLine("What is your name?");
        string name = Console.ReadLine();
        Console.WriteLine("Welcome {0}",name);
    }
}

Here we can see in case of “+” operator we use “{0}” in the string with Welcome. This is called the place holder. When we run the program, the value of the variables that we pass after comma in the WriteLine method replaces the place holder. So if we run this piece of code we will see the same result here.
The place holder syntax is more preferable than the Concatenation process. To see how place holder syntax gives more capability let’s modify the above program. Now we will ask the user to enter his/her first name then after reading the first name we will ask for last name and after reading that we will print the first name and last name separated by a comma with the welcome message. To do that the program should be as follows –

using System;
class Program
{
   static void Main()
    {
        Console.WriteLine("What is your first name?");
        string firstname = Console.ReadLine();
        Console.WriteLine("What is your last name?");
        string lastname = Console.ReadLine();
        Console.WriteLine("Welcome {0},{1}",firstname,lastname);
    }
}

Here in the code we can see there are two place holders and there are two string type variable as well to store the first name and last name of user. When we write the welcome message in WriteLine method we use two placeholder and two variable to replace the place holder. In the same way we can use as many as place holders we required. We just have to surround the number of that place holder with curly braces. That’s why place holder syntax is more preferable than the concatenation method.

Free open source UI toolkits you should check out for your Windows Phone / Windows Store apps

<This post will be updated in time. Kindly check back for newer entries>

When windows phone hit it’s 8.1 upgrade from Windows Phone 8 version, it shifted itself up from silverlight to WinRT kernel. Some of the hardcore Windows Phone fanatics like me was pretty sad because we lost access to our favourite UI toolkits by then. Although a lot of the expected UI controls came through in the sdk itself, still something was missing. This is a log of a set of UI toolkits you should discover when you are making your Windows Phone/Universal Apps.

1. SlideView: A Facebook like panel for Windows Phone: Ever wonder how a android like SlideView would look like in your native Windows Phone? Check this toolkit out Today!

2. WinRT XAML Toolkit:  The perfect set of helpers, extensions and mostly all of the controls from Windows Phone Toolkit has been ported here. It has Calendar, Gauge and other data visualization tool too.

3. MyToolkit for .NET:  Are you a big fan Windows App Studio? Do you know what has been used inside to facilitate all that? Meet MyToolkit. From MVVM toolkit to DataGrid everything is here, possibly everything. It even supports Xamarin projects too. 🙂

4.ExpanderRT: ExpanderRT is the ExpanderView port from Windows Phone 8 to WinRT. Missing the great control, don’t! 😉

I will continuously keep updating this blog post as soon as I find a new toolkit to add. 😉

Saving a SpeechSynthesis Audio in a windows store/phone app

Usually after doing a little speech synthesizing in our phone we usually stumble on one question, can I save this stream?
Luckily you can! All you gotta do is pull this out of your sleeve. 🙂

 


var synth = Windows.Media.SpeechSynthesis.SpeechSynthesizer();

SpeechSynthesisStream speechstream = await synth.SynthesizeTextToStreamAsync("Hello People");

using(var reader = new DataReader(speechstream))
{

await reader.LoadAsync((uint)stream.Size);

IBuffer buffer = reader.ReadBuffer((uint)stream.Size);

await FileIO.WriteBufferAsync(outputFile, buffer);

}

And, you’re done! Your file would be a .wav file of course.

Windows Phone 8.1 for Newbies – Navigation of Windows Phone 8.1 – Frame, Page and SuspensionManager

Windows Phone for Newbies সিরিজে এবার আমাদের বিষয় Windows Phone 8.1 এর নেভিগেশন মডেল। আমরা আজকে দেখবো আপনি একটি নতুন একটি অ্যাপ এ নেভিগেশন কিভাবে handle করবেন। আরো দেখবো আসলে নেভিগেশন কি করে হয়।

শুরুতে আমাদের দরকার একটি নতুন অ্যাপ। তো চলে যান আপনার Visual Studio তে। আমি ব্যবহার করছি Visual Studio 2013 Community Edition. আসুন খুলে নেই নতুন একটি প্রজেক্ট। চলে যান ফাইল -> নিউ প্রজেক্ট

Navigation-1

এখানে দেখতে পাবেন আপনার জন্যে বেশ কয়েকটি প্রজেক্ট টেমপ্লেট আছে। Blank, Pivot, Hub app এই তিনটি টেমপ্লেট আছে। আপনি যদি Pivot অথবা hub টেমপ্লেট সিলেক্ট করেন তাহলে NavigationHelper, SuspensionManager এর মতো Helper Class গুলো পেয়ে যাবেন। কিন্তু এখনকার জন্যে সেগুলো আপনার জন্যে একটু বেশি হয়ে যাবে। আসুন আমরা blank template নিয়ে এগিয়ে যাই।

তো তৈরী করে ফেলুন একটি Blank App. আমি আগেই বলেছি আমরা কিছু Helper Class পাবোনা এই টেমপ্লেট এ। একটি ছোট হ্যাক আছে সেগুলো এই টেমপ্লেট এ নিয়ে আসার। প্রথমে আপনি MainPage.xaml পেজটি Solution explorer থেকে delete করে দিন। এবার Solution Explorer এ সলুশ্যন এর নাম এর ওপরে right click করে Add-> New Item এ চলে যান।

Navigation-2

এরপর সিলেক্ট করুন Basic Page. দেখবেন নিচের মতো একটি পপ আপ ভেসে উঠবে।

Navigation-3

Navigation-4

এখন দেখবেন আপনার প্রজেক্টের Common Folder এ নিচের class গুলো যোগ হয়ে গিয়েছে।

Navigation-5

আমাদের আজকের বিষয় যেহেতু Navigation আমরা শুধু NavigationHelper আর SuspensionManager নিয়ে কথা বলবো।

SuspensionManager এবং Frame:

Windows Phone 8.1 এ আপনার UI টি আসলে বসে থাকে একটি Frame UI control এর উপর এবং এই Frame টি জানে কিভাবে এক Page হতে অন্য Page এ নেভিগেট করতে হয়। এখানেই উইন্ডোজ ফোন ৮.১ উইন্ডোজ ফোন ৮ থেকে আলাদা। এখানে একটি page এ একাধিক Frame থাকতে পারে। আপনি চাইলেই পারেন একটি Single Page Application বানাতে। এবং যেহেতু একটি Frame এ আপনার Navigation History (কোন পেইজ থেকে কোন পেইজে গিয়েছেন তার লিস্ট) থাকে সেহেতু একটি Page এ multiple frame থাকলে multiple navigation history ও থাকতে পারে। তবে তার কথায় এখন যাচ্ছিনা।

আসুন আমরা দেখি Frame কোথায় তৈরী হয়। এটি তৈরী হয় Application.OnLaunched (app.xaml.cs) এ। এটি Window.content property তে দেখে যে main UI টি তৈরী হয়েছে কিনা। না হলে তৈরী করে নেয়। এভাবেই আপনার root frame তৈরী হয়।

protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

            Frame rootFrame = Window.Current.Content as Frame;

            // Do not repeat app initialization when the Window already has content,
            // just ensure that the window is active
            if (rootFrame == null)
            {
                // Create a Frame to act as the navigation context and navigate to the first page
                rootFrame = new Frame();

                // TODO: change this value to a cache size that is appropriate for your application
                rootFrame.CacheSize = 1;

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    // TODO: Load state from previously suspended application
                }

                // Place the frame in the current Window
                Window.Current.Content = rootFrame;
            }

            if (rootFrame.Content == null)
            {
                // Removes the turnstile navigation for startup.
                if (rootFrame.ContentTransitions != null)
                {
                    this.transitions = new TransitionCollection();
                    foreach (var c in rootFrame.ContentTransitions)
                    {
                        this.transitions.Add(c);
                    }
                }

                rootFrame.ContentTransitions = null;
                rootFrame.Navigated += this.RootFrame_FirstNavigated;

                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                if (!rootFrame.Navigate(typeof(MainPage), e.Arguments))
                {
                    throw new Exception("Failed to create initial page");
                }
            }

            // Ensure the current window is active
            Window.Current.Activate();
        }

এখন একটু ভালোমতো খেয়াল করে দেখবেন frame একটি content control (এর একটি content property) আছে আর কি। এর বেশ কিছু method আছে যেমন (Navigate, CanNavigate) এবং এটি আপনার Navigation BackStack manage করে। কিন্তু যে দুটো ফাংশন নিয়ে আমি কথা বলতে চাই তা হচ্ছে

  • GetNavigationState
  • SetNavigationState

মনে করি আমাদের অ্যাপ এ ৩টি পেইজ আছে, প্রত্যেক পেইজে navigate করার সময় একটি param পাঠানো যায়। তাহলে navigation stack টা দাঁড়ায় এরকম Page 1 ( param 1 ) –> Page 2 ( param 2 ) –> Page 3 ( param 3 )

এখন আমরা যদি চাই কোন Page এর Frame এর state জানতে আমরা GetNavigationState() ব্যবহার করতে পারি। আমরা চাইলে Frame টি destroy করতে পারি এবং নতুন করে recreate করতে পারি। এবং চাইলে Frame টি যেখানে ছিলো সেইখানে তাকে রেখে আসতে পারি SetNavigationState() ফাংশনটি ব্যবহার করে।

যদি আমাদের navigation parameter এ সব দেয়া থাকে (যেটা navigate করার সময় আমরা পাঠিয়েছিলাম) তাহলে আমরা যে কোন Frame যে কোন অবস্থা থেকে পুনরায় তৈরী করতে পারবো। এটি কাজে লাগে তখন যখন আমাদের কোন অ্যাপ OS থেকে terminate হয়ে যায় এবং আমরা অ্যাপটিকে ঠিক আগের জায়গা থেকে শুরু করাতে চাই। আর এই কাজটি করতে পারে SuspensionManager class.

এখন SuspensionManager এ আমাদের Frame restore করতে চাইলে একে জানতে হবে Frame কোনটি। তাই Grid, Hub এইসব প্রজেক্ট টেমপ্লেট এ SuspensionManager এ Frame register করা থাকে। আপনি যদি blank template ব্যবহার করে থাকেন তাহলে আপনার OnLaunched মেথডে নিচের কোডটুকু যোগ করে ফেলুন।


Frame rootFrame = Window.Current.Content as Frame;

// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();

// MT: Register the Frame with the SuspensionManager.
SuspensionManager.RegisterFrame(rootFrame, "rootFrameKey");

তাহলে আসুন দেখি আমরা এতোক্ষণ কি দেখলাম।

navigation -5

এই register করার মাধ্যমে SuspensionManager জেনে নেয় এই Frame টি তে প্রয়োজনের সময় সে ফেরত আসতে পারবে।

SuspensionManager কিভাবে Frame restore করে

আসুন দেখি কিভাবে app terminate হয়ে যাবার পর ও আমরা একই Frame এ ফেরত যেতে পারি। আপনার Application.OnLaunched override এ এই কোডটুকু already আছে:


if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}

সাথে এইটুকু যোগ করে নিলেই হলো। এখন আপনার অ্যাপ Terminate হয়ে গেলেও user তার আগের Frame এ ফেরত যেতে পারবে। News app এর feature হিসেবে চমৎকার।


if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
await SuspensionManager.RestoreAsync();
}

এটি একটি async call কারণ SuspensionManager আপনার ফোনের Storage এ গিয়ে Frame navigation history খুঁজে বের করে এবং Frame টি কে SetNavigationState method এর মাধ্যমে তার পুরনো জায়গায় ফেরত দিয়ে আসে।

navigation - 6

মনে রাখবেন সব সময় এই কাজটি করবার দরকার নেই । অনেক আগে একটি অ্যাপ বন্ধ হয়ে গেলে সেটিকে আবার সেই পুরনো স্টেট এ নিয়ে যাবার দরকার নেই। আপনি চাইলেই এরকম একটি কোড সেগমেন্ট রাখতে পারেন যেখানে একটি নির্দিষ্ট সময় বা ইউজার বললে অ্যাপটি আর Frame restore করবেনা।

মজার ব্যাপার হচ্ছে restore করতে হলে state save করতে হয়। আমরা register এবং restore করেছি। save করিনি। state save না করলে restore কি করে হবে বলুন? 🙂

SuspensionManager কিভাবে App Suspension এর সময় State save করে

যখনি আপনার অ্যাপ টি Suspend হচ্ছে (terminate নয়) তখন ই আপনার অ্যাপটির SuspensionManager এর state disk এ save করলে পরে আপনি অ্যাপটি চালু করলে সে আবার পুনরায় আগের অবস্থায় Frame টি কে নিয়ে যাবে।

navigation - 7

যেহেতু এটি Suspension এর ইস্যু তাই আমাদের Application.OnSuspending handler লিখতে হবে এবং এটিতে আপনি Frame State save করতে পারেন এভাবে:


private async void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();

await SuspensionManager.SaveAsync();

deferral.Complete();
}

উপরের ছবিটি খেয়াল করে দেখলে বুঝবেন SuspensionManager একটি Global set of state রাখে নিজের কাছে যেটি আপনি SuspensionManager.SessionState হতে ব্যবহার করতে পারেন। এই Global State এর মধ্যে থাকে একটি Dictionary থাকে যাতে প্রতিটি Frame থাকে এবং তার মধ্যে প্রতিটি Page এর State এর একটি Dictionary থাকে যা NavigationHelper class ব্যবহার করে। আমরা এটি নিয়ে একটু পরে দেখবো।

কিছু নতুন Page যোগ করা:

আমি জানি অনেকেই সরাসরি এই জিনিসটি দেখতে চান কিন্তু যেহেতু Windows Phone 8.1 একটু আলাদা Windows Phone 8 থেকে তাই Frame এবং Page এর ব্যপারে কিছু না বললে ই নয়। আপনি যদি পুরোটা আগে পড়ে থাকেন তাহলে আপনি অবশ্যই উইন্ডোজ ফোন ৮.১ এর নেভিগেশন মডেল বেশ ভালোভাবে জানেন।

আমরা চলে যাই আবার Visual Studio 2013 এ। আমরা উপরে লেখা উপায়ে আরো দুটি Basic Page (Blank page নয়) যোগ করবো। প্রতিটি ক্ষেত্রেই আমি Add New Item dialog টি ব্যবহার করেছি।

আমার যোগ করা Page গুলোর নাম SecondPage এবং ThirdPage

আমার MainPage.xaml টি নিচের মতো:


<Page x:Name="pageRoot"
x:Class="BlankApp.SecondPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BlankApp"
xmlns:common="using:BlankApp.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="Green">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition />
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock x:Name="pageTitle"
Style="{StaticResource HeaderTextBlockStyle}"
Grid.Column="1"
IsHitTestVisible="false"
TextWrapping="NoWrap"
VerticalAlignment="Bottom"
Margin="0,0,30,40" />
</Grid>
<StackPanel Grid.Row="1"
Margin="120,0,0,0">
<TextBox x:Name="txtMainPageOne"
Text="Not Set" />
<Button Content="Navigate Second Page"
Click="OnNavigateSecondPage" />
</StackPanel>
</Grid>
</Page>

সবচেয়ে কাজে লাগার Method টি হচ্ছে OnNavigateSecondPage যেটি আপনাকে Second Page এ নিয়ে যাবে।


private void OnNavigateSecondPage(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(SecondPage), this.txtMainPageOne.Text);
}

খেয়াল করে দেখবেন txtMainPageOne টেক্সটবক্স এ যা ছিলো তা আমি parameter হিসেবে SecondPage.xaml এ পাঠিয়ে দিয়েছি।

SeondPage.xaml দেখতে এরকম:


<Page x:Name="pageRoot"
x:Class="BlankApp.SecondPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BlankApp"
xmlns:common="using:BlankApp.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="Green">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition />
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock x:Name="pageTitle"
Style="{StaticResource HeaderTextBlockStyle}"
Grid.Column="1"
IsHitTestVisible="false"
TextWrapping="NoWrap"
VerticalAlignment="Bottom"
Margin="0,0,30,40" />
</Grid>
<StackPanel Grid.Row="1"
Margin="120,0,0,0">
<TextBox x:Name="txtSecondPageOne"
Text="Not Set" />
<Button Content="Navigate Thid Page"
Click="OnNavigateThirdPage" />
</StackPanel>
</Grid>
</Page>

তার মানে MainPage থেকে পাঠানো parameter আমি access করতে পারবো navigationHelper_LoadState method এ।


private void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
this.pageTitle.Text = (string)e.NavigationParameter;
}

private void OnNavigateThirdPage(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(ThirdPage), this.txtSecondPageOne.Text);
}

দেখতেই পাচ্ছেন SeconPage থেকে ThirdPage এও যাবার সময় আমি একটি parameter পাঠিয়ে দিচ্ছি যা txtSecondPageOne textbox এ লেখা। এবং NavigationHelper class এখন আমাদের কাজে লাগলো কারণ এটি মাত্রই আমাদের Navigation Parameter e হতে MainPage.xaml হতে পাঠানো parameter টি লোড করলো।

আমাদের ThirdPage.xaml টি হলো:


<Page x:Name="pageRoot"
x:Class="BlankApp.ThirdPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:BlankApp"
xmlns:common="using:BlankApp.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">

<Grid Background="Orange">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition />
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<TextBlock x:Name="pageTitle"
Style="{StaticResource HeaderTextBlockStyle}"
Grid.Column="1"
IsHitTestVisible="false"
TextWrapping="NoWrap"
VerticalAlignment="Bottom"
Margin="0,0,30,40" />
</Grid>
</Grid>

</Page>

এখন খেয়াল করে দেখবেন আপনার অ্যাপটি নেভিগেট করার সময় প্যারামিটার ঠিকমতো পাস করে নিয়ে যাচ্ছে কিন্তু ব্যাক বাটন চাপলে অ্যাপটি বন্ধ হয়ে যাচ্ছে।

navigation - 8

 

এর কারণ এবং বের হবার উপায় আমরা দেখবো পরের পোস্ট এ। সেখানে আরো দেখবো কিভাবে পেজ ক্যাশ করতে হয়। 🙂

 

 

Making a game controller out of your Windows Phone using VJoy – Part 1.

I know the title sounds really intriguing. Truth to be told it is indeed intriguing. And as it goes the outcome is pretty intriguing too.

The whole tutorial would take a bit time to get inside your head, so Im going to take it step by step.

Step 1: The Bluetooth Server

To have this whole thing going we will need a bluetooth server going. To facilitate a very very simple bluetooth server we are going to use a Windows Store app. So I jotted down a very very simple GUi for the server first.


<Page
    x:Class="BluetoothServer.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:BluetoothServer"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel VerticalAlignment="Bottom" Margin="0,0,0,150" >
            <TextBlock Name="StatusText" FontSize="25" Margin="35,0,35,57" TextAlignment="Center"></TextBlock>
            <Button Content="Initiate Server"  Name="ServerToggleButton" HorizontalAlignment="Center" Click="Button_Click" />
            
        </StackPanel>
    </Grid>
</Page>

The only input mechanism I have in here is a textbox and a button. You pick the button to initiate a server and that’s it. All the code that has been used here are actually very very raw and coded in a hurry. So try to get the gist of the idea first so you can get yourself started.

The first method we are going to put in the back is an Initialization method for the server. This would actually Initialize the Bluetooth server we are going to use.


private StreamSocket socket;

private DataWriter writer;
private RfcommServiceProvider rfcommProvider;
private StreamSocketListener socketListener;

public async void InitializeRfCommServer()
{
            try
            {
                rfcommProvider = await RfcommServiceProvider.CreateAsync(RfcommServiceId.FromUuid(RfcommServiceUuid));

                // Create a listener for this service and start listening
                socketListener = new StreamSocketListener();
                socketListener.ConnectionReceived += OnConnectionReceived;

                await socketListener.BindServiceNameAsync(rfcommProvider.ServiceId.AsString(),
                   SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);

                 // Set the SDP attributes and start Bluetooth advertising
                InitializeServiceSdpAttributes(rfcommProvider);
                rfcommProvider.StartAdvertising(socketListener);

                StatusText.Text="Listening for incoming connections";
                ServerInitiated = true;

            }
            catch(Exception e)
            {
                StatusText.Text = e.Message;
                
                ServerInitiated = false;
            }
}

Here, Windows.Devices.Bluetooth.Rfcomm comes in extremely handy as RfcommServiceProvider is the prefect class to start a RFComm session. But before all that you are going to need some basic stuff. First you will need a service GUID. You can make a GUID from any place but I suggest to try make an unique one. Here I used something I generated from a site online but you can definitely try your way. Then you are going to need a SdpServiceNameAttributeId and SdpServiceNameAttributeType. SdpServiceNameAttributeType is actually a 8 bit scenario where the least significant 3 bits contains attribute size and the most significant 5 bits contains the attribute type value. And last but not the least you will need a service name too.


        private static readonly Guid RfcommServiceUuid = Guid.Parse("482af5ed-3faf-4a51-9dd0-718c85aa64d0");
        private const UInt16 SdpServiceNameAttributeId = 0x100;
        private const byte SdpServiceNameAttributeType = (4 << 3) | 5;
        private const string SdpServiceName = "Bluetooth Rfcomm Listening Service for VJoy";

Please keep these in mind because we are going to need these in the client too. And you also have to define these in your Package.appxmanifest too to make the server authorized to use the bluetooth in your pc.


<m2:DeviceCapability Name="bluetooth.rfcomm">
      <m2:Device Id="any">
        <m2:Function Type="serviceId:34B1CF4D-1069-4AD6-89B6-E161D79BE4D8"/>
      </m2:Device>
    </m2:DeviceCapability>

After all these are done and dusted, let’s move on with initializing the bluetooth server. The next thing that comes is a StreamSocketListener. And it’s job is kind of explained in it’s name. It will serve as our stream listener that would be recieved from the clients. Thus it has a ConnectionReceived event that has to be populated too.

The next thing to do would be bind the service name. Our StreamSocketListener object has a BindServiceNameAsync method to do so with serviceID and an option to take as a parameter. I defined SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication because I didnt want much security over the communication. You can explore other options if you want to impose some security measures.

Next comes InitializeServiceSdpAttributes(rfcommProvider) and he looks like the following:


        private void InitializeServiceSdpAttributes(RfcommServiceProvider rfcommProvider)
        {
            var sdpWriter = new DataWriter();

            // Write the Service Name Attribute.

            sdpWriter.WriteByte(SdpServiceNameAttributeType);

            // The length of the UTF-8 encoded Service Name SDP Attribute.
            sdpWriter.WriteByte((byte)SdpServiceName.Length);

            // The UTF-8 encoded Service Name value.
            sdpWriter.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
            sdpWriter.WriteString(SdpServiceName);

            // Set the SDP Attribute on the RFCOMM Service Provider.
            rfcommProvider.SdpRawAttributes.Add(SdpServiceNameAttributeId, sdpWriter.DetachBuffer());   
        }

The purpose of this method is definitely putting the SdpRawAttributes in place by using a DataWriter. Here we put in possibly everything we defined before for our bluetooth device.

The only thing we need to do just before calling StartAdvertising, we need to define our ConnectionReceived event.


private async void OnConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
        {
            try
            {
                socketListener.Dispose();
                socketListener = null;

                socket = args.Socket;

                writer = new DataWriter(socket.OutputStream);

                var reader = new DataReader(socket.InputStream);
                bool remoteDisconnection = false;

                bool res;
                while (true)
                {
                    uint readLength = await reader.LoadAsync(sizeof(uint));
                    if (readLength < sizeof(uint))
                    {
                        remoteDisconnection = true;
                        break;
                    }
                    uint currentLength = reader.ReadUInt32();

                    readLength = await reader.LoadAsync(currentLength);
                    if (readLength < currentLength)
                    {
                        remoteDisconnection = true;
                        break;
                    }
                    string message = reader.ReadString(currentLength);
                }

                reader.DetachStream();
                if (remoteDisconnection)
                {
                    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
                    {
                        Disconnect();
                    });
                }

            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

This is where the server keeps looping for message and Im not kidding. You will find a while(true) inside and what it does is it keeps reading data from the socket until someone pulls the trigger or somehow the connection gets jeopardized. You will see even a basic check on buffer length triggers the server to stop. And in any case of an exception an async Disconnect() is due.

And Disconect() is nothing but as simple as the following:


        private void Disconnect()
        {
            if (rfcommProvider != null)
            {
                rfcommProvider.StopAdvertising();
                rfcommProvider = null;
            }

            if (socketListener != null)
            {
                socketListener.Dispose();
                socketListener = null;
            }

            if (writer != null)
            {
                writer.DetachStream();
                writer = null;
            }

            if (socket != null)
            {
                socket.Dispose();
                socket = null;
            }

            ServerInitiated = false;
        }

Now , we can trigger this one from a toggle button like the following:

private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (ServerInitiated)
            {
                Disconnect();
                ServerToggleButton.Content = "Initiate Server";
            }
            else
            {
                InitializeRfCommServer();
                ServerToggleButton.Content = "Disconnect Server";
               
            }
        }

But the thing is that’s just a bluetooth server. To test it out you will need a bluetooth client too.

Step 2: The Bluetooth Client

The bluetooth client is essentially a Windows Phone app. I couldve showed the XAML here but that wouldn’t look that simple. In spite of doing that, let’s break down what do we have to do now. We have to:

1. Connect to a paired device. (Yes, you have to have your devices paired)

2. Search the bluetooth service we are looking for and if we find any, we’d give a list to pick

3. Use that selected device and send data to it .

Here, definitely the paired device is a device that has our server running.

Let’s assume we have a run button that starts the search for the paired devices with the desired service. Remember I said that we will need our service GUID and other identifications to make this work even from the client side because it has to know which service it is feeding itself to.

Thus, this definitions first come in place:

private static readonly Guid RfcommChatServiceUuid = Guid.Parse("482af5ed-3faf-4a51-9dd0-718c85aa64d0");

// The Id of the Service Name SDP attribute
private const UInt16 SdpServiceNameAttributeId = 0x100;
private const byte SdpServiceNameAttributeType = (4 << 3) | 5;

private StreamSocket chatSocket;
private DataWriter chatWriter;
private RfcommDeviceService chatService;
private DeviceInformationCollection chatServiceInfoCollection;

and the run method looks like the following:


private StreamSocket chatSocket;
private DataWriter chatWriter;
private RfcommDeviceService chatService;
private DeviceInformationCollection chatServiceInfoCollection;

private async void RunButton_Click(object sender, RoutedEventArgs e)
{
// Find all paired instances of the Rfcomm chat service
chatServiceInfoCollection = await DeviceInformation.FindAllAsync(
RfcommDeviceService.GetDeviceSelector(RfcommServiceId.FromUuid(RfcommChatServiceUuid)));

if (chatServiceInfoCollection.Count > 0)
{
List<string> items = new List<string>();
foreach (var chatServiceInfo in chatServiceInfoCollection)
{
items.Add(chatServiceInfo.Name);
}
cvs.Source = items;
ServiceSelector.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
else
{
Debug.WriteLine("No chat services were found. Please pair with a device that is advertising the chat service.");

}
}

You can definitely understand DeviceInformationCollection does all the hard work here finding the device and the next thing to do would be selecting one and using it. After selecting we will start our chat session and indulge ourselves on a loop so we can keep receiving messages sent from the server, actually in our case thats not necessary, but still it’s nicer to have it on the place.


private async void ServiceList_Tapped(object sender, TappedRoutedEventArgs e)
{
try
{
RunButton.IsEnabled = false;
ServiceSelector.Visibility = Windows.UI.Xaml.Visibility.Collapsed;

var chatServiceInfo = chatServiceInfoCollection[ServiceList.SelectedIndex];
chatService = await RfcommDeviceService.FromIdAsync(chatServiceInfo.Id);

if (chatService == null)
{
Debug.WriteLine(
"Access to the device is denied because the application was not granted access",
);
return;
}

var attributes = await chatService.GetSdpRawAttributesAsync();
if (!attributes.ContainsKey(SdpServiceNameAttributeId))
{
Debug.WriteLine(
"The Chat service is not advertising the Service Name attribute (attribute id=0x100). " +
"Please verify that you are running the BluetoothRfcommChat server.",
);
return;
}

var attributeReader = DataReader.FromBuffer(attributes[SdpServiceNameAttributeId]);
var attributeType = attributeReader.ReadByte();
if (attributeType != SdpServiceNameAttributeType)
{
Debug.WriteLine(
"The Chat service is using an unexpected format for the Service Name attribute. " +
"Please verify that you are running the BluetoothRfcommChat server.",);
return;
}

var serviceNameLength = attributeReader.ReadByte();

// The Service Name attribute requires UTF-8 encoding.
attributeReader.UnicodeEncoding = UnicodeEncoding.Utf8;
ServiceName.Text = "Service Name: \"" + attributeReader.ReadString(serviceNameLength) + "\"";

lock (this)
{
chatSocket = new StreamSocket();
}

await chatSocket.ConnectAsync(chatService.ConnectionHostName, chatService.ConnectionServiceName);

chatWriter = new DataWriter(chatSocket.OutputStream);
ControlBox.Visibility = Visibility.Visible;

DataReader chatReader = new DataReader(chatSocket.InputStream);
ReceiveStringLoop(chatReader);
}
catch (Exception ex)
{
RunButton.IsEnabled = true;
Debug.WriteLine("Error: " + ex.HResult.ToString() + " - " + ex.Message,);
}
}

The very basic thing it does it starts getting device info out and creates a String Loop that listens for a string. I wont go with that details rather I’d show how to send a bluetooth data through it.


private async void SendMessage(string message)
{
try
{
chatWriter.WriteUInt32((uint)message.Length);
chatWriter.WriteString(message);

await chatWriter.StoreAsync();

}
catch (Exception ex)
{
//MainPage.Current.NotifyUser("Error: " + ex.HResult.ToString() + " - " + ex.Message,
//    NotifyType.StatusMessage);
}
}

For the first part I’d stop here now, in the next two parts we are going to see how we are going to feed this data to vjoy and use our phone as a game controller. 🙂

গ্রাফ সার্চ – এ* সার্চ

গ্রাফ সার্চ নিয়ে কচকচানো শুরু করার কারণ আমি বেশ কয়েকদিন আগে একটি অ্যাপ এর কাজে এটি ব্যবহার করেছিলাম। ভাবলাম লিখে ফেলা উচিত, তাই শুরু করলাম। লেখাটা পড়ার আগে আপনার যা যা জানা থাকলে ভালো তা হচ্ছে।

  1. বেসিক গ্রাফ (http://en.wikipedia.org/wiki/Graph_%28mathematics%29)
  2. গ্রাফ ট্রাভের্সাল (http://en.wikipedia.org/wiki/Graph_traversal)

গ্রাফ সার্চের অসংখ্য মেথডের মধ্যে এ* সার্চ বেশ পরিচিত হবার কারণ এটি অনেক জায়গায় বিশাল কানেক্টেড একটি গ্রাফ এর এক প্রান্ত থেকে অন্য প্রান্তে যাবার রাস্তা খুঁজে বের করার জন্যে ব্যবহৃত হয়। যেসব জায়গায় এটি সবচেয়ে বেশি ব্যবহৃত হয় তা হচ্ছে:

  1. রুবিক কিউব সলভ করার জন্যে
  2. ম্যাপ এ রাউট সার্চ করার জন্যে
  3. রোবট নেভিগেশন রাউট বের করার জন্যে
  4. কোন গেইম এ পাথ, রাউট সার্চ করার জন্যে

অন্য সব অ্যালগরিদম থেকে এটির ব্যবহার এতো বেশি হবার কারণ এটি শুরু এবং শেষের নোড খোঁজার জন্যে শুরু এবং শেষের নোড এর আশেপাশের নোড গুলো থেকে শুরু করে। অন্য একটি কারণ হচ্ছে এ* সার্চ শুধুমাত্র একটি নোড হতে অন্য নোডের দূরত্ব (cost) ছাড়াও একটি অনুমেয় দূরত্ব(Heuristic cost) ব্যবহার করে।

যদি এখনো পর্যন্ত যা বলছি তা কঠিন লাগে তাহলে আসুন একটি বাস্তব উদাহরণ এ চলে যাই।

আমরা প্রথমে শুরু করছি একটি গ্রাফ দিয়ে। ধরে নেই আমাদের গ্রাফটি দেখতে এরকম:

Graph1

সহজ বাংলায় এখানে একটি ছোট গ্রাফ আছে যার নোডসংখ্যা ৫ টি এবং কোন নোড থেকে অন্যান্য নোড এ যাবার cost নোড গুলোর edge এ লেখা। যেমন S থেকে A  যাবার জন্যে Cost 1. A থেকে G তে যাবার Cost হচ্ছে ১২. অন্যান্য সকল গ্রাফ সার্চিং অ্যালগরিদম এর মতো শুধুমাত্র path cost এর উপর এটি নির্ভর করেনা। আপনার ঠিক এর পর যেটি দরকার হবে সেটি হচ্ছে একটি Heuristic Cost . এখন প্রশ্ন আসতেই পারে কিভাবে Heuristic Cost আমরা ঠিক করবো। এই ক্ষেত্রে আমরা আমাদের এক নোড থেকে অন্য নোডের Expected Cost বসিয়ে নিয়েছি। তবে আপনি চাইলে এই Heuristic Cost ও নির্ণয় করার পদ্ধতিগুলো পরীক্ষা করতে পারেন। আমরা সেগুলো পরবর্তী কোন টিউটোরিয়াল এ দেখবো।

আসুন ধরে নেই আমাদের Heuristic Cost Table এরকম:

Graph2

আমাদের শুরু করবার নোড হবে S এবং শেষ করবার নোড হবে G। আসুন দেখি এ* সার্চ কিভাবে সঠিক পথ টি খুঁজে বের করে। আমরা একটি priority queue ব্যবহার করবো এ ক্ষেত্রে। আপনি যদি Priority Queue কি না জেনে থাকেন, অনুগ্রহ করে জেনে নিন এখান থেকে।

মনে করি লিস্টটির নাম Closed List, এটির ব্যবহার ব্যাখ্যা করার থেকে দেখে নেয়াটাই বুদ্ধিমানের কাজ হবে। অাপাতত জেনে রাখুন এটি একটি লিস্ট। আমাদের শুরু করার নোড হচ্ছে S , আমরা যেতে চাই G তে। আসুন দেখি, আমরা কিভাবে সেটি করতে পারি। প্রথমে নেই S কে। S এর সাথে Attached Node হচ্ছে A এবং B। তাহলে S থেকে G তে যেতে হলে আগে আমাকে A অথবা B তে যেতে হবে। তার মানে হচ্ছে যে নোড টি থেকে আপনি শুরু করবেন তার সাথে সংযুক্ত সকল নোড কে আপনার আগে বিবেচনায় আনতে হবে অথবা node টি expand করতে হবে।

সবার শুরুতে S এর Total Cost হিসেব করি:

c(s) = g(s) + h(s)

এখানে g(s) হচ্ছে S এ আসার Cost. S এ আসতে আমার তেমন কোন খরচ হয়নি বিধায় আমি এটিকে ধরে নিচ্ছি শূন্য। এবং h(s) হচ্ছে S এর heuristic cost যেটা আমরা table থেকে দেখে পাচ্ছি 7. এখন আমাদের কাজ হচ্ছে S এর সাথে সংযুক্ত সকল নোড বিবেচনায় আনা, মানে S expand করা। S কে expand করলে আমরা পাই A এবং B ।

c(s) = 0 + 7

মনে করি শুরুতে আমরা A তে যাবো।

এখন S হতে A তে যাবার Cost নির্ণয় করার উপায় হচ্ছে S থেকে A তে যাবার Cost এবং A এর Heuristic Cost যোগ করা। মনে করি:

c(S-A) = ( g(s)+g(a) ) + h(a)

এখানে c(S-A) হচ্ছে S হতে A তে যাবার Total Cost. g(s) হচ্ছে s এ আসার Cost. এখানে যেটি শুন্য। কারণ, s থেকে আমরা শুরু করছি। A তে যাবার Cost হচ্ছে 1. A এর Heuristic Cost হচ্ছে 6. তাহলে সম্পূর্ণ Cost দাঁড়ায়:

c(S-A) = ( 0+ 1 ) + 6 =7

অনুরূপ ভাবে S হতে B যাবার পর Cost দাঁড়ায়

c(S-B) = ( 0+ 4 ) + 4 =8

কারণ, s এ আসতে 0 এবং B আসতে 4 এবং B এর heuristic cost হলো 4 . এখন আমাদের অবস্থা নিচের মতো:
(sav)Graph

খেয়াল করলে দেখবেন, এখানে closed_list নামে একটি queue আছে। আমরা যখনি কোন নোড পুরোপুরি expand করে ফেলবো তখনি সেটিকে এখানে নিয়ে নেবো, যাতে পরে এটিকে Expand না করা লাগে। তাই আমরা এখানে S এর সব attached node (A, B) ভিসিট করে ফেলেছি বলে S কে closed_list এ রেখে দিয়েছি। আর ডান পাশে যে Tree টি তৈরী হচ্ছে তাকে বলবো আমরা Search Tree.

এখন যেহেতু A এবং B ভিসিট করা শেষ, আমাদের পরবর্তী টার্গেট A অথবা B expand করা। A এবং B এর মধ্যে কোনটি আগে করবো? যার Total cost কম তারটি আগে। এখানে A এর Total Cost 7 যেখানে B তে আসার Total Cost হচ্ছে 8, তাই এটি আগে expand করবো। A হতে শুধু B,C,G তে যাওয়া যায়। তাই ৩ টি পথের ই Total Cost বের করতে হবে। তাই Total Cost হবে:

c(S-A-B) = ( g(s)+g(b)+g(c) ) + h(c)

c(S-A-B) = ( 0+1+2) +4 = 7

অনুরূপভাবে,

c(S-A-C) = (0+1+5) + 2 = 8

c(S-A-G) = (0+1+12) + 0 = 13

(sav)Graph3যেহেতু A নোডটি আমাদের expand করা শেষ সেহেতু আমি A কে closed_list এ পাঠিয়ৈ দিবো। এখন সার্চ ট্রি এর দিকে লক্ষ্য করুন। প্রশ্ন হচ্ছে কোনটি আপনি expand করবেন? ট্রি এর সকল Leaf Node গুলো খেয়াল করুন (যেগুলো এখনো expand হয়নি)। নোডগুলো হচ্ছে:

  1. s-a-b
  2. s-a-c
  3. s-a-g
  4. s-b

এখন এর মধ্যে সবচেয়ে কম Total Cost হচ্ছে s-a-b এর। এটি এখন expand করতে হবে।

s-a-b এর শেষ নোড b, তাহলে b expand করি। b থেকে শুধু c তে যাওয়া যায় ।

c(s-a-b-c) = (g(s) + g(a) + g(b) + g(c)) + h(c)

c(s-a-b-c) = (0+1+2+2) + 2 = 7

যেহেতু B নোডটি আমাদের expand করা শেষ সেহেতু আমি B কে closed_list এ পাঠিয়ৈ দিবো।

(sav)Graph4

এখন আমাদের Leaf Node (ট্রি এর তলার নোড গুলো যেগুলো এক্সপান্ড করা হয়নি) সেগুলো হচ্ছে

  1. s-a-b-c
  2. s-a-g
  3. s-a-c
  4. s-b

যেহেতু s-a-b-c এর Total Cost কম সেহেতু আমরা এটিই expand করবো, মানে এটির শেষ নোড c expand করবো। c থেকে শুধু g তে যাওয়া যায়। তাহলে s-a-b-c-g এর total cost হচ্ছে

c(s-a-b-c-g) = (g(s) + g(a) + g(b) + g(c) + g(g) ) + h(g)

c(s-a-b-c-g) = (0+1+2+2+3) + 0 = 8

আমরা C কেও closed_list এ ঢুকিয়ে দেবো কারণ, এটি expanded হয়ে গেছে।

(sav)Graph5

এখন খেয়াল করলে দেখবেন আমাদের expand করার মতো path এবং তাদের Total Cost হচ্ছে:

  1. s-a-b-c-g = 8
  2. s-a-c = 8
  3. s-a-g = 13
  4. s-b = 8

এখানে s-a-b-c-g এবং s-a-c এবং s-b এর Total cost এক ই। এখন কোনটি expand করবো?

এখন আমাদের সমস্যা সমাধান করার জন্যে খেয়াল করে দেখুন alphabetically dictionary sort এ s-a-b-c-g আগে আসে, এরপর আসে s-a-c এবং তার পরে s-b

তাহলে s-a-b-c-g expand করা উচিত। কিন্তু এটি g তে চলে এসেছে এবং এখানেই আমরা আসতে চেয়েছিলাম। তাই, এই s-a-b-c-g ই আমাদের খুঁজতে থাকা পথ।তার মানে হচ্ছে আপনার এ* সার্চ এ যদি এক্সপান্ড করতে যে নোডটি সিলেক্ট হবে সেটিই যদি গোল নোড হয়, আপনি আপনার পথ পেয়ে গেছেন।

এটি ই সবচেয়ে ভালো পথ কিনা সেটি নিয়ে কথা বলবো পরের টিউটোরিয়াল এ। সাথে থাকবে একটি স্যাম্পল উইন্ডোজ ফোন অ্যাপ।

হ্যাপী কোডিং!

Introduction(Understand the basic structure of a c# program)

Hello Everyone!! In this series of tutorial we are going to discuss about the basic elements of C#. Like all others OOP (Object Oriented Programming) languages C# is also an OOP language that means the three qualities that make a programming language object oriented can be found in C# also. The qualities are-

  • Encapsulation
  • Polymorphism
  • Inheritance

We will understand each of this qualities in the later session of this series. In this article we will understand the basic structure of a C# program. All the sample programs of this series is going to be a Console Application and we are using Visual Studio as the IDE. So first we will learn how to open a console application in Visual Studio.

A console application is nothing but a program that can be executed in the command prompt of our Computer. To open a console application first we have to open visual studio then from the menu choose File-> New-> Project. Then another windows will pop up then in the popup window choose Visual C# in the left and you can see console application there. Choose Console Application template and give it a suitable name, you can choose the location where to save this program in your pc from here also. When you choose everything click the OK button to create the program.

OpenNewProject

When you click the OK button the program will be created and you will see the following code –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace introduction
{
    class Program
    {
        static void Main()
        {
        }
    }
}

Now for simplicity we will remove some code from the above and make it a very basic structure of a C# program. After removing those code the above program will looks like the following-

using System;

class Program
{
    static void Main()
    {

    }
}

The above program can be said as a very basic structure of C# program. Now we will describe each line of the above program.
The first line is-
using System;

This is called the namespace declaration. A namespace is nothing but a collection of some classes, enums, structs, interfaces and delegates. What are all these we will discuss later. A namespace can hold another namespace also. For now to understand the above line we can say there are some built-in methods in this namespace called System and to use those methods and classes we have to declare the namespace by using keyword at the top. Just for an example if we want to print something in the console then we can write the following code-

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello world");
    }
}

To run the above code press Ctrl+F5. Then the command prompt should appear with the message “Hello world”.
The definition of this Writeline method is written in the namespace called System. Now if we remove the using System; line from our code then we will get an error in the line Console.WriteLine(“Hello world”);
Because now the definition of WRITELINE method is missing from our program. If we want to remove the namespace declaration then we have to write the name in the line when we use a method belongs to that namespace as follows-

class Program
{
    static void Main()
    {
        System.Console.WriteLine("Hello world");
    }
}

Namespace is used to organize our code more effectively. If you don’t use the namespace declaration at the top then each time when you use a method you have to write its namespace which is more time consuming. So the use of namespace declaration is important.
Now the next thing in our basic structure is a Class declaration. We assume that you are familiar with OOP and if you are so then you are already known to class. Like other OOP language the class declaration in C# is exactly same. Anything you write in C# is belongs to a class. There are different types of class in C#. We will discuss it later in this series. Just for now we can say any piece of code should be inside of a class. Here the name of our class is Program.
Then there is also a method named Main and it is a static method. What is static method and class we will discuss it later. Now what we have to understand is the Main method is the starting point of our program. When we run our code it start to execute each line from the beginning of Main method and end when the Main method ends. To prove this, we can declare another same method named Main2 and in this method we print another message to differentiate the two method. We can consider the following piece of code-

using System;
class Program
{
    static void Main2()
    {
        Console.WriteLine("Another Message");
    }
    static void Main()
    {
        Console.WriteLine("Hello world");
    }
}

Here if we run the program we will see that only the message “Hello world” is printed. Another method named MAIN2 is not executed. So it’s proved that our program start from Main method and terminate when the MAIN method terminates. If we want to print the 2nd message then we have to call the MAIN2 method from MAIN method before it terminates. We can do it by the following-

using System;
class Program
{
    static void Main2()
    {
        Console.WriteLine("Another Message");
    }
    static void Main()
    {
        Console.WriteLine("Hello world");
        Main2();
    }
}

Now we should be able to see both messages.
In this article we see the basic structure of a C# programming and we can sum up with the following decisions from the above discussion-
• The namespace declaration using System; indicates that you are using System namespace
• A namespace is a collection of Classes, Structs, Delegates, Enums, Interfaces and used to organize the code more effectively.
• Our program starts with the Main method and terminates when the Main method terminates.

 

Recording Audio in Windows Phone 8.1

First Words

This article points to a simple, fast way to record audio in Windows Phone 8.1. As the old Microphone class is no longer available, Windows Phone 8.1 came with new MediaCapture class to consolidate the media recording part for audio and video together. So, why waiting, let’s see how to do it!

Let’s get busy

I jotted a very simple GUI for this that has three simple buttons named “Capture Audio”, “Stop Capture” and “Play Capture”.  And it looks as follows:

CaptureAudio1

If you guys want to have a closer look at the XAML behind, peek a look:

<Page
    x:Class="CaptureSoundTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CaptureSoundTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <MediaElement x:Name="playbackElement1" ></MediaElement>
        <Button x:Name="CaptureButton" Content="Capture Audio" HorizontalAlignment="Center" Margin="0,184,0,0" VerticalAlignment="Top" Click="CaptureButton_Click" Width="145"/>
        <Button x:Name="StopCaptureButton" Content="Stop Capture" HorizontalAlignment="Center" Margin="0,284,0,0" VerticalAlignment="Top" Click="StopCaptureButton_Click" Width="145"/>
        <Button x:Name="PlayRecordButton" Content="Play Capture" HorizontalAlignment="Center" Margin="0,380,0,0" VerticalAlignment="Top" Click="PlayRecordButton_Click" Width="145"/>

    </Grid>
</Page>

It’s pretty basic, I didn’t do much here without keeping the buttons in place. There’s a MediaElement named playbackElement1 to play back the recorded video.

Now, it’s time to populate the button events here named CaptureButton_Click, StopCaptureButton_Click and PlayRecordButton_Click

Initializing and Capturing audio

To capture audio, first we need to initialize the recording. Before digging into that, let’s just initialize some variables that we might need on the journey.

private MediaCapture _mediaCaptureManager;
private StorageFile _recordStorageFile;
private bool _recording;
private bool _userRequestedRaw;
private bool _rawAudioSupported;

The MediaCapture class here is the one responsible here to capture audio and video both here. And StorageFile instance will help us store, locate and play the recorded media on our device.

So, let’s have a look how our recording initialization method looks like:

private async void InitializeAudioRecording()
{

   _mediaCaptureManager = new MediaCapture();
   var settings = new MediaCaptureInitializationSettings();
   settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
   settings.MediaCategory = MediaCategory.Other;
   settings.AudioProcessing = (_rawAudioSupported &amp;&amp; _userRequestedRaw) ? AudioProcessing.Raw : AudioProcessing.Default;

   await _mediaCaptureManager.InitializeAsync(settings);

   Debug.WriteLine("Device initialised successfully");

   _mediaCaptureManager.RecordLimitationExceeded += new RecordLimitationExceededEventHandler(RecordLimitationExceeded);
    _mediaCaptureManager.Failed += new MediaCaptureFailedEventHandler(Failed);
}

So, the very first thing done here is the initialization of the MediaCapture class. Every media capture is associated with a MediaCaptureInitializationSettings instance. We’ve set the StreamingCaptureMode to Audio to make sure this is only audio recording rather than video. There were two bool variables declared before named _rawAudioSupported and _userRequestedRaw. Although I didn’t hook them up from GUI, you guys can defintiely try hooking them up from GUI and thus you can give the app a choice to record raw or pointing it to default audio processing.

The next thing to do is initializing the _mediaCaptureManager with the settings provided. I have included two event handlers for RecordingLimitExceeded and Failed. You guys can write your own handlers of course in these cases.

Now, usually you can put the InitializeAudioRecording method where your app initializes. I put it here on MainPage constructor.

Now, let’s capture audio, MediaCapture class made it really easy indeed.

private async void CaptureAudio()
{
   try
   {
     Debug.WriteLine("Starting record");
     String fileName = "record.m4a";

     _recordStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);

     Debug.WriteLine("Create record file successfully");

     MediaEncodingProfile recordProfile = MediaEncodingProfile.CreateM4a(AudioEncodingQuality.Auto);
     await _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile);

     Debug.WriteLine("Start Record successful");

     _recording = true;
    }
    catch (Exception e)
    {
      Debug.WriteLine("Failed to capture audio");
    }
}

If you have a good look on the code you will see we declared a filename first. And then we created a file in our VideosLibrary using KnownFolders.VideosLibrary.CreateFileAsync that actually points to the media and video library of windows phone 8.1 with a given filename and we also gave a CreationCollisionOption.GenerateUniqueName that says it will create a unique name in case of collision. The next thing to do is creating a recording profile using MediaEncodingProfile class and you can get all possible recording profiles for videos and audios from here. I created a M4a audio profile using MediaEncodingProfile.CreateM4a(recordProfile, this._recordStorageFile) method.

All we have left to do is now start the recording, so  let’s go ahead and start the recording. And it’s easy as pie with _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile)

Stopping Recording

Stopping the recording is quiet easy too. All you have to do is call _mediaCaptureManager.StopRecordAsync()

private async void StopCapture()
{

     if (_recording)
     {
          Debug.WriteLine("Stopping recording");
          await _mediaCaptureManager.StopRecordAsync();
          Debug.WriteLine("Stop recording successful");
          _recording = false;
     }

}

Playing Recording

Playing a recording kind of consists of two tasks. First we have to open the recorded file and then play it. If you guys remember we used StorageFile _recordStorageFile to define our file that will hold the recording.

private async void PlayRecordedCapture()
{
     if (!_recording)
     {
         var stream = await _recordStorageFile.OpenAsync(FileAccessMode.Read);
         Debug.WriteLine(&quot;Recording file opened&quot;);
         playbackElement1.AutoPlay = true;
         playbackElement1.SetSource(stream, _recordStorageFile.FileType);
         playbackElement1.Play();
     }
}

So, let’s open up the file and assign the resultant stream to a source of a MediaElement on XAML. In this case that one is playBackElement1

 

Voila! You’re done, now you can play your recording. All you have to do now is assign these three methods to proper button events. For the full source please download the demo project above.

Windows Phone 8.1 for newbies: Episode 2 – Hello Xaml!

উইন্ডোজ ফোন সম্পূর্ণ নতুনদের জন্যে তৈরী করা সিরিজের দ্বিতীয় ভিডিও এটি। আজকের বিষয় Hello Xaml. আশা করি কেমন লাগছে জানাতে ভুলবেন না।

ইউটিউব প্লেলিস্টটি পাচ্ছেন এইখানে