This is the last post in my 4 part series. The previous posts in this series covered the basics for creating a simple Xamarin.Android Video Player application. Feel free to check them out to see how we built a basic Video Player:
Part 1 – Using VideoView
Part 2 – Adding Media Controls
Part 3 – Progress Indicator and Orientation Changes
In this final post, we will polish off our Video Player by taking steps to ensure the application does not fail in the event a network connection isn’t present, since we are loading videos from an external site. We will listen for changes in the network connection while the application is running so that when the connectivity state changes we can handle it accordingly. We will display a relevant error message when no connection is found, and we will attempt to resume the video playback when the connection is restored.
Let’s take a look at the classes provided through the API which enables us to monitor the current network connection on a device.
ConnectivityManager and BroadcastReceiver
The ConnectivityManager is a class which provides information on the current network connection (i.e. whether there is a connection and the type of connection), monitors for network connectivity changes, and broadcasts a connectivity action when any connection details have changed.
The BroadcastReceiver is a base class that will receive notifications in the form of intents when another application or the system triggers the SendBroadcast(Intent) method. An intent will contain an action string and optional data that will be received by any applications that are registered as receivers.
To enable your application to listen for connectivity change notifications broadcast by the ConnectivityManager, you must register a broadcast receiver by adding the following line to your AndroidManifest.xml file:
In addition to that, because you are accessing information about network state, you will need to include the necessary permission in your AndroidManifest as well:
Next, you must extend the BroadcastReceiver base class and override its OnReceive(Context, Intent) method. Within this override method, you can check the intent’s Action to determine if and how you will respond to the broadcast intent within your own application.
The Connectivity Plugin
Now that you have an understanding of the basic components that help you to monitor network connections in an Android application, I have some good news – Xamarin’s own James Montemagno has already written a plugin for that and made it available as a Nuget package :)
The Connectivity Plugin contains the necessary code for retrieving information about the network, monitoring for network connections and listening for connection changes.
The best part of this plugin is that it is a complete cross platform solution, so that you can use it in your client applications and Portable Class Libraries. He has provided both the abstraction layer and the necessary platform-specific implementations (ie. Android, iOS, Windows 8.1 and Windows Phone (8.0 & 8.1)). The Connectivity Plugin handles loading the platform-specific implementation logic. All you have to do is make the appropriate calls through the plugin’s IConnectivity interface which is exposed through the CrossConnectivity.Current static property. At runtime, the Connectivity Plugin will load the platform-specific implementation and make it available through CrossConnectivity.Current.
This may not seem like a big deal now, since we are only targeting Android. But if you ever wanted to expand your application to target multiple platforms, you will realize a huge time savings from only having to call one API rather than code each platform’s implementation to achieve the desired result.
James has made the entire solution for the Connectivity Plugin available on his Github account. Feel free to peruse the code or download it and customize it for your needs.
Side Note: When using 3rd party components, be sure to provide proper attribution within your application - for example, by adding a Credits page that lists the components you used, along with their respective authors. These components are provided by developers to make your life easier, so it’s important to give credit where credit is due.
Using the Connectivity Plugin in our Android Project
To add the Connectivity Plugin to our application, right-click on the project in Solution Explorer, and select Manage Nuget Packages. Within the Manage Nuget Packages dialog, search for Xamarin Connectivity. Install the Connectivity Plugin for Xamarin and Windows.
Once the Connectivity Plugin has been added to the project, take a look at the project’s references. Notice that it added two new references to the project – Connectivity.Plugin and Connectivity.Plugin.Abstractions.
In the MainActivity code file, add using directives for these namespaces:
There are two things we care about and need to account for:
1) listening for changes in network connectivity
2) performing the appropriate check so the video attempts to load only when a network connection is present
To monitor for changes in network connectivity, we need to register an event handler for the ConnectivityChanged event. Add the following to the OnStart method:
CrossConnectivity.Current.ConnectivityChanged += OnCurrentConnectivityChanged;
Be sure to unregister the event handler in the OnStop method as well.
Next, we need to include the action we want taken when the network connectivity changes. In this scenario, we only care about whether or not the video can play. Since the LaunchVideo method is responsible for starting the video playback, let’s include a check to only start the playback if the network is currently connected, so that no matter where it’s called from, we are performing our due diligence. I am also going to ensure that the video player isn’t in the middle of playing the video already since LaunchVideo is called from multiple locations.
Then in our OnCurrentConnectivityChanged event, we can simply call the LaunchVideo method as is, since it’s already checking to ensure an active connection before playing the video. Alternatively, you could check the state of the connection within this event handler through the ConnectivityChangedEventArgs.IsConnected property. It’s up to you, whichever way you prefer to handle it.
Now, we want to be able to display a status message when the network connection is lost. Let’s add a TextView to the MainActivity layout.
Notice that the text of the control is set to a custom string definition. Add the following to your Strings.xml file:
With the TextView in place, we now need to ensure we set the view states on the VideoView, the ProgressBar and our new TextView based on connection state. When there is no network connection, we want only the status message (ie. the TextView) to display, otherwise it is hidden and the ProgressBar and VideoView will display.
Let’s create a separate method called UpdateVideoPlayerState, and include the code to achieve this:
However, we also need to account for hiding the TextView, and displaying the VideoView and the ProgressBar when the network is connected. We also want to be able to call this method anytime we need to update the state of the controls in the video player, so let’s extend it to also be able to hide the ProgressBar in the event the video is ready to play. We can do this by passing in a boolean parameter to indicate the state the video player is in when connected, as follows:
Again, note that we are also checking to make sure the video player isn’t in the midst of playing the video, since this method is also called from multiple locations.
Tip: If you’re wondering why we do not set the VideoView’s Visibility to Gone or Invisible when the ProgressBar is displayed, it is because the VideoView will not fire events when hidden. Since we registered an event handler for its Prepared event in order to determine when to trigger the video playback, we need to ensure it remains Visible in this scenario.
Now we can simply add the call to UpdateVideoPlayerState, passing in a false value when the video player activity first starts, when the configuration changes or connectivity changes.
When the OnVideoPlayerPrepared event is triggered, we know the video is ready to play, so let’s call updateVideoPlayerState passing in a true value, as follows:
Last but not least, don’t forget to modify the AndroidManifest.xml to register a broadcast receiver and to request permission to access network state as we discussed earlier.
Playing Video only when connected to WiFi
If you only want the application to play the video when connected to a WiFi network, you can easily modify the existing code to check to see if the device is currently connected to WiFi. The Connectivity Plugin exposes a collection of all the current active connection types. So we can include a bool property which returns true or false if the device has a WiFi connection:
Note that we are using a simple LINQ query to check for a WiFi connection type. This requires the inclusion of the following using directive within your class:
Replace the checks from CrossConnectivity.Current.IsConnected to IsConnectedToWiFi.
At this point, you can run and test the application. Play around with turning on/off WiFi connections while the video is loading and while the video is playing to see what happens. I know you will find more ways to improve upon this sample application just by testing it out. I hope this gives you a good starting point to work from. You can check out the completed project on my Github account.
In Part 1 of this series, we developed a simple video player using Android’s VideoView, and in Part 2 we improved upon it by adding media controls to enable users to rewind, fast forward, pause and resume video. However, in testing the application, it is obvious that there are some key features missing. Let’s take a look at how we can improve our Video Player application to provide a better user experience.
Why does the video restart when the orientation changes?
Run the application as it is, and as the video is playing change the device orientation. What do you notice? The video starts over from the beginning. This is annoying, right? I personally think so. It would be ideal to have the video pick up from where it left off when the user rotates the device. Also, what will happen if a phone call comes in and the application is moved to the background? When the user returns, the video restarts from the beginning. Again, the user is expecting that the video picks up from where it left off when returning to the application. So how do we accomplish that?
Activity provides an override method, OnSaveInstanceState, which allows you to store the current state of the activity before it is destroyed and recreated through the actions we discussed above. OnSaveInstanceState provides a Bundle which we can use to add in values that we will use to restore the activity’s state when it is recreated. In this case, we will use this method to check if a video is playing, and store its current playback position in the Bundle. This is straightforward since the VideoView exposes properties, IsPlaying and CurrentPosition, which makes light work of this:
Now, we need to retrieve that value from the Bundle when the Activity is recreated and when the application is restored. We can do this within the OnCreate and OnRestoreInstanceState methods respectively.
Notice that we also ensure that the video player is launched when the application is resuming from the background.
Now that we have a starting position for the playback to resume from, we will pass it into the VideoView’s SeekTo method, which sets the current position of the video. Note that the time is in milliseconds. We still need to call the VideoView’s Start method to trigger the playback. The following lines must be added to the LaunchVideo method:
How can I show an indicator while the video is loading?
While testing out the application, you may have noticed there is a delay within the application as the video is loading, moreso because we are loading from a URL. Ideally, we want to display a progress indicator until the video is loaded and ready to play. This will provide a better user experience rather than just displaying a blank screen. We will add a ProgressBar to the layout, which will display by default and then will be removed from the view when the video is ready.
In the Activity’s layout file, add the ProgressBar to the layout, after the VideoView, as follows:
Next, we need to obtain a handle to the ProgressBar in the Activity’s code file, just as we did with the video player and media controller. While I’m at it, I’m going to refactor the code to move these calls to a private method, called InitializeVideoPlayer, which will be called from the OnStart method rather than from OnCreate. This will ensure we will retrieve a handle to the controls even when our app is resumed from being placed in the background.
Now that we have a handle to the ProgressBar, this allows us to set the its Visibility to appear whenever the Activity’s orientation changes (ie. when the user rotates the device to view the video in either portrait or landscape mode), and to disappear when the video is ready to play.
Since we want to hide the ProgressBar when the video is ready to play, we can make use of the OnVideoPlayerPrepared event handler. Within this event, set the ProgressBar’s Visibility state to ViewStates.Gone as follows:
videoProgressBar.Visibility = ViewStates.Gone;
If you’re wondering why we are using Gone instead of Invisible, it has to do with a difference in the way the layout space is handled when the view is hidden. The ViewStates.Gone value will ensure that the ProgressBar does not take up any layout space when hidden, whereas ViewStates.Invisible will still continue to take up the layout space when hidden.
Finally, we want to ensure the ProgressBar is displayed when the orientation changes, we can override the OnConfigurationChanged event and set the ProgressBar’s Visibility as follows:
videoProgressBar.Visibility = ViewStates.Visible;
In this post, we improved upon our basic VideoPlayer application by adding a progress indicator as the video reloads when the device is rotated, and ensuring that the video playback resumes at the same position it left off.
Since our application depends on a network connection, we need to perform due diligence and verify that the device is connected to the carrier network or WiFi before attempting to load the video. In this way, we can display a relevant error message when no connection is present. In my next post, we will build on this example and include the proper checks to handle cases where no network connection is present, as well as how to listen for changes in the network connection while the application is running.
In Part 1 of this series, we developed a simple video player using Android’s VideoView. However, in testing the application, it is obvious that there are some key features missing. Let’s take a look at how we can improve our Video Player application to provide a better user experience.
Where are the media controls?
The first noticeable thing that seems to be missing from our Video Player is the play, rewind, and fast forward buttons, as well as the progress slider that we are used to seeing when watching videos in other popular video players. The user will not be able to control video playback without it, which isn’t ideal. Luckily for us, it is very easy to incorporate this within our Xamarin.Android application.
The Android API provides a MediaController view, which contains the play/pause, skip forward, and skip back buttons along with a progress slider. To make use of the MediaController, we will need to instantiate it programmatically, and associate it with the VideoView, as follows:
private MediaController mediaController;
protected override void OnCreate(Bundle bundle)
videoPlayer = FindViewById<VideoView>(Resource.Id.PlayerVideoView);
mediaController = new MediaController(this, true);
The constructor we are using for the MediaController requires that we pass in the current context, which is the current Activity, and a boolean value to indicate whether or not to show the rewind and fast forward buttons. With the code above in place, the MediaController will display the Play/Pause button, the rewind and fast forward buttons, and the progress slider. If you wish to hide the fast forward and rewind buttons, simply pass in false as the second parameter value instead.
To ensure that any action the user takes on the MediaController affects the video playback accordingly, we must associate the MediaController with the VideoView by calling the VideoView’s SetMediaController method and passing in a reference to the MediaController. Not only does this allow the user to control the video playback with the controller, but it also registers a touch listener that is associated with the VideoView so that when the view is tapped, the MediaController will appear. There is nothing else we need to do at this point. We can run the application and the MediaController will just work. We can play, pause, fast forward and rewind the video without any additional coding needed on our end. When the MediaController disappears from the view, tap the video to make it reappear.
Tip: In the event that you are creating an application which allows users to manage a playlist of videos, and you want to allow them to skip to the navigate through the video queue, you will need to register event handlers for the MediaController’s PreviousClick and NextClick events. Within those events, include your custom code to load the next or previous video in the queue. Once you have registered for those events, you will notice the Previous and Next buttons will appear in the MediaController.
Test out the application so far, play with the media controls and switch the device orientation from portrait to landscape mode while the video is playing. Notice that when the video playback starts, we don’t see the MediaController on the screen at all. In order to display the controls, the user must touch the video to force it appear. This isn’t really intuitive. It would be ideal to show the user that the MediaController is there when the video starts to play, and then hide it after a brief period, let’s say 3 seconds.
The MediaController provides a Show method, which accepts a timeout in milliseconds for this purpose. It will force the MediaController to appear and remain visible for the specified time.
Since we want the controller to appear when the video playback starts, we will handle this in the VideoView’s Prepared event, which is triggered when the video is ready to play. Register this event in the Activity’s OnStart method:
protected override void OnStart()
videoPlayer.Prepared += OnVideoPlayerPrepared;
In the same respect, we should unregister the event in the OnStop method:
protected override void OnStop()
videoPlayer.Prepared -= OnVideoPlayerPrepared;
Next, we will add our custom OnVideoPlayerPrepared event handler and call the MediaController’s Show method, as follows:
private void OnVideoPlayerPrepared(object sender, EventArgs e)
//show media controls for 3 seconds when video starts to play
Run the application in portrait mode. Notice that the media controls are displayed at the bottom of the screen, far removed from the video.
Would it be preferable to render the controller as an overlay on the video? We can easily make that change by calling the MediaController’s SetAnchorView method and passing in a reference to the VideoView. This will enable the MediaController to know where to position itself when it is rendered onscreen. The media controls will then be displayed as an overlay at the bottom of the anchored view.
To achieve this effect, add a call to the SetAnchorView method in the OnVideoPlayerPrepared event:
private void OnVideoPlayerPrepared(object sender, EventArgs e)
//show media controls for 3 seconds when video starts to play
Tip: If you attempt to call SetAnchorView from the OnCreate or OnStart methods, it will still render at the bottom of the screen. This is because the height of the VideoView is not known at this time. It’s best to call this method within the VideoView’s Prepared event when the video is loaded and its size is known, to ensure the controller is properly anchored to the VideoView.
Run the application again ensuring the device is upright (in portrait mode).
Notice that the MediaController appears as an overlay on the VideoView, aligned with the bottom of video. This is much nicer than having the controller floating at the bottom of the screen away from the video itself.
In this post, we built upon our basic Video Player application by associating a MediaController to the VideoView, enabling users to control video playback (i.e. pause, resume, skip forward and rewind). We also covered how to anchor the controller to the VideoView and force the controller to appear for a few seconds when the video first loads. In Part 3 of this series, we will look at providing some polish to the VideoPlayer by handling video playback when the orientation changes, and displaying a progress indicator while the video is loading.
Recently, I was tasked with including video playback within a Xamarin.Android application, so I decided to write a blog post series about my approach in hopes it helps others who are building similar apps.
Incorporating videos within your Xamarin.Android application can be handled in a couple of ways. You can load and play the video in the application or you can launch the video in an external installed media player on the device. In this post, we will walk through the steps to incorporate videos right within the application using Android’s VideoView. We will develop a simple demo that loads a video from a URL.
Modifying the Android Manifest
Since we will load a video from a URL, we must add the following permission to the AndroidManifest.xml file:
<uses-permission android:name="android.permission.INTERNET" />
Adding the VideoView to an Activity
In order to play a video within a Xamarin.Android application, we will use a VideoView which can load and play videos from a specified path or URI.
For this post, let’s create a simple demo to illustrate the main concepts of creating a basic video player to display videos and whose orientation will change when the device is rotated. In this case, we will just use the MainActivity to display the video full screen.
Modify the MainActivity.axml file to include a VideoView within a RelativeLayout, and configure the VideoView to appear center screen as follows:
<?xml version="1.0" encoding="utf-8"?>
Within MainActivity.cs, we need to obtain a handle to the VideoView in order to specify the URI of the video to play, and then trigger the video to launch when the activity is loaded:
[Activity(Label = "VideoPlayerDemo.Droid",
MainLauncher = true,
Icon = "@drawable/icon")]
public class MainActivity : Activity
private VideoView videoPlayer;
protected override void OnCreate(Bundle bundle)
videoPlayer = FindViewById<VideoView>(Resource.Id.PlayerVideoView);
protected override void OnStart()
private void LaunchVideo()
//do the guys in this video look familiar?
string videoUri = "http://bitly.com/1MC3Gig";
At this point, the video will play and will rotate when the device is rotated, which is great! With very little effort, we were able to easily incorporate video playback within the application, but there are some additional features we can include to enhance the user experience. In Part 2 of this series, we will look at improving upon our simple video player by adding media controls and incorporating a progress indicator while the video loads.
The Spotlight posts are back again! For this post, I decided to interview Andy Houghton, an IT professional and a member of Canada’s Technology Triangle .NET User Group, who regularly attends the sessions and full day workshops.
Andy understands that an important aspect in the IT field is continuous learning. He is a super star on the Microsoft Virtual Academy track, achieving Platinum status with over 14K points. Andy is currently ranked among the Top 10 overall MVA students in Canada.
If you haven’t heard of Microsoft Virtual Academy, then check out my short post, Microsoft Virtual Academy – Free Training At Your Fingertips
Andy Houghton has been in the IT community since 1988. He has held many IT roles from Help Desk to Programmer to IT Manager. Andy enjoys working, and helping others grow, in technology. He is currently working on a contract at the Co-operators Insurance Company in Guelph, Ontario. Outside of work, Andy and his wife provide a safe place for children as foster parents. He also has a 19 year old daughter who recently completed her first year of university.
I had a chance to ask Andy some questions about how he got started with MVA, and how it has impacted his career.
1) When did you first get started with Microsoft Virtual Academy (MVA)?
I started using MVA on June 24th, 2011, which was the second week it was available.
2) How did you hear about it?
I received an email from Microsoft.
3) How many courses have you completed through MVA to date?
To date, I have completed about 120 courses.
4) What is your motivation for pursuing the MVA courses?
Keeping current on new technology.
5) How has your career changed since taking the MVA courses?
I have been able to improve my skills and get more contracts. I also feel more confident that what I am telling customers is correct because I heard it on MVA. Sometimes in the past, you created your own solution and it was not the best practice. When I learn something on MVA I know it is the best practice, because it is coming from Microsoft.
6) Of all the courses you’ve taken, what is your favourite MVA course? And who is your favourite MVA instructor?
The OneNote training was my favourite because it is what I use to keep track of my IT resources.
I do not have a favourite instructor I find all of them really knowledgeable and easy to listen to.
7) Are there any additional resources you use to continue to learn and grow in your field of expertise?
Besides MVA, I also use MSDN and TechNet websites. There is an abundance of user created content online which is really useful. Office 365 also has some separate resources that you can search for online.
I use OneNote notebooks to keep track of the best resources. I also make note of those resources that are not so good, so I know to avoid them in the future.
8) What advice can you give to new grads that are entering the workforce?
Never stop learning. I received one piece of advice from an MVA course that I will always remember. I am not sure what course it was, I believe it was an Office 365 course where the instructor said. If you want to continue to advance your career and make more money, “Be more valuable to your employer this year then you were last year”.
The key to success in this field is the ability to change, and adapt, as new technologies emerge. Microsoft Virtual Academy is one of the many resources available online that help you to hone your skills, and keep current, at no cost to you. Thanks Andy for participating in this month’s Spotlight post!
Last but not least…
If you enjoy keeping up with the technology trends, I highly recommend that you register for Microsoft Virtual Academy and create your own personal learning plan. While you’re at it be sure to check out the upcoming Windows 10 Developer Readiness Canadian Webcast.
Online resources are awesome, but in-person events are just as important, both for the learning and the networking opportunities. If you’re in the GTA or surrounding area, register for the Toronto stop of the Build Tour as well as for the Build Highlights sessions that both I and fellow Microsoft MVP, Tom Walker, will be running for our local area .NET User Groups: London Developers .NET Meetup Group and Canada’s Technology Triangle .NET User Group (Kitchener).
I look forward to seeing you there!
Join the Windows 10 Developer Readiness – Powered by MVPs global webcast series to learn how to build an app or bring an existing App to the *NEW* Universal Windows Platform!
This live webcast is part of a global series provided by the MVP Award Program for developers. Our goal is to bring you the latest opportunities in developing for the Windows Platform, and to bring you closer to the Microsoft MVPs from your region.
By joining this webcast you will be able to:
- Learn about the *NEW* Universal Windows Platform for apps and web developers.
- Participate in open Q&A with Microsoft MVPs, some of the top experts in the field.
Canadian Webcast Details
Registration Link: https://mvp.eventbuilder.com/event?eventid=r9f3h0®Now=1
Speaker: Colin Melia
Moderator: Tom Walker
Date: Thursday, June 11th
Time: 12pm EST
For more information, visit the event page: http://mvp.microsoft.com/win10mvp.aspx
It’s that time of year again! ObjectSharp’s At the Movies event is right around the corner, and we can’t wait to share all of the good things coming up in our industry this year! I really enjoy being a part of this event, and not just for the posters (but on an important side note, thanks to Denis Makarenko for his hard work in making those posters look amazing!). What’s important is the information we are bringing to you, so that you can get up to speed with the changes coming your way, and to show you how Microsoft is making it easier than ever to manage projects with TFS, integrate advanced services into your enterprise or mobile applications through Azure, and develop high quality applications for the enterprise or consumer market.
In a few short days, my fellow ObjectSharp colleagues and I will take to the stage at the TIFF Bell Lightbox in downtown Toronto to share all of the exciting advancements that Microsoft announced recently at its annual Build conference.
Shane Castle will talk about the sophisticated service offerings available in Azure which can easily be incorporated into your applications regardless of the platform they are running under.
Dave Lloyd and Max Yermakhanov will then step up to discuss the new features coming in TFS 2015 enabling you to easily set up your team and projects for success.
Last but not least, David Totzke and I will take to the stage to share with you what we learned firsthand while attending the Build conference.
Be sure to register for this event at http://objectsharp.com/atm! It’s free, it’s fun, and it’s full of information that is relevant to you! We are all looking forward to seeing you there!
Being able to attend //build/ last week was a dream come true. In the 18 years that I have worked in the industry, this was the first time I was able to attend a major Microsoft conference. In the past, when working as a full time employee, I had never received approval from employers for this type of professional development. Being a consultant changed the playing field. I didn’t need to ask anyone for permission, or have someone else approve the cost. I didn’t have to beg, bargain and plea for the time off. I was the requester and approver all rolled into one. Suffice it to say, I wasn’t going to let the opportunity pass me by. I had a feeling this was THE year to be in San Francisco, instead of watching it from the comfort of my home. Within 45 minutes, registration to //build/ was at max capacity with myself being among the many that were lucky enough to have processed the registration in time.
“Why spend all that money to go in person when you can watch it online?”
This was a question I often heard when discussing the upcoming conference. Yes, the cost of the registration and travel expenses combined are not for the faint of heart, including the days of lost wages for a consultant. But for me, this was well worth the expense. This was all before I even knew what I was getting myself into. And now, after returning from a glorious week in sunny San Francisco, truth be told, how do I feel? Thankful, excited, and rejuvenated.
Thankful that I had the opportunity to go, and was able to cover my own expenses to do so. Life is short, and often throws you a curveball when you least expect it. Seeing as how this year the stars aligned perfectly in my favour, I grabbed the bull by the horns and registered without hesitation. Who knows if I’ll have the chance next year or the year after that? I wasn’t going to let this one pass me by.
Excited over the opportunities that are on the forefront for .NET Developers with Windows 10, Azure, and Office 365. Did your heart skip a beat when Joe Belfiore showed off Continuum for Windows Phone? Mine did. Did you drool at the HoloLens demo and wish you were the one walking around the stage, pinning virtual items to the wall, talking to a robot, and manipulating 3D holograms in real time? I sure did. Did you envision the potential opportunities for all Microsoft developers when seeing what Azure, Office 365, and the Windows 10 platform has to offer? Ditto for me.
Rejuvenated after having spent a week with other professionals that share the same passion and excitement for not only what we do now, but for the possibilities that are open to us in the very near future.
If I had decided to stay home, I wouldn’t have:
1) Met Charles Petzold and scored a signed hard copy of his new book
2) Tried on the HoloLens!!!!
3) Participated in a focus group to provide valuable feedback and make my voice heard
4) Met up with people I’ve only communicated with over Twitter prior to this conference – Jason Young (MS Dev Show), Omer Raviv (OzCode), Stephen Keefer (Accuweather), Mark MacDonnell (Sela Canada), Sid Gurjar (Accuweather)
5) Reconnected with some of my favourite MVPs who I wouldn’t have had the opportunity to talk to face-to-face otherwise – Laurent Bugnion, René Schulte, Ginny Caughey, Carl Schweitzer, Jan Hannemann, Sébastien Lachance, Brian Lagunas, Rob Irving, Oren Novotny, Mark Schramm, Paras Wadehra and the list goes on and on
6) Attended the many awesome parties that were put on by Xamarin, Infragistics, and Microsoft
7) Hung out with my local colleagues and friends, who I rarely get a chance to see in person because we are all crazy busy otherwise – Tom Walker (London .NET Dev Group), Richard Underwood (fellow ObjectSharpie), David Totzke (fellow ObjectSharpie and co-author)
8) Met and had lunch with an editor from O’Reilly (thanks Brian!)
9) Shared the experience with friends over which session to see next, being collectively enamored with the “ooh” and “ahh” moments over the new APIs we learned about in the deep dive sessions, and been part of our post-session discussions as we compared notes and speculated on what opportunities this could bring.
The //build/ conference isn’t just about the sessions you see on Channel 9. There is so much more to it than that. The ability to participate in focus groups, to voice your opinions on the marketing, direction or usability of a product – whether it be Visual Studio, Windows 10, and yes even HoloLens, is by far one of the most compelling reasons to attend. The networking opportunities to meet new people, who share the same interest and excitement as you do is always worthwhile. It’s refreshing to connect with others face-to-face rather than through the online medium we’ve become accustomed to. There’s no replacement for that, believe you me.
If you live in the GTA…
…then pencil off May 13th in your calendar, and make a point to join me and my fellow ObjectSharp colleagues at this year’s At The Movies event at the Bell TIFF Lightbox in downtown Toronto, where we will recap the highlights from //build/. It’s free, fun, and highly informative. Don’t miss out on yet another awesome event! Visit objectsharp.com/atm to register today!
Looking back on 2014, I realize so much has changed in such a short time, and appreciate all of the good things that have come my way. Here are my favourite moments of 2014.
Awarded Microsoft MVP
I was beyond excited when I was awarded my very first (and hopefully not the last!) Microsoft MVP in April 2014!
I have always admired and respected other Microsoft MVPs whose paths had crossed mine over the years, and to be considered part of that group is a huge honour.
Given Opportunities to Speak
Prairie Dev Con was the first conference that accepted my session submissions, and so I was off to Winnipeg in early April to talk to people about Windows Phone development. What a thrill it was to be part of a roster of all-star speakers! I felt lucky to not only have been selected to be a part of the conference, but to meet those people that I have learned from as well. It was special to be at a conference with people who were there to learn and to have fun. Kudos to D’Arcy Lussier for organizing this fantastic conference each year.
I’m excited to announce that I’ve have been selected to return to Prairie Dev Con Winnipeg 2015!
My conference submission to That Conference 2014 was also accepted. The thrill and excitement to be a part of yet another conference is something I can’t describe.
The best part of it being that it’s held at a family friendly venue - the Kalahari Resort in Wisconsin Dells. Although my children are both grown and had no interest in attending this with me, I still found it to be a wonderful experience to see others there with their families, and to see children participating in the conference as well!
The opening keynote by Elizabeth Naramore was inspiring and worth watching.
Big props to Greg Levenhagen and his crew for putting on a great event year in and year out!
I was also invited to participate in ObjectSharp’s At the Movies event which was held at a movie theatre in downtown Toronto in May.
It was an honour to be able to represent ObjectSharp and speak at this event, in front of an audience of over 300 people. The event was also recorded by Microsoft and is now currently up on the Channel 9 site, which makes it my second video appearance on Channel 9!
Last but not least, I had the opportunity to present at both CTTDNUG’s Cloud Camp in early 2014, and at the London .NET Developers Group Cloud Camp in late 2014!
Attended MVP Open Day and MVP Summit!
Microsoft Canada hosted an Open Day in May 2014 for current Canadian MVPs. This was my first opportunity to attend an event where I would meet my MVP Lead, Simran Chaudhry, along with Joel Langford and the rest of the Microsoft team that focuses on the developer community. It was also a wonderful feeling to meet other MVPs from across the country.
In November 2014, I was on a plane heading to Seattle to attend the MVP Global Summit where I met other MVPs from around the world. It was an experience like no other! Aside from attending the various sessions, the networking opportunities were priceless and the social events were fun. I met so many amazing people, including my MVP Summit roommate Sara Silva, as well as the father of MVVM Light, Laurent Bugnion.
Continued writing Posts for the Canadian Developer Connection blog
In 2013, I had the opportunity to write multiple posts for Microsoft’s Canadian Developer Connection blog, and the momentum kept going in 2014:
1) Save Time, Money, and Your Sanity: Coded UI Testing for the Windows Phone - Part 1
2) Save Time, Money, and Your Sanity: Coded UI Testing for the Windows Phone - Part 2
3) Save Time, Money, and Your Sanity: Coded UI Testing for the Windows Phone–Adding Assertions
4) Save Time, Money, and Your Sanity: Coded UI Testing for the Windows Phone–Test Methods
5) Windows First: A New Strategy for Mobile Development and Beyond
6) Using Portable Class Libraries
7) The Power of Speech in Your Windows Phone 8.1 Apps
8) The Power of Speech in Your Windows Phone 8.1 Apps - Text-to-Speech
9) The Power of Speech in Your Windows Phone 8.1 Apps–Speech Recognition
Transitioned the User Group to Meetup.com
With the new Canadian Anti-Spam Legislation in place as of July 2014, I decided this was a perfect time to transition the Canadian Technology Triangle .NET User Group to Meetup.com, and ask members to join our Meetup group in order to deactivate the old web site. This was a risky move, considering we had a solid member base in place. I was worried about losing members, but it was a risk worth taking. As part of the legislation compliance, we were required to ask people to “opt-in” to email newsletters even though they were already in our database. The old site was built on an old version of Dot Net Nuke, and we had over 1000 registered emails in the CTTDNUG database which would have required manual vetting to determine which emails were still linked to valid members.
Moving to Meetup made it easier for our members to manage their own email notifications, made it easier for them to join or leave our group without requiring any manual action on our end, and introduced our group to a wider audience. In less than 6 months, CTTDNUG has 196 members!
Achievement Unlocked: Xamarin Mobile Developer Certification
Early in the year, I subscribed to Xamarin University to learn firsthand from those that know about cross-platform development with Xamarin. I absolutely loved that the online classes were run by live instructors. Being able to interact with the instructors and other students only enhanced the learning experience. Along with that, Xamarin University provides the recordings of each class so that you can view them at your own convenience. I found this to be great to revisit topics where I needed a refresher as I was preparing for the certification exam.
I’m not sure what 2015 has in store for me, but I know I don’t plan to sit idle. I plan to continue to learn, grow, and share my knowledge with others.
Happy New Year!
In the last few posts, we have walked through how to design the Ultimate Fan App using Windows AppStudio and the Bandsintown API.
In Part 1, I went over the basics of Windows AppStudio and Bandstown API, and briefly touched on how they can be used collectively to create a Universal app that allows you to track your favourite musician or band.
In Part 2, I demonstrated how you can get the majority of the app completed simply using Windows AppStudio. To complete the app, I mentioned that it would be necessary to download and modify the source code.
Before digging into the code, my last post was focused on looking at the solution and source code that was generated by AppStudio to gain a better understanding of the structure of the projects. This helps us to identify where modifications will need to be made.
The Necessary Changes
In order to ensure the Bandsintown concert listings are rendered in the application, and to allow users to link to the band’s concert page to purchase tickets, we need to make some changes. My goal for these changes are to show a concerts list with the name of the venue, the city and/or country the concert is in, and the concert’s date and time. I would also like to make it easy to see which concerts still have tickets available for sale.
Last but not least, when a concert item that has tickets available is tapped, I want to the app to load the concert’s ticket sales page.
To accomplish this, changes are required to the application logic within the Portable Class Library and Shared Project. Further changes are needed to each platform-specific project to ensure the user interface displays the data in a desirable format.
In the Portable Class Library:
1) Add a class, named ConcertSchema, to represent the data retrieved from the Bandsintown API.
You can easily add the members to this class from a JSON sample of the data in Visual Studio 2013. First, go to the Event JSON Response page on the Bandsintown API site: http://www.bandsintown.com/api/responses#event-json
Next, highlight and copy the sample Event data. Now go back to your ConcertSchema class in the Portable Class Library and delete the default class that is created. Click Edit > Paste Special… > Paste JSON As Classes
You will notice the main Events result set is created as a class called Rootobject. Any subsequent classes that are needed are automatically created as well (in this case, Artist and Venue).
2) Add a class, named ConcertDataProvider, to perform the web request which will retrieve the data from the Bandsintown API for your favourite artist. It also will translate the retrieved data into an object which we can use within the code. This is referred to as deserialization.
3) Rename the Rootobject class to ConcertSchema. For conformity, I also renamed the Venue and Artist classes that were generated to VenueSchema and ArtistSchema respectively. I also changed the data type of on_sale_datetime from DateTime to object, since this field may not always have a value, causing null exceptions to be thrown.
Try building the solution now to see if we are on the right track.
What happened? Did you notice an error similar to this:
The solution to this is to ensure the class derives from the BindableSchemaBase abstract class, similar to the way that the RssSchema class does:
public class ConcertSchema : BindableSchemaBase
Right-click on BindableSchemaBase within the ConcertSchema class, and select to implement abstract class:
Modify the override methods that were added as part of the abstract class implementation as shown below:
Since the concert listings pulls a DefaultTitle, DefaultSummary and DefaultContent for each list item, it’s easy to feed the concert data that we want to the concert item by just returning that information through these classes. AppStudio has already provided the bindings (or virtual glue) that wires everything together to get the data flowing from back to front.
4) Modify the ConcertsDataSource class to make use of the new Concert data provider.
In the Shared Project:
1) Modify the ConcertsViewModel in the Shared Project to utilize the new ConcertSchema class. This can be simply accomplished by replacing RssSchema with ConcertSchema.
2) Add an image to the Assets folder which will be used to represent a ticket. In this case, I used Syncfusion’s Metro Studio to obtain an image which suits the purpose.
3) Add a converter class, named TicketAvailableToVisibilityConverter which will display the ticket image when tickets are available, and hides it when tickets are not available for a concert.
In each platform-specific project:
1) Modify the ConcertsViews data template in each platform-specific project to include the ticket image that displays when tickets are available for a concert, as well as text indicating “available”.
2) Delete ConcertDetailsPage.xaml from each platform-specific project
Next, it’s important to revisit the ConcertsViewModel class to modify the ItemClickCommand so that when a concert item is tapped, the application launches a browser and navigates to the artist’s Bandsintown page. We will accomplish this by using the LaunchUriAsync method off the Launcher object:
Last but not least, it is just as important to add a Credits section in your app to give attribution to any images obtained under the Creative Commons License. In this case, the background image used in the app must be attributed to Léa Reviron. As well, attribution should be included for any external data providers, and/or 3rd party libraries used within the app, such as the Json.NET library. In the Windows 8.1 project, this could be included as an additional App Flyout.
Credits Flyout on Windows 8.1
In the Windows Phone 8.1 project, this could be added to the About page, as part of a Pivot item or a separate Credits page. It’s up to you.
Build and Run
With all of the modifications in place, it’s time see what it looks like. Build and run the app on each platform to see if everything is displayed and working as expected.
Maroon 5 Fan Book on Windows 8.1
Concert listings from Bandsintown on Windows 8.1
As you can see, concert data is flowing into the app from the Bandsintown API. The other feeds which AppStudio wired up for us - Twitter, YouTube and Maroon 5 Blog feeds - are working as expected. Tapping a concert listing that shows tickets are available launches a new browser page and loads the concert’s ticket sales page right within the app.
Drill-down into the concerts listings page by tapping the concerts header. Now navigate back to the main page. What do you notice?
It appears that the other feeds still have their data displayed, but the concerts list is rebuilding each time you navigate back to the main page. Let’s see what the other feeds are doing that we aren’t.
RssSchema, TwitterSchema, and VideosSchema implement IEquatable and IComparable. If you take a look at ObservableCollectionExtensions class in the Common folder within the Portable Class Library, you will notice that it contains two methods: AddRangeUnique and AddSorted. All data sources call this method when loading data to first determine if the data has already been loaded. If so, then it just retrieves the collection from the AppCache. If not, it loads the data and stores the collection to the AppCache so that on the next page load it doesn’t go through the expensive operation of reloading the data unnecessarily. The goal when designing mobile apps is to keep the application running efficiently and with minimal resources. Caching data so that it does not load data needlessly from either a web service, database, or other mechanism multiple times is one of those improvements that will really make a difference in your application’s performance. This also takes care of the flash issues we were experiencing when navigating back and forth between pages.
Let’s make the necessary changes to ConcertSchema to ensure it implements IEquatable and IComparable.
In the Equals and GetHashCode methods, we will use the concert’s id as an equality check. In the CompareTo method, we will use the concert’s event datetime field as a comparison to ensure items that get added to the list are sorted by date so we can see upcoming concerts in order by concert date.
Build and run the app again and perform the same test see if concert data is being displayed from the AppCache. Do you notice that the concert listing flash is gone now when navigating between pages after the initial data load?
One Last Gotcha
In testing the app on Windows Phone 8.1, I discovered that attempting to load the concert’s event page at the Bandsintown website fails. Instead it prompts the user to install an app from the Store, but no related app is found. In attempting to simply use the built-in browser to navigate to the URL outside of the app, I am prompted with this:
So there is clearly something wrong with the way the native browser interprets the URL or the attempted redirect that is occurring on the Bandsintown end. I’ve sent off an email to Bandsintown about this issue. In the meantime, I have revamped my Windows Phone app so that users can only view concert listings in the app. They cannot navigate to the Bandsintown event page to purchase tickets. The browser just won’t load the page.
I simply removed the wiring to the ItemClickCommand from the ConcertsList Data Template in the ConcertsViews.xaml file in the Window Phone 8.1 project. When a user taps the item, no action is taken. I will revisit this once I hear back on a solution to the issue from Bandsintown.
Other than that, everything else looks good in the Windows Phone app.
Whew! That was quite the project, but then again, imagine having to develop the entire app from scratch!
With Windows AppStudio, we were able to create a pretty slick Fan App that is supported on Windows 8.1 and Windows Phone 8.1 devices. The majority of the application was automatically generated based on information we entered in the AppStudio design tool. We had to make some modifications to bring it to the homestretch, and add that coolness factor by integrating the Bandsintown API to tie in concert listings. Sure it required a little bit of effort, but the payoff is priceless!
You can download the source code for this demo from my Github account. Remember that you will need to add your own consumer key and access token for the Twitter feed to work.