Capture usage information of a Windows Phone 7 application using Google Analytics

About half a year ago I created a Blend behavior to capture usage information of a Silverlight application. But what’s next, in the near future we will have Windows Phone 7, and we can write very nice applications by using the Silverlight platform.

Although the platform is the same, you won’t be able to make use of the Blend behavior I’ve written before. Because this Blend behavior makes use of scripting inside the hosting html page. There simply is no page that hosts your Silverlight application. This is a similar problem we face when a Silverlight application is running out-of-browser, but back to the phone.

Solution Direction

To connect to Google Analytics I need to have a html page that contains a script that calls into Google Analytics to track events. So somehow I need to connect a Windows Phone 7 app to this html page.

Solution Implementation

I started off with the html page, and made it as small as possible, no content, only the scripting part.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Windows Phone 7 - Application Tracking</title>
    <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
    <script type="text/javascript">
        var pageTracker = _gat._getTracker("UA-xxxxx-x");
        pageTracker._trackPageview();

        function trackEvent(category, action, label) {
            pageTracker._trackEvent(category, action, label);
        }
    </script>
</head>
<body>
</body>
</html>

I hosted it somewhere so it’s accessible through the internet. If you copy-paste this code please make sure that you fill in your own Google Analytics tracking code.

I’ve seen some code examples where Windows Phone 7 apps were hosting a webbrowser and where the app was communicating to the page hosted in the app. So that’s where I began as well.

Add a WebBrowser control to the MainPage.xaml, I named it trackingBrowser

<browser:WebBrowser x:Name="trackingBrowser"/>

Make sure that scripts are enabled on the WebBrowser control

image

In the end it’s not required to make it visible at all so we can set the Visibility to Collapsed. If you’re not comfortable with not showing the browser during development you can of course leave the browser visible.

image

The resulting xaml will look similar to this.

<browser:WebBrowser x:Name="trackingBrowser" 
                    IsScriptEnabled="True" 
                    Visibility="Collapsed" />

The WebBrowser needs to load the create html page. So in the Loaded event of the containing page I set the url of the WebBrowser.

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    trackingBrowser.Navigate(new Uri("http://change-to-your-domain.com/tracking.htm"));
}

As soon as the WebBrowser navigated to this url I want to execute the trackEvent inside the html page. To call Javascript on a WebBrowser control you will have to make use of the InvokeScript method. Because the Navigated event doesn’t come back to the UI Thread we will need to make use of the Dispatcher to actually call the trackEvent method.

trackingBrowser.Navigated += (s, args) =>
                                Dispatcher.BeginInvoke(
                                    () => trackingBrowser.InvokeScript("trackEvent",
                                                                       "WindowsPhoneExperiment",
                                                                       "Load",
                                                                       "On Loading of Application"));

For the sake of the experiment I also added a button to the form to track events on button click. The event handler for the button-click looks like this.

private void button1_Click(object sender, RoutedEventArgs e)
{
    trackingBrowser.InvokeScript("trackEvent",
                                 "WindowsPhoneExperiment",
                                 "Click",
                                 "On Click of a Button");
}

That’s all, and now we wait…

Result

It’s very important to view the result. It will take some time before the Google Analytics stats are working. I waited a day before I looked at the stats. Good to see the concept works.

image

Full code

MainPage.xaml

<phoneNavigation:PhoneApplicationPage x:Class="MM.Phone.Experiments.MainPage"
                                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                      xmlns:phoneNavigation="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Navigation"
                                      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                                      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                                      mc:Ignorable="d"
                                      d:DesignWidth="480"
                                      d:DesignHeight="800"
                                      FontFamily="{StaticResource PhoneFontFamilyNormal}"
                                      FontSize="{StaticResource PhoneFontSizeNormal}"
                                      Foreground="{StaticResource PhoneForegroundBrush}"
                                      xmlns:browser="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.WebBrowser"
                                      Loaded="PhoneApplicationPage_Loaded">

    <Grid x:Name="LayoutRoot"
          Background="{StaticResource PhoneBackgroundBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <!--TitleGrid is the name of the application and page title-->
        <Grid x:Name="TitleGrid"
              Grid.Row="0">
            <TextBlock Text="MM Phone Experiments"
                       x:Name="textBlockPageTitle"
                       Style="{StaticResource PhoneTextPageTitle1Style}" />
            <TextBlock Text="Analytics"
                       x:Name="textBlockListTitle"
                       Style="{StaticResource PhoneTextPageTitle2Style}" />
            <Button Content="Button"
                    Height="70"
                    HorizontalAlignment="Left"
                    Margin="320,77,0,0"
                    Name="button1"
                    VerticalAlignment="Top"
                    Width="160"
                    Click="button1_Click" />
        </Grid>

        <!--ContentGrid is empty. Place new content here-->
        <Grid x:Name="ContentGrid"
              Grid.Row="1">
            <browser:WebBrowser x:Name="trackingBrowser"
                                IsScriptEnabled="True"
                                Visibility="Collapsed" />
        </Grid>
    </Grid>

</phoneNavigation:PhoneApplicationPage>

MainPage.xaml.cs

using System;
using System.Windows;
using Microsoft.Phone.Controls;

namespace MM.Phone.Experiments
{
    public partial class MainPage : PhoneApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();

            SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;

