Integrating Google Analytics in WP/WinRT

How we had wished there was a Google Analytics SDK for windows phone and windows 8! The ease of a Google dashboard, the amount of info that it gives, the integration,  is way superior as compared to the other analytics tools available in the market.

and here is a GoogleAnalyticsSDK available in Codeplex. Works perfect and well documented! (An unusual combination :P)

Integration is a piece of cake!

Google Analytics SDK

May the code be with you! 😀

How to add multiple versions of the assembly without causing conflicts! -WP

An unusual sticky situation it is!

You have a external class, say Class Saviour , in your project. Class Saviour  uses another class, Class MostSoughtAfter from codeplex. Class Saviour has implemented Class MostSoughtAfter to suit its needs. So where ever you create an instance of Class MostSoughtAfter,  it will refer the Class MostSoughtAfter defined by Class Saviour . Suppose you need to use a function in the original Class MostSoughtAfter, and you add the dll . Visual Studio will throw a warning saying there is an ambiguity and that Class MostSoughtAfter implemented in Class Saviour is used to instantiate.

Bingo! You have multiple versions of the same class in your project and you need to reference them separately. I found a similar question in StackOverflow

Now in C# we have an “extern alias” keyword which will allow us to do the same. MSDN says

By using an external assembly alias, the namespaces from each assembly can be wrapped inside root-level namespaces named by the alias, which enables them to be used in the same file.

  1. In the solution explorer of your project, click the properties of the dll you want to reference,
  2. The Aliases field is set to ‘global’ by default. Change the global to name of your choice, say MyDLL.
  3. In the class you want to use the dll, first declare the alias right above the using statements
    extern alias MyDLL;
    
  4. To use a method in the assembly we make use of :: qualifier
    MyDLL:: System.Windows.Media.Imaging.MyClass.Resize();
    
  5. Thus a simple creation of an instance of MyClass will use the class implemented in the project. And if you want to use the original dll reference using the alias .

‘extern’  and an MSDN blog saves my day!!

References

Happy coding !! 😀

Saving a Canvas into a PNG file – WP8

This is a familiar situation that most developers run into. The need to save a canvas element to a png file.

Scenario

  • You have few strokes drawn on a canvas and you want to save it as a png .
  • You want to save the just the strokes on a transparent background.
  • You want to save the strokes along with the canvas background.
  • You want to save it with your specified sizes

I too ran into this ditch lately. And had a tough time finding a solution. A random google search will give you numerous methods, most of which is applicable only to traditional C#/.NET application.

Then I found this MSDN link. I still have’nt figured out how to use a PNGEncoder and DeCoder. If anyone finds a good blog about it, feel free to post it here. Many of the solutions I found never worked. The searches how ever led me to the WriteableBitmapEx hosted at codeplex. It had several useful functions but none to save a canvas to an image.

A week’s search, frustration, irritation,  trial & error of several broken classes finally led me to ToolStack. It is mentioned that it works for Windows Phone 7.1 but I have implemented in WP8 project. There 3 classes which will do the job neatly, although compression is not yet implemented.

  1. ToolStackPNGWriterWBext.cs – Implementation of WriteableBitmapExtensions
  2. ToolStackPNGWriterLib.cs – Core Class and implementation of saving to PNG
  3. ToolStackCRCLib.cs – Additional classes needed for ToolStackPNGWriterLib.

Getting it working on your project.

  1.  Download all necessary files from ToolStack. Download the example too and run it first so that you can understand how it works.
  2.  Add the Classes mentioned to your project.
  3. Create a Writeablebitmap of your canvas and then use the WritePNG function to save
    </pre>
    WriteableBitmap wb = new WriteableBitmap(MyCanvas, null);
    wb.WritePNG(MyStreamforWriteAsync);
    <pre>

And there your image lies in the specified location, in the size of your canvas! 🙂  Remember to add the necessary using statements in your file. Any canvas element can be captured into a WritableBitmap, even an InkPresenter can be captured.

NOTE TO WIN8 DEVELOPERS

If you try to implement the same functionality in a metro app, you’re in for trouble mate. Because the very simple function which allows to capture a canvas onto a WriteableBitmap does not exist! There is a method to save the inkstrokes though, but only the portion containing the stroke will be saved. You cannot save it along with its transparent/colored background. I consulted few developers and they seem to have no answer too. It seems this is possible in JavaScript.

Lets see if Windows 8.1 contains something for us developers in this direction.

Happy Coding!! 😀

Inking in WindowsPhone 8 – Part 1

Those who are familiar with Windows 8 will know that the platform gives us an elaborate, clean and easy to use InkManager class which allows you all the stroke manipulation you want.

As a part of my new project I was trying out the Inking features in WP8 only to find that there is no InkManager class at all!!. 😦
MSDN gives a meager list of classes to manipulate and interact with ink in windows phone. A quick search in the vast MSDN territory will give you an InkPresenter element which enables you to display the strokes. This does not fit my needs hence, I started the traditional way, to capture the touch inputs and then display them.

Create a canvas in my MainPage and give a white background image for the it.

</pre>
<Canvas x:Name="InkCanvas2" Height="150" HorizontalAlignment="Left" Width="471" Margin="0" >
<Canvas.Background>
<ImageBrush Stretch="Fill" ImageSource="/Assets/theme_img_note.png"/>
</Canvas.Background>
 </Canvas>
<pre>

Declare MouseMove and MouseLeftButtonDown Event handlers for the canvas in the constructor and define them as follows.

</pre>
void InkCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
 {
 currentPoint = e.GetPosition(InkCanvas); // captures the first point
 oldPoint = currentPoint;
 }

void InkCanvas_MouseMove(object sender, MouseEventArgs e)
 {
 currentPoint = e.GetPosition(this.InkCanvas);

Line line = new Line() { X1 = currentPoint.X, Y1 = currentPoint.Y, X2 = oldPoint.X, Y2 = oldPoint.Y };
 line.Stroke = StrokeColorBrush;
 line.StrokeThickness = StrokeWidth;//I have predefined the color and width for the stroke

line.StrokeStartLineCap = PenLineCap.Round; // This gives a round tip to the line
 line.StrokeEndLineCap = PenLineCap.Round;
 line.StrokeLineJoin = PenLineJoin.Round;

this.InkCanvas2.Children.Add(line);
 oldPoint = currentPoint;
 }
<pre>

😀 . The lines need to be optimized, I’m working on that. Hope this helps somebody!

test

Here are few references which I found useful.

  1. .MSDN sample
  2. .Net Speaks
  3. Codeguru

In the next post I’l be explaining how to save these images as PNG in folders.

Happy coding!!! 😀

Warm welcome to the latest addition of the Windows Phone family, WP8!

I guess most of the people have started developing for Windows phone 8 and I got a bit caught up with exploring the new terrains of the same. So this article comes in a bit late. Anyways better late than never 🙂

Here’s a small introduction about WP8 for the benefit for those who are new in this arena.

Windows Phone 8 as everyone knows is supposedly Microsoft’s ninja successor of Windows Phone 7.5 (Mango). As a part of unifying the phone, tablet and PC experience into one platform, Microsoft has taken a giant leap of re-engineering its mobile platform so as to share the same NT kernel as its big brother Windows 8. Now what does “shared core” mean to us?

  1. As most of us would unanimously would ask, “Could we use the same code?”.  Yes we can reuse ‘not all’ but ‘most of’ the code that we wrote for Windows 8 app. That’s some relief, but again until we actually delve into the nitty gritty of trying to port Win8 code to WP8, we would never know 🙂 . MSDN has given here detailed notes on how to maximize reuse of code.
  2. We talk different languages, some of us are C++ experts or C# or may be C. The good news is Windows Phone 8 now supports native code. To quote Joe Belfiore “What this means is a game developer who authors an unbelievable, detail-rich, immersive, compelling game experience for the PC has a super-easy port of their native game to the phone,”  And you also can mix C#/XAML with DirectX/C++ or consume native C++ libraries from C# apps. Although there is a small disappoint for the Javascript + HTML guys. Microsoft had allowed Javascript + HTML be to used as UI/coding combination for Windows 8, but it is not available for Windows Phone 8.
  3. In Windows Phone 8, the multitasking capabilities has been improved and expanded to VoIP and background location services.
  4. In-app purchase!! I guess I do not need to explain more.
  5. Other improvements like different screen resolutions, micro SD cards, NFC capabilities, multi-core support and so forth.

The next question that would obviously cross anybody’s mind would be, “What about WindowsPhone 7.5?” Well, the lovely mango remains, but sadly it does not get any update. The major reason being Windows Phone 7.5 had a CE kernel, while WP8 has an NT kernal. WP8 has a higher hardware requirements than that of the older generation windows phones. So I guess it makes sense not upgrading the WP7, even if they had managed, the OS would have crawled in the those devices powered by the lesser specs.

Again now, what it means to developers? What happens to all those apps we made for WP7.5? Is our laborious efforts soaked in sweat and blood getting flushed down the drain? Absolutely not, all apps that run on WP7.5 will run on WP8. You can count on me on that, I tested. 😀 And as expected, it doesn’t work the other way round. The apps which are meant for WP8 would not run on its predecessors.