            trackingBrowser.Navigated += (s, args) =>
                                         Dispatcher.BeginInvoke(
                                             () => trackingBrowser.InvokeScript("trackEvent",
                                                                                "WindowsPhoneExperiment",
                                                                                "Load",
                                                                                "On Loading of Application"));
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            trackingBrowser.Navigate(new Uri("http://change-to-your-domain.com/tracking.htm"));
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            trackingBrowser.InvokeScript("trackEvent",
                                         "WindowsPhoneExperiment",
                                         "Click",
                                         "On Click of a Button");
        }
    }
}

tracking.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Windows Phone 7 - Application Tracking</title>
    <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
    <script type="text/javascript">
        var pageTracker = _gat._getTracker("UA-xxxxx-x");
        pageTracker._trackPageview();

        function trackEvent(category, action, label) {
            pageTracker._trackEvent(category, action, label);
        }
    </script>
</head>
<body>
</body>
</html>
  • Gravatar Bjorn Backlund June 24th, 2010 at 16:17
    No need for a WebBrowser, see the new Silverlight Analytics Framework ( http://msaf.codeplex.com ) or the Tracking API in the AppStats solution (www.web-analysis.net)
  • Gravatar sebastian holst June 24th, 2010 at 19:33
    The Silverlight Analytics Framework (SAF) works well for capturing "web analytics". In fact, the technology I am about to reference (Runtime Intelligence) is also a full blown plugin to the SAF framework - so when the SAF is called for, the user can select Runtime Intelligence inside Blend if they like.

    However, Runtime Intelligence instrumentation can also be injected into Silverlight assemblies using the community edition of Dotfuscator found inside Visual Studio 2010 (all SKUs but express). Since you mention CodePlex, it is worth noting that through a partnership with PreEmptive (we make both Dotfuscator and Runtime Intelligence), all CodePlex projects have free access to the commercial analytics repository too. Checkout CodePlex's announcement of the service here http://port25.technet.com/archive/2010/05/06/codeplex-users-to-get-free-analytics-data.aspx

    Here is a 90 second channel 9 video on how to use Dotfuscator for injection here - http://channel9.msdn.com/posts/Clint/Docfuscator-Runtime-Intelligence-in-90-seconds/

    What is compelling about this approach is that you can use Expression Blend SAF to configure "web stats" and Visual Studio Dotf. CE to configure feature usage, and monitor physical layers of software OFF OF the Silverlight client (even Azure). ...AND all of the data streams to the same endpoint for analysis.

    ...and yes, it will work on Windows Mobile 7 too.

    Please note, the free version (CE)of Dotfuscator lags the commercial SKU (since we check in our CE version to MSFT WAY early) and so Windows Mobile 7 support must lag a bit too by necessity. Today, the commercial SKU supports all of this now and the CodePlex analytics works fine with CE.
  • Gravatar progg.ru June 27th, 2010 at 16:02
    <strong>Capture usage information of a Windows Phone 7 application using Google Analytics « Mark Monster...</strong>

    Thank you for submitting this cool story - Trackback from progg.ru...
  • Gravatar mich January 16th, 2011 at 04:11
    i found these 2 companies

    mtiks - http://www.mtiks.com
    localytics - http://www.localytics.com
  • Gravatar Mangesh January 31st, 2011 at 09:01
    Hi,
    I want to make use of MSFT Silverlight Analytics framework, to track usage information of my WPF application.
    How to do this? Any pointer will be helpful.
  • Gravatar Doug Rathbone February 15th, 2011 at 12:23
    hey there,

    thought you'd be interested in knowing that i have a c# library that does this natively called GaDotNet.

    it is open source and is on codeplex:

    http://gadotnet.codeplex.com/

    my original post about it

    http://www.diaryofaninja.com/blog/2010/07/11/google-analytics-event-tracking-in-native-code-ndash-now-in-gadotnet-12

    you could probably adapt this for use with the phone
  • Gravatar joseharriaga October 29th, 2011 at 02:16
    I got it to work. You were right: it was the Interactivy assembly.
    Unfortunately, even though this solution is very clean, the Analytics Framework adds up almost two seconds to my application's start up time.
    Because of this, I think I'll implement the browser solution you proposed before instead. :)
  • Gravatar Air Jordan 4 September 10th, 2012 at 08:47
    I got it to work. You were right: it was the Interactivy
  • Gravatar ground beef recipes healthy quick March 29th, 2014 at 10:46
    Although organic foods and products are more accessible than ever, some organic foods are hard to
    find. This makes an easy and delicious weekday dinner
    that even picky eaters will love. Changing your lifestyle is difficult, but do not let a little
    discouragement break your resolve.
  • Gravatar healthy egg salad recipe with greek yogurt March 30th, 2014 at 09:06
    Cereal For crunchy treats, I buy a bag of generic
    cereal (like off-brand Cap'n Crunch or Chex Mix) and then disperse
    the contents into sandwich bags. Remove from heat,
    pour out hot water and run a constant stream of cold water over the eggs until completely cooled.

    The Leflore Farmers Market has a great selection and good prices on their locally grown and farm fresh produce.
  • Gravatar toms on sale online April 11th, 2014 at 02:53
    An independent physician named by Grillo last week corroborated the determination that Jahi is legally dead, saying that testing showed no blood flow to the brain, no ability to breathe without the ventilator and no sign of electrical activity in her brain.Jail for men who robbed cattery
  • Gravatar 608606.pink2.net April 19th, 2014 at 05:29
    Really great 608606.pink2.net. I received these businesses now of chestnut(the next ones in the measurement!!) and i am very very pleased with it all!!!
Gravatar