Few links that can get you started

So thats all for now… Over and out!

Happy coding!! 😀

Storage Files and JSON

Something I was totally unfamiliar was, how to deal with was the StorageFiles and JSON data in WinRT. This is a basic example of how to read and write JSON data into a StorageFile.

Before we get to the code. What is JSON?

MSDN defines JSON as

an open, text-based data exchange format (see RFC 4627). Like XML, it is human-readable, platform independent, and enjoys a wide availability of implementations. Data formatted according to the JSON standard is lightweight and can be parsed by JavaScript implementations with incredible ease, making it an ideal data exchange format for Ajax web applications. Since it is primarily a data format, JSON is not limited to just Ajax web applications, and can be used in virtually any scenario where applications need to exchange or store structured information as text.

So JSON is relatively simpler than XML. It provides easier format to save and retrieve data and has native support for Arrays and Objects. Data stored will be in the following key value format.

[{“FirstName”:”hello”,”SecondName”:”sir”}]

Lets get our hands dirty with code. 😀

I created a simple page with two textboxes and a button, We enter the first name and the second name and when we click the button called save, it should save the data as JSON data into a File.

Now we make one more copy of the above elements, ie 2 more textboxes and a button. This button is for retrieving the saved data. On press of this retrieve button, it should open the same file, read the data and put them into the newly created textboxes.

<Grid Margin="107,75,816,335" Grid.Row="1">

<TextBox x:Name="firstTextbox" HorizontalAlignment="Left" Height="40" Margin="155,0,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="140" FontSize="20" />

<TextBox x:Name="secondTextbox" HorizontalAlignment="Left" Height="45" Margin="155,65,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="140" FontSize="20" />
<TextBlock x:Uid="firstTextblock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="First" VerticalAlignment="Top" Width="110" Height="40" FontSize="28"/>
<TextBlock x:Uid="secondTextblock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Second" VerticalAlignment="Top" Margin="0,75,0,0" Width="110" Height="35" FontSize="28"/>
<Button Content="Save JSON" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="80,145,0,0" Tapped="OnSaveButtonClicked"/>
</Grid>

<Grid Margin="640,75,316,335" Grid.Row="1" RenderTransformOrigin="0.5,0.5">
<TextBox x:Name="firstTextbox1" HorizontalAlignment="Left" Height="40" Margin="155,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="140" />
<TextBox x:Name="secondTextbox1" HorizontalAlignment="Left" Height="33" Margin="155,75,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="140" />
<TextBlock x:Uid="firstTextblock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="First" VerticalAlignment="Top" Width="110" Height="40" FontSize="28"/>
<TextBlock x:Uid="secondTextblock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="Second" VerticalAlignment="Top" Margin="0,75,0,0" Width="120" Height="35" FontSize="28"/>
<Button x:Name="RetrieveButton" Content="Retrieve" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="155,155,0,0" Tapped="OnRetrieveClicked"/>
</Grid>

Add the following namespace so as to enable the JSON data and declare a StorageFolder inside the MainPage class

using Windows.Data.Json;

Windows.Storage.StorageFolder localfolder;

So on the click of save button you call the SaveJSONData function.


private async void OnSaveButtonClicked(object sender, TappedRoutedEventArgs e)
 {
await SaveJSONData();
}

And the SaveJSONData has the code to convert the text to JSON. Here I have declared just one JsonObject. If you have an array of objects you can declare a JsonArray to which each object can be placed.

public async Task<bool> SaveJSONData()
 {
 JsonArray dataArray = new JsonArray();

JsonObject dataObject = new JsonObject();
 dataObject.Add("FirstName", JsonValue.CreateStringValue(firstTextbox.Text));
 dataObject.Add("SecondName", JsonValue.CreateStringValue(secondTextbox.Text));

dataArray.Add(dataObject);

string jsonString = dataArray.Stringify();
 await WriteToFile(jsonString);
 return true;
 }

JsonArray.Stringify returns the JSON representation of the encapsulated value. So after obtaining the encapsulated value we write it to a file.

public async Task<bool> WriteToFile(string jsonString)
 {
 try
 {
 StorageFile DataFile = await localfolder.CreateFileAsync("SampleFile", CreationCollisionOption.ReplaceExisting);

using (var stream = await DataFile.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
 {
 var outputStream = stream.GetOutputStreamAt(0);

using (DataWriter dataWriter = new DataWriter(outputStream))
 {
 dataWriter.WriteString(jsonString);

await dataWriter.StoreAsync();
 dataWriter.Dispose();
 await outputStream.FlushAsync();
 }

await stream.FlushAsync();
 }
 }
 catch (Exception)
 {
 }

return true;
 }

Similarly for reading the saved data,

private async void OnRetrieveClicked(object sender, TappedRoutedEventArgs e)
 {
 await RetrieveJSONData(); ;
 }

public async Task<bool> RetrieveJSONData()
 {
 string jsonString = await ReadFromFile();
 if (jsonString != null)
 {
 JsonArray jsonArray = JsonArray.Parse(jsonString);
 firstTextbox1.Text = jsonArray.GetObjectAt(0).GetNamedString("FirstName");
 secondTextbox1.Text = jsonArray.GetObjectAt(0).GetNamedString("SecondName");
 return true;
 }
 return false;
 }

 public async Task<string> ReadFromFile()
 {
 StorageFile DataFile = null;
 String buffer = null;

try
 {
 DataFile = await localfolder.GetFileAsync("SampleFile");
 }
 catch (FileNotFoundException)
 {
 }
if (DataFile != null)
 {
 try
 {
 using (var fs = await DataFile.OpenAsync(FileAccessMode.Read))
 {
 using (var inStream = fs.GetInputStreamAt(0))
 {

using (var reader = new DataReader(inStream))
 {
 await reader.LoadAsync((uint)fs.Size);
 buffer = reader.ReadString((uint)fs.Size);
 }
 }
 }
 return buffer;
 }
 catch (Exception)
 {
 }
 }
 return buffer;
 }

You have successfully created JSON data and written it to a file and read it back. Alternatively you can use serialize the .NET class objects to JSON and deserialize them back.

How to: Serialize and Deserialize JSON Data

Happy coding! 😀

Localization of a Metro app

While porting your app from Windows Phone to Windows 8, you’ll see that a lot of the code can be reused without much of trouble. Most of the changes have to be done in the design front as more screen real estate is available as compared to a standard 480×800.

Localization is defined by MSDN as

the translation of application resources into localized versions for the specific cultures that the application supports.

There are few differences in the way localization is done in Windows Phone and Windows 8. The resource file is named as a .resw file and not a resx file.  If you are porting the .resx as it is, I would suggest to name your elements the same as in the .resx file. Although you can localize using Bindings, I prefer associating the x:Uid which definitely makes the XAML code easier to read.

1. Firstly we need to create a folder in the project into which all the strings in the app needs to go. Here I have named it Strings

2. Inside the Strings folder, we create subfolders for each language. eg: en, fr.

3. Then we create individual resource file for every culture. [Right-Click on folder > Add > New Item > Resource File (.resw) .By convention name it as Resources.resw

After the above steps your solution explorer will look like this

Next is how we bind the xaml elements to these strings and how we can access the resw strings from the code-behind.

XAML

1. For every xaml element you create and has a string that need to be localized, associate a x:Uid attribute with it.

For eg,


<TextBlock x:Uid="calPageTitle" Grid.Column="1" Text="" Style="{StaticResource PageHeaderTextStyle}"/>

2. Now, in your Resource.resw file add the string that needs to appear in your TextBlock. Add the x:Uid of the element and the property. Here I’ve added the Text property ie the string should display “Calendar”.

3. We then set the Neutral language of the app to en-US.

To set the neutral language, Right Click the project in the Solution Explorer > Properties > In the Application Tab which is highlighted by default, click Assembly Information >In the neutral language option select the default language we want. Here I’m selecting English(United States)

Now when you run the app, the Textblock named pageTitle should have displayed “Calendar”.

For the other languages add the appropriate text in the corresponding resw.

Accessing the string from code behind

Declare a new object, loader of ResourceLoader type. You may have to include

using Windows.ApplicationModel.Resources;

Use GetString function to obtain the necessary string. I have noticed that the string in the resw which is bound to the xaml x:Uid cannot be used in the code behind. Some how string calPageTitle  or calPageTitle.Text does not seem to fetch the string. So I declare another string in the resw file called calPageTitle2 which has the same string “Calender”.

var loader = new ResourceLoader();
pageTitle.Text = loader.GetString("calPageTitle2")

So when I run the app once with the x:Uid removed , “Calender” is displayed again.

To test for different languages, change the simulator language from the control panel.

As in windows phone, there is no need of writing a separate class for fetching the strings and we do not need to make changes to the <SupportedCulture> in the cs.proj file.

🙂 I have my app localized!!

May the code be with you 🙂

Ref: Quickstart: Using string resources (Metro style apps using C#/VB/C++ and XAML).